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

[파이썬 주식] 변동성돌파전략 - 12. 실적 좋은 종목으로 백테스트 본문

STOCK/변동성돌파전략

[파이썬 주식] 변동성돌파전략 - 12. 실적 좋은 종목으로 백테스트

BOTTLE6 2021. 2. 20. 15:23

 

돈을 적게 벌더라도 한번에 크게 잃으면 안된다. 

과거에 크게 잃지 않았던 종목이 앞으로도 크게 잃지 않을까? 라는 생각에서 수익률 백테스트

 

▶ 2021.1월

(5종목 임의 수익률 기준)

과거 12개월(20.1~20.12) 258% 수익률

과거 3개월 (20.10~20.12) 168% 수익률

기록한 종목의 1개월(21.1)간의 수익률은 약 103% 수준으로 테스트 되었다.

과연 안정적일까?란 생각에 더 과거로 돌아가서 한달 단위로 테스트 해보았다. 

 

0. 전체종목 검색 => codes

1. 12개월 조건 => new_codes

2. 3개월 조건 => symbol_codes

 

 

### 1. 라이브러리 임포트

from Investar import Analyzer # 파이썬 증권데이터분석 책 참고
mk = Analyzer.MarketDB()
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import time
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
# matplotlib 한글 폰트 출력코드

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. 종목불러오기

## 종목 불러오기
import pandas as pd
"""KRX로부터 상장기업 목록 파일을 읽어와서 데이터프레임으로 반환"""
url = 'http://kind.krx.co.kr/corpgeneral/corpList.do?method='\
    'download&searchType=13'
krx = pd.read_html(url, header=0)[0]
krx = krx[['종목코드', '회사명']]
krx = krx.rename(columns={'종목코드': 'code', '회사명': 'company'})
krx.code = krx.code.map('{:06d}'.format)
krx = krx.set_index('code')


codes = list(krx.index)
companys = [krx.loc[code,'company'] for code in codes]

### 3. 함수정의

def backtest(종목명, k, start='2020-01-01', end_date='2021-02-14'):
    df=mk.get_daily_price(종목명, start, end_date)
    df.set_index(df['date'].apply(lambda x:pd.to_datetime(x)),inplace=True)
    df['diff_ratio'] = df['diff'] / df['close'].shift(1)
    df['open_gap'] = df['open']-df['close'].shift(1)
    
    df['변동폭'] = df['high']-df['low']
    df['목표가'] = df['open'] + df['변동폭'].shift(1)*k
    df['MA3_yes'] = df.close.rolling(window=3).mean().shift(1)
    df['내일시가'] = df.open.shift(-1)
    df['MA20'] = df['close'].rolling(window=20).mean() 
    df['stddev'] = df['close'].rolling(window=20).std() 
    df['upper'] = df['MA20'] + (df['stddev'] * 2)
    df['lower'] = df['MA20'] - (df['stddev'] * 2)
    df['PB'] = (df['close'] - df['lower']) / (df['upper'] - df['lower'])
    df['PB_yes'] = df['PB'].shift(1)
    df['bandwidth'] = (df['upper'] - df['lower']) / df['MA20'] * 100 # ①  
    cond = ( df['high'] > df['목표가'] ) & ( df['목표가'] > df['MA3_yes'] ) & ( df['PB_yes'] < 0.6 )
    
    df.loc[cond,'수익률'] = df.loc[cond,'내일시가']/df.loc[cond,'목표가']*0.9975 - 0.006 #0.9975 수수료, 0.002 슬리피지
    df=df[19:]
    #print(df.dropna().수익률.cumprod().iloc[-1])
    #df.수익률.plot.hist(bins=20)
    #return df #일반
    return df['수익률'] #return 데이터프레임용
