본문 바로가기
개발일지

파이썬 투자 보조 지표 분석 / 전략 설계 - 스토캐스틱

by kirion 2022. 11. 23.
728x90
반응형

투자 보조 지표 스토캐스틱

세 번째 시간으로 스토캐스틱에 대해 알아보겠다. 

 

스토캐스틱

스토캐스틱이란 주가는 파동적 성격을 가지고 있다. 주가가 과열되면 조만간 하락할 것이고, 반대로 침체되어있으면 조만간 반등할 것이라 예상해 볼 수 있는데 이러한 속성을 지표화 한 것이 스토캐스틱이다. 

원래 채권시장에서 사용하기 위해 만들어졌는데, 주식시장에서도 효과가 나타나서 알려진 지표이다.

주가의 큰 추세에서는 사용할 수 없고, 박스권이나 횡보하는 장에서 유용하다.

 

스토캐스틱 계산 방법

Stochastic = (현재 가격 - N일 최저 가격) / (N일 최고 가격 - N일 최저 가격) * 100

 

해석

N일 간 최고, 최저 가격의 최저 가격의 차에서 현재의 가격과 최저 가격의 차에 대한 백분율로 나타낸 것. 0~100% 사이 값을 가진다.

 

전략

  • 20% 이하일 때 과매도 구간 -> 매수 시점
  • 80% 이상일 때 과매수 구간 -> 매도 시점

하지만 스토캐스틱은 변화가 심하고 거짓 신호가 많이 보이기 때문에 보완된 지표를 사용한다. 

 

슬로우 스토캐스틱 계산 방법

Stochastic K = Stochastic A 일 이동 평균

Stochastic D = Stochastic K  M일 이동 평균

 

쉽게 정리하면 스토캐스틱을 A를 이동 평균하면 스토캐스틱 K라 하고, 스토캐스틱 K를 또다시 M일 이동 평균하면 스토캐스틱 D이다. 이를 활용해 Fast Stochastic과 Slow Stochastic으로 구분한다.

  • Fast Stochastic : Stochastic과 Stochastic K 사용.
  • Slow Stochastic : Stochastic K와 Stochastic D 사용. 

N, A, M의 적용 숫자는 다양하게 사용할 수 있는다.

  • 5 - 3 - 3
  • 10 - 6 - 6
  • 14 - 3 - 3
  • 20 - 12 -12

전략

  • 스토캐스틱이 20 이하에서 K선이 D선을 상향 돌파하면 매수 관점
  • 스토캐스틱 80 이상에서 K선이 D선을 하향 돌파하면 매도 관점

파이썬 구현

import ta
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import FinanceDataReader as fdr
import copy
df_krx = fdr.StockListing('KRX')

kospi_data = df_krx[(df_krx["Market"]=="KOSPI") & (~df_krx["Sector"].isna())]

target = kospi_data[kospi_data["Name"]=="KT&G"]

price_data = fdr.DataReader("033780","2020","2022-11-17")

 

# 네이버 증권 기준 fast, slow 계산 일 수
#Fast 5 -3 -3
#Slow 12 -5 -3
# Fast %K
def stochastic(close_price, low, high, n=5):
    fast_k = ((close_price - low.rolling(n).min()) / (high.rolling(n).max() - low.rolling(n).min())) * 100
    return fast_k
 
# Fast %D, Slow %K = Fast %K의 A기간 이동평균(SMA)
def stochastic_k(stoch, n=3):
    fast_d = stoch.rolling(n).mean()
    return fast_d
 
# Slow %D = Slow %K의 M기간 이동평균(SMA)
def stochastic_d(fast_k, n=3):
    slow_d = fast_k.rolling(n).mean()
    return slow_d

 

계산 함수는 위와 같다. 

네이버 증권 기준으로 Fast는 5 - 3, Slow는 12 - 5 - 3이다. 네이버 기준으로 계산해 보겠다.

stochastic, stochastic_k는 Fast %K, %D로 계산되는 함수이고,

stochastic_k, stochastic_d는 Slow %K, %D로 계산되는 함수이다.

stoch = stochastic(price_data['Close'],price_data['Low'],price_data['High'],5)
stoch_k = stochastic_k(stoch,3)
stoch_d = stochastic_d(stoch_k,3)

price_data["fast_k"] = stoch
price_data["fast_d"] = stoch_k

stoch = stochastic(price_data['Close'],price_data['Low'],price_data['High'],12)
stoch_k = stochastic_k(stoch,5)
stoch_d = stochastic_d(stoch_k,3)

price_data["slow_k"] = stoch_k
price_data["slow_d"] = stoch_d
price_data_tmp = price_data[price_data.index>"2022"].copy()
price_data_tmp["lower"] = 20
price_data_tmp["upper"] = 80

2022년 데이터를 대상으로 시각화한다.

# Fast
fig, ax1 = plt.subplots(figsize = (14,7)) 
ax1.set_ylabel('Price') 
ax1.plot(price_data_tmp["Close"],color = "black",alpha = 0.7)

ax2 = ax1.twinx() 
ax2.set_ylabel('Index') 
ax2.plot(price_data_tmp["fast_k"],color = "blue",alpha = 0.5)
ax2.plot(price_data_tmp["fast_d"],color = "red",alpha = 0.5)
ax2.plot(price_data_tmp["upper"],color = "black",alpha = 0.5)
ax2.plot(price_data_tmp["lower"],color = "black",alpha = 0.5)
ax2.legend(["fast_k","fast_k"],loc = "upper right")
plt.title(target["Name"].values[0])
plt.show()

