4주차 2편에서는
사는 시점(buy)과 파는 시점(sell)을 구해
그 종가로 수익률을 구해보고,
장/단기 이평선을 적용시킨 수익률을 구한 후,
최적의 장/단기 이평선을 구하는 내용을 배웠다.
복잡하고 어려운 내용들로 가득해서,
천천~히 여러번 반복해봐야겠다.
6. 수익률 구하기
1) 실제로 사는 시점(buy)
- buy > buy > buy 혹은 sell > sell > sell 이라면, 사거나 파는게 아니다.
- 즉, buy와 sell이 바뀌는 순간이 중요하다.
- action_temp라는 열을 만들고, action 값들을 한칸씩 뒤로 밀어 넣는다. 그러면 buy와 sell이 바뀌는 부분을 확인할 수 있다.
df['action_temp'] = df['action'].shift(1)
- 위와 같은 조건에 부합하는 cond을 만들어 본다.
cond = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
df['real_buy'] = np.where(cond,'buy','')
df
- 사는 날짜(buy)를 모아본다.
cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
df[cond]
2) 실제로 파는 시점(sell)
- 사는 시점을 모으는 것과 마찬가지로 cond2를 만들어 파는 시점(sell)을 모아본다.
cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')
df_sell = df[cond2]
df_sell
3) 마지막 시점에서 무조건 팔기
- 마지막에 팔아야 수익율을 알 수 있다
df = fdr.DataReader('005930','2018')
df = df[['Close']]
df['ma'] = df.rolling(3).mean().shift(1)
df['action'] = np.where(df['Close'] > df['ma'], 'buy', 'sell')
df.iloc[-1,-1] = 'sell'
cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')
df_buy = df[cond1]
df_sell = df[cond2]
4) 사고, 파는 시점을 붙이기
- `concat` 을 이용하면 되는데, 가로로 붙이려면 `,axis=1`를 써준다.
df_result = pd.concat([df_buy,df_sell],axis=1)
df_result
5) 전략 세워보기
- buy 때 사서, sell에 파는 것인데, 더 쉽게 보기 위해 .reset_index()를 이용해 가로로 붙여본다.
- buy 때의 Close와 sell 때의 Close 에 주목하면 된다.
df_buy = df[cond1].reset_index()
df_sell = df[cond2].reset_index()
df_result = pd.concat([df_buy,df_sell],axis=1)
df_result
6) 수익률 구하기
- 먼저, 헷갈리지 않도록 Close라는 컬럼명을 다르게 수정해준다.
- 그리고, `수익률 = 종가(sell) / 종가(buy)` 를 추가해준다.
df_buy = df[cond1].reset_index()
df_buy.columns = ['날짜','종가(buy)','이평값','액션']
df_sell = df[cond2].reset_index()
df_sell.columns = ['날짜','종가(sell)','이평값','액션']
df_result = pd.concat([df_buy,df_sell],axis=1)
df_result['수익률'] = df_result['종가(sell)'] / df_result['종가(buy)']
df_result
7) 오류 해결하기
- 기존 dataframe을 건드리지 않고 수익률을 가져오기 위해 .copy()를 써준다.
df = df[['Close']].copy()
8) 누적 수익률 계산하기
- .cumprod()를 입력하면 누적 곱을 볼 수 있다.
df_result[['수익률']].cumprod()
- 누적 곱의 마지막 값(수익률)을 가져온다.
df_result[['수익률']].cumprod().iloc[-1,-1]
- 1(원금)을 빼주고 100을 곱해주면 수익률(%)이 나온다.
(df_result[['수익률']].cumprod().iloc[-1,-1] - 1)*100
9) 함수로 만들기
- 코드만 입력하면 될 수 있도록 함수로 만들어본다.
- get_return(code,n) 에 기업 코드와 기준일을 넣어, 수익률이 얼마인지 확인해본다.
def get_return(code,n):
df = fdr.DataReader(code,'2018')
df = df[['Close']].copy()
df['ma'] = df.rolling(n).mean().shift(1)
df['action'] = np.where(df['Close'] > df['ma'], 'buy', 'sell')
df.iloc[-1,-1] = 'sell'
cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')
df_buy = df[cond1].reset_index()
df_buy.columns = ['날짜','종가(buy)','이평값','액션']
df_sell = df[cond2].reset_index()
df_sell.columns = ['날짜','종가(sell)','이평값','액션']
df_result = pd.concat([df_buy,df_sell],axis=1)
df_result['수익률'] = df_result['종가(sell)'] / df_result['종가(buy)']
return df_result[['수익률']].cumprod().iloc[-1,-1] - 1
7. 단기/장기이평선 적용하기
1) 단기/장기이평선 구하기
- rolling의 숫자를 3일(단기) , 10일(장기)로 지정해준다.
df = fdr.DataReader('005930','2018')
df = df[['Close']].copy()
df['ma_1'] = df['Close'].rolling(3).mean().shift(1)
df['ma_2'] = df['Close'].rolling(10).mean().shift(1)
df
2) 적절한 값으로 수정하기
- Close, ma_1, ma_2 를 고려하여 컬럼값을 추가해준다.
df = fdr.DataReader('005930','2018')
df = df[['Close']].copy()
df['ma_1'] = df['Close'].rolling(3).mean().shift(1)
df['ma_2'] = df['Close'].rolling(10).mean().shift(1)
df['action'] = np.where(df['ma_1'] > df['ma_2'], 'buy', 'sell')
df.iloc[-1,-1] = 'sell'
cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')
df_buy = df[cond1].reset_index()
df_buy.columns = ['날짜','종가(buy)','이평값1','이평값2','액션']
df_sell = df[cond2].reset_index()
df_sell.columns = ['날짜','종가(sell)','이평값1','이평값2','액션']
df_result = pd.concat([df_buy,df_sell],axis=1)
df_result['수익률'] = df_result['종가(sell)'] / df_result['종가(buy)']
df_result
- 수익률의 마지막 값을 .tail(1)로 바꾸어 주고, 단기·장기 컬럼을 만들어준다.
df_final = (df_result[['수익률']].cumprod().tail(1) - 1)*100
df_final['단기'] = 3
df_final['장기'] = 10
df_final
3) 함수로 만들기
- 함수로 만들고, code, short, long 값만 바꿔주면 된다.
- 그러면 기업의 단기, 장기 기준일을 정해서 수익률을 확인할 수 있다.
def get_return_sl(code, short, long):
df = fdr.DataReader(code,'2018')
df = df[['Close']].copy()
df['ma1'] = df['Close'].rolling(short).mean().shift(1)
df['ma2'] = df['Close'].rolling(long).mean().shift(1)
df['action'] = np.where(df['ma1'] > df['ma2'], 'buy', 'sell')
df.iloc[-1,-1] = 'sell'
cond1 = (df['action'] == 'buy') & (df['action'].shift(1) == 'sell')
cond2 = (df['action'] == 'sell') & (df['action'].shift(1) == 'buy')
df_buy = df[cond1].reset_index()
df_buy.columns = ['날짜','종가(buy)','이평값1','이평값2','액션']
df_sell = df[cond2].reset_index()
df_sell.columns = ['날짜','종가(sell)','이평값1','이평값2','액션']
df_result = pd.concat([df_buy,df_sell],axis=1)
df_result['수익률'] = df_result['종가(sell)'] / df_result['종가(buy)']
df_final = (df_result[['수익률']].cumprod().tail(1) - 1)*100
df_final['단기'] = short
df_final['장기'] = long
return df_final
4) 한 종목에 대한 최적의 단기/장기이평선 구하기
- for문을 이용해서 최적의 단/장기 이평선과 수익률을 구해본다.
'CODING > PYTHON' 카테고리의 다른 글
[Python] 5주차_백테스팅 기초(2) : 월-금 전략 (Feat. 스파르타코딩클럽) (0) | 2022.12.20 |
---|---|
[Python] 5주차_백테스팅 기초(2) : 변동성 돌파 전략 (Feat. 스파르타코딩클럽) (0) | 2022.12.20 |
[Python] 4주차_백테스팅 기초(1) : 골든/데드크로스 전략 구현 (1편) (Feat. 스파르타코딩클럽) (0) | 2022.12.13 |
[Python] 3주차_DART 데이터 내 마음대로 활용하기(3편) (Feat. 스파르타코딩클럽) (1) | 2022.12.08 |
[Python] 3주차_DART 데이터 내 마음대로 활용하기(2편) (Feat. 스파르타코딩클럽) (0) | 2022.12.08 |