def 돌려보기(codes, start_date, end_date):
    def load_data(code, k, start='2020-01-01'):
        
        df=mk.get_daily_price(code, start, end_date)
        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['MA3_yes'] = df['close'].rolling(window=3).mean().shift(1)
        df['MA20'] = df['close'].rolling(window=20).mean() 
        df['stddev'] = df['close'].rolling(window=20).std() 
        df['upper'] = df['MA20'] + (df['stddev'] * 2)
        df['lower'] = df['MA20'] - (df['stddev'] * 2)
        df['PB'] = (df['close'] - df['lower']) / (df['upper'] - df['lower'])
        df['PB_yes'] = df['PB'].shift(1)
        df['bandwidth'] = (df['upper'] - df['lower']) / df['MA20'] * 100 # ①
        df['TP'] = (df['high'] + df['low'] + df['close']) / 3
        df[19:]
        return df

    start = time.time()
    a=[]
    b=[]
    c=[]
    d=[]
    e=[]
    f=[]
    g=[]
    h=[]
    i=[]
    j=[]
    k=[]
    l=[]
    m=[]
    n=[]
    name=[]
    #name2=[]
    iteration=0
    for code in codes:
        iteration=iteration+1    
        if iteration%500==0: #알림용
            print(iteration)
        try:
            df = load_data(code, 0.5, start=start_date)
            기간 = df.shape[0] # 기간수
            cond = ( df['high'] > df['목표가'] ) & ( df['목표가'] > df['MA3_yes'] ) & (df['PB_yes']<0.6)# 구매조건
            df=df[cond]

            df['수익률'] = df['내일시가']/df['목표가']*0.9975 - 0.006 #0.9975 수수료, 0.002 슬리피지
            df['승패'] = np.where(df['수익률']>1, 1, 0)
            df=df.iloc[:-2]

            조건만족횟수 = df.shape[0] # 조건만족 수
            조건만족비율 = 조건만족횟수/기간
            조건승률 = df['승패'].value_counts()[1] / len(df['승패'])
            #최근승률 = df[-1:].승패.value_counts()[1]/ len(df[-10:].승패)
            보유수익률 = (df['close'][-1]/df['close'][0]*0.9975-0.006-1)
            돌파수익률 = (df.수익률.cumprod()[-1]-1)
            최대수익률 = (df.loc[df.수익률.idxmax()].수익률-1)
            평균수익률 = df.수익률.mean()-1
            중앙수익률 = df.수익률.median()-1
            수익률표준편차 = df.std()['수익률']
            최대손실률 = (df.loc[df.수익률.idxmin()].수익률-1)
            기간수익률 = df.수익률.cumprod().iloc[-1]
            돌파비율 = 돌파수익률-보유수익률
            N = (df.index[-1] - df.index[0]).days / 252
            M = df.dropna().shape[0]
            CAGR = (기간수익률 ** (1/N))-1
            기하평균수익률 = (기간수익률 **(1/M))-1
            name.append(code)
            #name2.append(krx.loc[code])
            a.append(조건만족횟수)
            b.append(조건만족비율)
            c.append(조건승률)
            #d.append(최근승률)
            e.append(보유수익률)
            f.append(돌파수익률)
            g.append(최대수익률)
            h.append(평균수익률)
            i.append(중앙수익률)
            j.append(최대손실률)
            k.append(CAGR)
            l.append(기하평균수익률)
            m.append(수익률표준편차)
            n.append(돌파비율)
        except :
            pass
        df=pd.DataFrame({"종목이름":name,"조건만족횟수":a,"조건만족비율":b,"조건승률":c,"보유수익률":e,"돌파수익률":f,"평균수익률":h,"수익률표준편차":m,"중앙수익률":i,"최대수익률":g,"최대손실률":j,"돌파비율":n,"CAGR":k,"기하수익률":l})
    print("완료 소요시간 :", time.time() - start)  # 현재시각 - 시작시간 = 실행 시간
    df['돌파-보유'] = df['돌파수익률'] - df['보유수익률']
    df['랭크_돌파'] = df['돌파수익률'].rank(ascending=False) 
    df['랭크_중앙'] = df['중앙수익률'].rank(ascending=False) 

    #k는 그룹수
    #몫 = df.shape[0]//4 +1=225
    def 그룹화(x):
        return (x//df.shape[0]//4)+1
    df['랭크_돌파'] = df['랭크_돌파'].apply(lambda x:그룹화(x))    
    df['랭크_중앙'] = df['랭크_중앙'].apply(lambda x:그룹화(x))
    
    return df
def returns_(returns):
    import random
    returns_=pd.DataFrame()
    returns_['min']= returns.min(axis=1)
    returns_['mean']= returns.mean(axis=1)
    returns_['median']= returns.median(axis=1)
    returns_['max']= returns.max(axis=1)
    returns_['count'] = returns.count(axis=1)
    returns_['승패'] = returns_['mean'].map(lambda x:1 if x>1 else 0 )
    returns_['count_rev'] = returns_['count'].map(lambda x : x/5 if 0<x<5 else 1) #5종목 이내일 때는 1/5
    returns_['mean_rev'] = returns_['mean']**(returns_['count_rev'])
    for date in list(returns_.index):
        codes_date = returns.loc[date].dropna()
        if len(codes_date) >=5:
            codes_rand = random.sample(range(0,len(codes_date)),5)
            returns_.loc[date, 'mean_rand5'] = codes_date[codes_rand].mean()
        else:
            returns_.loc[date, 'mean_rand5'] = returns_.loc[date,'mean']**(returns_.loc[date,'count_rev'])

    returns_['count_rev2'] = returns_['count'].map(lambda x : x/2 if 0<x<2 else 1) #5종목 이내일 때는 1/5
    returns_['mean_rev2'] = returns_['mean']**(returns_['count_rev2'])
    for date in list(returns_.index):
        codes_date = returns.loc[date].dropna()
        if len(codes_date) >=2:
            codes_rand = random.sample(range(0,len(codes_date)),2)
            returns_.loc[date, 'mean_rand2'] = codes_date[codes_rand].mean()
        else:
            returns_.loc[date, 'mean_rand2'] = returns_.loc[date,'mean']**(returns_.loc[date,'count_rev2'])
    for date in list(returns_.index):
        codes_date = returns.loc[date].dropna()
        if len(codes_date) >=1:
            codes_rand = random.sample(range(0,len(codes_date)),1)
            #returns_.loc[date, 'mean_rand1'] = codes_date[codes_rand].mean()
            returns_.loc[date, 'mean_rand1'] = codes_date[random.sample(list(codes_date.index),1)[0]]
        else:
            returns_.loc[date, 'mean_rand1'] = returns_.loc[date,'mean']



    #print("5종목 평균수익률 : {:.2f}".format(returns_['mean_rev'].dropna().cumprod().iloc[-1]))
    #print("2종목 평균수익률 : {:.2f}".format(returns_['mean_rev2'].dropna().cumprod().iloc[-1]))
    print("1종목 임의평균수익률 : {:.2%}".format(returns_['mean_rand1'].dropna().cumprod().iloc[-1]))
    print("2종목 임의평균수익률 : {:.2%}".format(returns_['mean_rand2'].dropna().cumprod().iloc[-1]))
    print("5종목 임의평균수익률 : {:.2%}".format(returns_['mean_rand5'].dropna().cumprod().iloc[-1]))

    #print("1종목 중앙수익률 : {:.2f}".format(returns_['median'].dropna().cumprod().iloc[-1]))
    returns_[['mean_rand1','mean_rand2','mean_rand5']].cumprod().loc[:].plot()
    return returns_

### 4. 1년(2020.01.01~2020.12.31) → 3개월(2020.10.01~2020.12.31) 실적 좋은 종목 필터링 하여,

         다음 1개월(2021.01.01~2021.01.31) 수익률 백테스트

■ 1단계 _ 1년

  ○ 돌려보기

codes = companys
start_date='2019-12-01'#30일 전으로 가야함 20일 이동평균을 활용하기 위해, 
end_date = '2020-12-31'
df = 돌려보기(codes, start_date, end_date)
df

  ○ 조건 필터링 : 81개 종목

cond = (df['조건승률']>0.53 ) &(df['기하수익률']>0.005) & (df['최대손실률']>-0.07) & (df['조건만족횟수']>3) & (df['랭크_돌파']<3) & (df['랭크_중앙']<3)
print(df[cond].shape[0])
print("평균승률 : {:.2f}".format(df[cond].조건승률.mean()))
print("평균수익률 : {:.2f}".format(df[cond].평균수익률.mean()))
print("중앙수익률 : {:.2f}".format(df[cond].중앙수익률.mean()))
print("기하수익률 : {:.2f}".format(df[cond].기하수익률.mean()))
print("돌파수익률 : {:.2f}".format(df[cond].돌파수익률.mean()))
new_codes = list(df[cond]['종목이름'])
df[cond].sort_values(by='기하수익률',ascending=False).head()

  ○ 종목 개수별 임의의 수익률 

start= '2019-12-01' #한달전으로 세팅
end = '2020-12-31'
returns = pd.DataFrame()
for code in new_codes:
    df2 = backtest(code,k=0.5,start=start, end_date=end)
    returns[code] = df2
    #time.sleep(0.01)
returns.set_index(returns.reset_index()['date'].apply(lambda x:pd.to_datetime(x)),inplace=True)
returns.set_index(returns.index.strftime("%Y-%m-%d"),inplace=True)

print("{} ~ {} 수익률 : {:.2%}".format(start, end, returns.mean(axis=1).dropna().cumprod().iloc[-1]))
a=returns_(returns)

■ 2단계_ 3개월 

#2단계 : 1개월 
#new_codes = list(df[cond]['종목이름'])
start_date='2020-09-01'
end_date = '2020-12-31'
new_df = 돌려보기(new_codes, start_date, end_date)
new_df

  ○ 조건 필터링 : 28개 종목

cond = (new_df['조건승률']>0.55 ) &(new_df['기하수익률']>0.005) & (new_df['최대손실률']>-0.04) & (new_df['조건만족횟수']>1) & (new_df['랭크_돌파']<3) & (new_df['랭크_중앙']<3)
print(new_df[cond].shape[0])
print("평균승률 : {:.2f}".format(new_df[cond].조건승률.mean()))
print("평균수익률 : {:.2f}".format(new_df[cond].평균수익률.mean()))
print("중앙수익률 : {:.2f}".format(new_df[cond].중앙수익률.mean()))
print("기하수익률 : {:.2f}".format(new_df[cond].기하수익률.mean()))
print("돌파수익률 : {:.2f}".format(new_df[cond].돌파수익률.mean()))
symbol_codes = list(new_df[cond]['종목이름'])
new_df[cond].sort_values(by='기하수익률',ascending=False).head()

  ○ 12개월(2020.01.01~2020.12.31) 필터링 된 81종목(new_codes)의 3개월(2020.10.01~2020.12.31)간 임의종목 수익률

start= '2020-09-01' #한달전으로 세팅
end = '2020-12-31'
returns = pd.DataFrame()
for code in new_codes:
    df2 = backtest(code,k=0.5,start=start, end_date=end)
    returns[code] = df2
    time.sleep(0.01)
returns.set_index(returns.reset_index()['date'].apply(lambda x:pd.to_datetime(x)),inplace=True)
returns.set_index(returns.index.strftime("%Y-%m-%d"),inplace=True)

print("{} ~ {} 수익률 : {:.2%}".format(start, end, returns.mean(axis=1).dropna().cumprod().iloc[-1]))
a=returns_(returns)
#returns.mean(axis=1).cumprod().plot()

○ 3개월(2020.10.01~2020.12.31) 필터링 된 28종목(symbol_codes) 3개월 임의종목 수익률

start= '2020-09-01' #한달전으로 세팅
end = '2020-12-31'
returns = pd.DataFrame()
for code in symbol_codes:
    df2 = backtest(code,k=0.5,start=start, end_date=end)
    returns[code] = df2
    time.sleep(0.01)
returns.set_index(returns.reset_index()['date'].apply(lambda x:pd.to_datetime(x)),inplace=True)
returns.set_index(returns.index.strftime("%Y-%m-%d"),inplace=True)

print("{} ~ {} 수익률 : {:.2%}".format(start, end, returns.mean(axis=1).dropna().cumprod().iloc[-1]))
a=returns_(returns)
#returns.mean(axis=1).cumprod().plot()

 3개월(2020.10.01~2020.12.31) 필터링 된 28종목(symbol_codes) 과거 12개월 임의종목 수익률

start= '2019-12-01' #한달전으로 세팅
end = '2020-12-31'
returns = pd.DataFrame()
for code in symbol_codes:
    df2 = backtest(code,k=0.5,start=start, end_date=end)
    returns[code] = df2
    time.sleep(0.01)
returns.set_index(returns.reset_index()['date'].apply(lambda x:pd.to_datetime(x)),inplace=True)
returns.set_index(returns.index.strftime("%Y-%m-%d"),inplace=True)

print("{} ~ {} 수익률 : {:.2%}".format(start, end, returns.mean(axis=1).dropna().cumprod().iloc[-1]))
a=returns_(returns)
#returns.mean(axis=1).cumprod().plot()

■ 3단계 _ 다음 1개월

start= '2020-12-01' #한달전으로 세팅
end = '2021-01-10'
returns = pd.DataFrame()
for code in symbol_codes:
    df2 = backtest(code,k=0.5,start=start, end_date=end)
    returns[code] = df2
    time.sleep(0.01)
returns.set_index(returns.reset_index()['date'].apply(lambda x:pd.to_datetime(x)),inplace=True)
returns.set_index(returns.index.strftime("%Y-%m-%d"),inplace=True)

print("{} ~ {} 수익률 : {:.2%}".format(start, end, returns.mean(axis=1).dropna().cumprod().iloc[-1]))
a=returns_(returns)
#returns.mean(axis=1).cumprod().plot()

▶ 2021.1월 

(5종목 임의 수익률 기준)

과거 12개월(20.1~20.12) 258% 수익률

과거 3개월 (20.10~20.12) 168% 수익률

기록한 종목의 1개월(21.1)의 수익률은 약 103% 수준이다. 

 

수익이 크진 않지만, 안정적 수익을 원하기 때문에 나쁘지 않은 것 같아 과거 1년 동안 검토해보았다. 

 

 

### 5. 12M_3M_종목찾기 백테스트

def 종목찾기_12M_3M(start_1='2019-12-01', start_2='2020-09-01',start_3='2020-12-31',end_1='2020-12-31',end_2='2021-01-31'):
    ## df
    codes = companys
    start_date = start_1#30일 전으로 가야함 20일 이동평균을 활용하기 위해, 
    end_date = end_1
    df = 돌려보기(codes, start_date, end_date)

    ## new_codes
    cond = (df['조건승률']>0.53 ) &(df['기하수익률']>0.005) & (df['최대손실률']>-0.07) & (df['조건만족횟수']>3) & (df['랭크_돌파']<3) & (df['랭크_중앙']<3)
    new_codes = list(df[cond]['종목이름'])

    ## new_codes 1년 그리기
    start= start_1 #한달전으로 세팅
    end = end_1
    returns = pd.DataFrame()
    for code in new_codes:
        df2 = backtest(code,k=0.5,start=start, end_date=end)
        returns[code] = df2
    returns.set_index(returns.reset_index()['date'].apply(lambda x:pd.to_datetime(x)),inplace=True)
    returns.set_index(returns.index.strftime("%Y-%m-%d"),inplace=True)
    print("new_codes:{}".format(len(new_codes)))
    print("{} ~ {} 수익률 : {:.2%}".format(start, end, returns.mean(axis=1).dropna().cumprod().iloc[-1]))
    a=returns_(returns)

    ## new_df
    start_date = start_2
    end_date = end_1
    new_df = 돌려보기(new_codes, start_date, end_date)
    #new_df

    ## symbol_codes 
    cond = (new_df['조건승률']>0.55 ) &(new_df['기하수익률']>0.005) & (new_df['최대손실률']>-0.04) & (new_df['조건만족횟수']>1) & (new_df['랭크_돌파']<3) & (new_df['랭크_중앙']<3)
    symbol_codes = list(new_df[cond]['종목이름'])

    ## symbol_codes 3개월 그리기
    start= start_2 #한달전으로 세팅
    end = end_1
    returns = pd.DataFrame()
    for code in symbol_codes:
        df2 = backtest(code,k=0.5,start=start, end_date=end)
        returns[code] = df2
        #time.sleep(0.01)
    returns.set_index(returns.reset_index()['date'].apply(lambda x:pd.to_datetime(x)),inplace=True)
    returns.set_index(returns.index.strftime("%Y-%m-%d"),inplace=True)
    print("symbol_codes:{}".format(len(symbol_codes)))
    print("{} ~ {} 수익률 : {:.2%}".format(start, end, returns.mean(axis=1).dropna().cumprod().iloc[-1]))
    a=returns_(returns)
    #returns.mean(axis=1).cumprod().plot()

    ## symbol_codes 1달
    if end_1 == end_2 : #결과만 보여주기
        pass
    else:
        start=start_3 #한달전으로 세팅
        end = end_2
        returns = pd.DataFrame()
        for code in symbol_codes:
            df2 = backtest(code,k=0.5,start=start, end_date=end)
            returns[code] = df2
            #time.sleep(0.01)
        returns.set_index(returns.reset_index()['date'].apply(lambda x:pd.to_datetime(x)),inplace=True)
        returns.set_index(returns.index.strftime("%Y-%m-%d"),inplace=True)
        print("{} ~ {} 수익률 : {:.2%}".format(start, end, returns.mean(axis=1).dropna().cumprod().iloc[-1]))
        a=returns_(returns)
    return symbol_codes

■ 2021.01.15~2021.02.15 ▶ 108%

종목찾기_12M_3M(start_1='2019-12-15', start_2='2020-09-15',start_3='2020-12-15',end_1='2021-01-14',end_2='2021-02-15')

 

(아래부터는 한달 결과만)

 

■ 2020.12월 ▶ 104%

종목찾기_12M_3M(start_1='2019-11-01', start_2='2020-08-01',start_3='2020-10-31',end_1='2020-11-30',end_2='2020-12-31')

■ 2020.11월 ▶ 102%

종목찾기_12M_3M(start_1='2019-10-01', start_2='2020-07-01',start_3='2020-10-01',end_1='2020-10-31',end_2='2020-11-30')

분산투자가 필요해 보인다.. 1종목은 너무 위험해 보임

■ 2020.10월 ▶94%

종목찾기_12M_3M(start_1='2019-09-01', start_2='2020-06-01',start_3='2020-09-01',end_1='2020-09-31',end_2='2020-10-30')

■ 2020.9월 ▶78%

종목찾기_12M_3M(start_1='2019-08-01', start_2='2020-05-01',start_3='2020-08-01',end_1='2020-08-31',end_2='2020-9-30')

■ 2020.8월 ▶108%

종목찾기_12M_3M(start_1='2019-07-01', start_2='2020-04-01',start_3='2020-07-01',end_1='2020-07-30',end_2='2020-8-30')

■ 2020.7월 ▶ 99%

종목찾기_12M_3M(start_1='2019-06-01', start_2='2020-03-01',start_3='2020-06-01',end_1='2020-06-30',end_2='2020-7-30')

■ 2020.6월 ▶ 93%

종목찾기_12M_3M(start_1='2019-05-01', start_2='2020-02-01',start_3='2020-05-01',end_1='2020-05-30',end_2='2020-6-30')

■ 2020.5월 ▶107%

종목찾기_12M_3M(start_1='2019-04-01', start_2='2020-01-01',start_3='2020-04-01',end_1='2020-04-30',end_2='2020-5-30')

 

 

■ 2020.4월 ▶110%

종목찾기_12M_3M(start_1='2019-03-01', start_2='2019-12-01',start_3='2020-03-01',end_1='2020-03-30',end_2='2020-4-30')

■ 2020.3월 ▶100%

종목찾기_12M_3M(start_1='2019-02-01', start_2='2019-11-01',start_3='2020-02-01',end_1='2020-02-29',end_2='2020-3-30')

■ 2020.2월 ▶98%

종목찾기_12M_3M(start_1='2019-01-01', start_2='2019-10-01',start_3='2020-01-01',end_1='2020-01-30',end_2='2020-2-29')

 

■ 2020.1월 ▶101%

종목찾기_12M_3M(start_1='2018-12-01', start_2='2019-09-01',start_3='2019-12-01',end_1='2019-12-30',end_2='2020-1-30')

■ 2019.12월 ▶97%

종목찾기_12M_3M(start_1='2018-11-01', start_2='2019-08-01',start_3='2019-11-01',end_1='2019-11-30',end_2='2019-12-30')

■ 2019.11월 ▶100%

종목찾기_12M_3M(start_1='2018-10-01', start_2='2019-07-01',start_3='2019-10-01',end_1='2019-10-30',end_2='2019-11-30')

 

■ 2019.10월 ▶100%

종목찾기_12M_3M(start_1='2018-09-01', start_2='2019-06-01',start_3='2019-09-01',end_1='2019-9-30',end_2='2019-10-30')

 

■ 2019.09월 ▶97%

종목찾기_12M_3M(start_1='2018-08-01', start_2='2019-05-01',start_3='2019-08-01',end_1='2019-8-30',end_2='2019-9-30')

 

■ 2019.08월 ▶90%

종목찾기_12M_3M(start_1='2018-07-01', start_2='2019-04-01',start_3='2019-07-01',end_1='2019-7-30',end_2='2019-8-30')

 

■ 2019.07월 ▶97%

종목찾기_12M_3M(start_1='2018-06-01', start_2='2019-03-01',start_3='2019-06-01',end_1='2019-6-30',end_2='2019-7-30')

 

■ 2019.06월 ▶103%

종목찾기_12M_3M(start_1='2018-05-01', start_2='2019-02-01',start_3='2019-05-01',end_1='2019-5-30',end_2='2019-6-30')

 

▶ 과거를 갈수록 변동성파 조건을 만족하는 종목의 수가 많이 줄어들었다. 3개 까지도 줄어들었으며,, 그래서 

임의 종목에 대한 수익률이 아닌 실제 테스트 종목의 수익률이 된다. 

생각보다 과거로 갈수록 안 좋아 보이지만, 하락인 월을 보면, 초반보다는 후반부에 하락폭이 더 큰 것으로 보이며 더 짧은 주기로 종목을 변경하면 어떨까란 생각이 들긴한다.. 

 

Comments