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

[파이썬 주식] 변동성돌파전략 - 7. kospi와 수익률 관계? 본문

STOCK/변동성돌파전략

[파이썬 주식] 변동성돌파전략 - 7. kospi와 수익률 관계?

BOTTLE6 2021. 1. 30. 23:01

### 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
# 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. 종목 데이터 불러오기

# 백테스트 함수 정의
def backtest(code, k, start):
    code = str(code)+".KS"
    df=pd.DataFrame()
    df = pdr.get_data_yahoo(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.0032
    return df['수익률']

# 코드불러오기
codes = ['A204320', 'A028050', 'A035150', 'A011210', 'A131390', 'A006360', 'A005070', 'A005380', 'A001510', 'A001140', 'A068270', 'A004020', 'A032560', 'A200130', 'A039490',
 'A079430', 'A000990', 'A011790', 'A210980', 'A002840', 'A035510', 'A029460', 'A086280', 'A005940', 'A006800', 'A020760', 'A011760', 'A069260']
codes = [ code[1:] for code in codes ]

# 수익률 함수 만들기
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.index.strftime("%Y-%m-%d"),inplace=True)

# 수익률 결과 정리하기
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 )

 

### 3. 코스피 데이터 합치기

kospi = pdr.get_data_yahoo( "^KS11",'2020-01-01' )
kospi['어제종가']=kospi.Close.shift(1)
kospi['수익률']=(kospi['Close']/kospi['어제종가'])
kospi.set_index(kospi.index.strftime("%Y-%m-%d"),inplace=True)
# kospi수익률을 returns_함수에 합치기
returns_['코스피']=kospi['수익률']
returns_

 

 

### 4. 시각화

fig, ax = plt.subplots(figsize=(20,8))
returns_[['mean','코스피']].plot(ax=ax)
ax.plot(np.ones(returns_.shape[0]),color='black')

plt.figure(figsize=(20,10))

ax1 = plt.subplot(2,2,1)
cond = returns_['mean']>1
data= returns_.loc[cond]
data[['mean','코스피']].plot(ax=ax1)
ax1.plot(np.ones(data.shape[0]),color='black')
plt.title("mean>1")

ax2= plt.subplot(2,2,2)
cond = returns_['mean']<1
data= returns_.loc[cond]
data[['mean','코스피']].plot(ax=ax2)
ax2.plot(np.ones(data.shape[0]),color='black')
plt.title("mean<1")

ax3 = plt.subplot(2,2,3)
cond = returns_['코스피']>1
data= returns_.loc[cond]
data[['mean','코스피']].plot(ax=ax3)
ax3.plot(np.ones(data.shape[0]),color='black')
plt.title("코스피>1")

ax4= plt.subplot(2,2,4)
cond = returns_['코스피']<1
data= returns_.loc[cond]
data[['mean','코스피']].plot(ax=ax4)
ax4.plot(np.ones(data.shape[0]),color='black')
plt.title("코스피<1")

plt.figure(figsize=(20,10))

ax1 = plt.subplot(2,2,1)
cond = (returns_['mean']>1)&(returns_['코스피']>1)
data= returns_.loc[cond]
data[['count']].plot.hist(ax=ax1)
plt.title("mean>1 코스피>1")

ax2= plt.subplot(2,2,2)
cond = (returns_['mean']<1)&(returns_['코스피']>1)
data= returns_.loc[cond]
data[['count']].plot.hist(ax=ax2)
plt.title("mean<1 코스피>1")

ax3 = plt.subplot(2,2,3)
cond = (returns_['mean']>1)&(returns_['코스피']<1)
data= returns_.loc[cond]
data[['count']].plot.hist(ax=ax3)
plt.title("mean>1 코스피<1")

ax4= plt.subplot(2,2,4)
cond = (returns_['mean']<1)&(returns_['코스피']<1)
data= returns_.loc[cond]
data[['count']].plot.hist(ax=ax4)
plt.title("mean<1 코스피<1")

 

Comments