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

[파이썬 주식] 변동성돌파전략 - 10. 조건추가 PB(2) 본문

STOCK/변동성돌파전략

[파이썬 주식] 변동성돌파전략 - 10. 조건추가 PB(2)

BOTTLE6 2021. 2. 13. 10:21

## 20210212_3.

 

몇가지 종목으로 pb값 정하기

수익률 슬리피지 -0.006으로 변경

 

## 1. 종목

codes = ['A053450', 'A074600', 'A065560', 'A088130', 'A039560', 'A093920', 'A066620', 'A357780', 'A262260', 'A332570', 'A064760', 'A000990', 'A029460','A204320','A011790','A000990','A029460','A005070']
codes = [code[1:] for code in codes]
codes

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

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   

## 3. 백테스트 pb 조건 전

def backtest(code, k, start):
    df=pd.DataFrame()
    df = df=mk.get_daily_price(code, start)
    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)
    cond = ( df['high'] > df['목표가'] ) & ( df['목표가'] > df['MA3_yes'] )
    df.loc[cond,'수익률'] = df.loc[cond,'내일시가']/df.loc[cond,'목표가']*0.9975 - 0.006 #0.9975 수수료, 0.002 슬리피지
    return df['수익률']

returns = pd.DataFrame()
for code in codes:
    df = backtest(code,k=0.5,start='2020-01-01')
    returns[code] = df
    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)

plt.figure(figsize=(12,8))
returns.mean(axis=1).cumprod().plot()

▶ 평균 수익률은 1년동안 거의없음

 

## 4. 백테스트 pb <0.6

def backtest(code, k, start):
    df=pd.DataFrame()
    df = df=mk.get_daily_price(code, start)
    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)
    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 슬리피지
    return df['수익률']
returns = pd.DataFrame()
for code in codes:
    df = backtest(code,k=0.5,start='2020-01-01')
    returns[code] = df
    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)
returns.mean(axis=1).cumprod().plot()

 

▶ pb조건이 없을 때보다는 최종적으로 2배로, 상승하였음.

그렇지만 하락하는 경우도 많이 눈에 보임.

 

## 백테스트 그외 

(pb < 0.3)

(pb < 0.9)

 

Comments