# Slow
fig, ax1 = plt.subplots(figsize = (14,7)) 
ax1.set_ylabel('Price') 
ax1.plot(price_data_tmp["Close"],color = "black",alpha = 0.7)

ax2 = ax1.twinx() 
ax2.set_ylabel('Index') 
ax2.plot(price_data_tmp["slow_k"],color = "blue",alpha = 0.5)
ax2.plot(price_data_tmp["slow_d"],color = "red",alpha = 0.5)
ax2.plot(price_data_tmp["upper"],color = "black",alpha = 0.5)
ax2.plot(price_data_tmp["lower"],color = "black",alpha = 0.5)
ax2.legend(["slow_k","slow_d"],loc = "upper right")
plt.title(target["Name"].values[0])
plt.show()

Fast
Slow

 

Fast 스토캐스틱의 경우 굉장히 빈번하게 매수, 매도 신호나 나온다. 주가가 지속적으로 오르고 있음에도 불구하고 확실히 거짓 신호가 많이 보인다. 

반면, Slow 스토캐스틱은 거짓된 신호는 제거된 것 같다.

따라서 슬로우 스토캐스틱 %D로 벡테스팅을 간단하게 돌려보자.

 

벡테스팅 방식과 결과는 이전 글을 참고 바란다.

2022.11.07 - [개발일지] - 3. 투자지표를 활용한 매매 시점 모니터링 - 벡테스팅

2022.11.08 - [개발일지] - 5. 투자지표를 활용한 매매 시점 모니터링 - Kospi 종목 벡테스팅

2022.11.09 - [개발일지] - 6. 투자지표를 활용한 매매 시점 모니터링 - 손절선

 

 

시드머니 1,000만원 1회 매매 금액 500만원으로 2012년부터 22년까지 테스트한 결과이다.

손절선 RSI Stochastic
손절선 X
  • 손익 확률 + : 57.73%, - : 42.27%
  • 최대 손익률 + : 30.14%, - 66.8%
  • 손익 + 연평균 수익률
    중위수 : 5.17%, 평균 : 5.96%
  • 손익 - 연평균 수익률
    중위수 : -4.45%, 평균 : -7.29%
  • 기대 수익금
    중위수 : 289만원, 평균 : 254만원
  • 손익 확률 + : 50.79%, - : 49.21%
  • 최대 손익률 + : 49.61%, - 57.91%
  • 손익 + 연평균 수익률
    중위수 : 4.65%, 평균 : 6.23%
  • 손익 - 연평균 수익률
    중위수 : -4.75%, 평균 : -7.38%
  • 기대 수익금
    중위수 : 190만원, 평균 : 295만원
-3.5%
  • 손익 확률 + : 69.43%, - : 30.57%
  • 최대 손익률 + : 17.21%, - 24.15%
  • 손익 + 연평균 수익률
    중위수 : 3.09%, 평균 : 3.71%
  • 손익 - 연평균 수익률
    중위수 : -1.95%, 평균 : -3.36%
  • 기대 수익금
    중위수 : 177만원, 평균 : 174만원
  • 손익 확률 + : 49.21%, - : 50.67%
  • 최대 손익률 + : 48.93%, - 36.14%
  • 손익 + 연평균 수익률
    중위수 : 3.79%, 평균 : 4.99%
  • 손익 - 연평균 수익률
    중위수 : -3.99%, 평균 : -5.44%
  • 기대 수익금
    중위수 : 116만원, 평균 : 198만원
-10%
  • 손익 확률 + : 59.56%, - : 40.44%
  • 최대 손익률 + : 30.14%, - 43.2%
  • 손익 + 연평균 수익률
    중위수 : 3.56%, 평균 : 4.28%
  • 손익 - 연평균 수익률
    중위수 : -2.48%, 평균 : -4.38%
  • 기대 수익금
    중위수 : 197만원, 평균 : 160만원
  • 손익 확률 + : 50.18%, - : 49.82%
  • 최대 손익률 + : 30.23%, - 23.9%
  • 손익 + 연평균 수익률
    중위수 : 3.3%, 평균 : 4.24%
  • 손익 - 연평균 수익률
    중위수 : -2.63%, 평균 : -3.93%
  • 기대 수익금
    중위수 : 149만원, 평균 : 186만원

 

손익 확률에서 너무 확률이 떨어진다. stochastic 자동매매를 할 시에 수익을 얻을 확률이 반반이라니.. 여전히 RSI가 가장 안정적이고 우수한 성과를 보이고 있다.

 

계산하고 나니 기대 수익금에 오류가 있다.

똑같이 1,000만원으로 연평균 수익, 손해율을 이용해 최종 금액을 계산 후 그 차를 기대 수익금이라 적었는데 손익 확률에서 차이가 나는 것을 반영하지 못했다.

손익 확률이 똑같이 50 대 50 이면 기대 수익률이 어느 정도 의미가 있겠지만, 60 대 40이 된 경우 수익 쪽을 더 가중해야 정확한 기대 수익률이 나온다.

수정하자면 현재 1대 1 기준으로 기대 수익금을 계산하고 있으므로 이 상황을 손익 확률 50% 대 50%라고 가정하고, 60% : 40% 일대 1.2 : 0.8로 가중치를 두어 계산하면 심플한 방법으로 반영될 것 같다. 

 

수정안을 조금 더 고민해보고 하루 날 잡아서 벡테스팅 결과표를 수정해야겠다.

 

 

728x90
반응형

댓글