웬디의 기묘한 이야기

글 작성자: WENDYS
반응형

https://wendys.tistory.com/174 - pandas_datareader를 이용하여 주식 데이터 가져오기! Yahoo Finance

Stochastic Oscillator 개념

스토캐스틱은, 최근 N일간의 최고가와 최저가의 범위 내에서 현재 가격의 위치를 표시할 때, 매수세가 매도세보다 강할 때는 그 위치가 높게 형성되고, 매도세가 매수세보다 강할 때는 그 위치가 낮게 형성된다는 것을 이용한 것이다.

 

예를 들어 최근 5일간 최고가가 15,000원이고 최저가가 10,000원인 주식이 있을때, 현재가가 14,000원이라면 매수세가 강하여 오르는 추세임을 알 수 있다. 만일 현재가가 11,000원이라면 매도세가 강하여 내리는 추세임을 알 수 있다.

 

예를 들어 최근 15일 중 최고가가 15,000원이고 최저가가 10,000원이며 현재가격이현재 가격이 14,000원이라면, 스토캐스틱 값은 80%가 된다. 고가가 15,000원이고 저가가 10,000원이며 현재 가격이 11,000원이라면, 스토캐스틱 값은 20%가 된다.

스토캐스틱 값의 범위는 항상 0~100% 사이가 된다. 100%라면 현재 가격이 N일간 최고가이므로 매수세가 가장 강한 경우가 되며, 0%라면 현재 가격이 N일간 최저가이므로 매도세가 가장 강한 경우가 된다.

 

https://ko.wikipedia.org/wiki/%EC%8A%A4%ED%86%A0%EC%BA%90%EC%8A%A4%ED%8B%B1 - WIKI

 

스토캐스틱에는 Fast Stochastic과 Slow Stochastic이 존재합니다.

Fast Stochastic은 그래프의 변화가 너무 잦고 급격하여 노이즈 즉 가짜 신호가 많아 매수 매도시 참고하기 어렵다는 문제점이 있기 때문에 일반적으로 Slow Stochastic을 사용합니다.

 

Fast Stochastic 공식

  • Fast %K = ((현재가 - n기간 중 최저가) / (n기간 중 최고가 - n기간 중 최저가)) * 100
  • Fast %D = Fask %K의 m기간 이동평균(SMA)

 

%K를 계산할 때 n기간 값을 5를 사용하고, m과 t기간 값은 3일을 사용하는 것이 일반적입니다. n기간을 10으로 사용하면 m과 t기간 값은 6으로 배수로 설정해서 활용하는 것이 좋습니다.

 

Slow Stochastic 공식

  • Slow %K = Fast %K의 m기간 이동평균(SMA)
  • Slow %D = Slow %K의 t기간 이동평균(SMA)

 

Slow Stochastic에서는 n(5)-m(3)-t(3) 공식이 가장 많이 사용되며, 이 값은 임의로 조절하여 사용할 수 있습니다.

예를 들어 대부분 증권사에서는 n(5)-m(3)-t(3)를 사용하고 네이버금융은 n(15)-m(5)-t(3)을 이용하고 있습니다.

 

위의 Fast %K (K), Slow %K (D), Slow %D (J) 를 K, D, J라고 표현하기도 하며, 그렇기 때문에 Slow Stochastic을 KDJ Stochastic 지표라고 부르기도 합니다.

 

이런 점에 착안하여 스토캐스틱 %K선과 %D선을 이용한 매매 기법이 있습니다.

과매수, 과매도의 구역을 설정하여 스토캐스틱이 80 이상일 때 과매수 상태, 20 이하일 때 과매도 상태로 판단하여 시장 가격이 과매수 상태에 들어서면 하락의 가능성이 커지고, 반대로 과매도 상태에 들어서면 상승의 가능성이 커지는 것을 이용한 매매법 기법이 있습니다.

여기서 %K선과 %D선이 교차하는 순간을 매매 시점으로 판단하여 오류를 최대한 줄이도록 하는 게 중요합니다.

 

스토캐스틱 20 이하에서 %K선이 %D선을 상향 돌파하면 골든크로스라고 하여 매수 관점으로 접근할 수 있고,

스토캐스틱 80 이상에서 %K선이 %D선을 하향 돌파하면 데드크로스라고 하여 매도 관점으로 바라볼 수 있습니다.

 

 

그렇다면 코드로 구현을 해볼까요??

Python Slow Stochastic Code

# Fast %K = ((현재가 - n기간 중 최저가) / (n기간 중 최고가 - n기간 중 최저가)) * 100
def get_stochastic_fast_k(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

# Slow %K = Fast %K의 m기간 이동평균(SMA)
def get_stochastic_slow_k(fast_k, n=3):
  slow_k = fast_k.rolling(n).mean()
  return slow_k

# Slow %D = Slow %K의 t기간 이동평균(SMA)
def get_stochastic_slow_d(slow_k, n=3):
  slow_d = slow_k.rolling(n).mean()
  return slow_d

...

# fast_k, slow_k, slow_d를 획득
df['fast_k'] = get_stochastic_fast_k(df['Close'], df['Low'], df['High'], 5)
df['slow_k'] = get_stochastic_slow_k(df['fast_k'], 3)
df['slow_d'] = get_stochastic_slow_d(df['slow_k'], 3)


df.plot(y=['Close'], figsize = (20, 5))

# Slow %K, Slow %D를 그려서 확인
df.plot(y=['slow_k', 'slow_d'], figsize = (20, 5))

 

Python Slow Stochastic Full Code

import pandas as pd
import pandas_datareader as pdr
import datetime

# 종목 타입에 따라 download url이 다름. 종목코드 뒤에 .KS .KQ등이 입력되어야해서 Download Link 구분 필요
stock_type = {
    'kospi': 'stockMkt',
    'kosdaq': 'kosdaqMkt'
}

# 회사명으로 주식 종목 코드를 획득할 수 있도록 하는 함수
def get_code(df, name):
  code = df.query("name=='{}'".format(name))['code'].to_string(index=False)
  
  # 위와같이 code명을 가져오면 앞에 공백이 붙어있는 상황이 발생하여 앞뒤로 sript() 하여 공백 제거
  code = code.strip()
  return code

# download url 조합
def get_stock_code(market_type=None):
  market_type_param = stock_type[market_type]
  download_link = 'http://kind.krx.co.kr/corpgeneral/corpList.do'
  download_link = download_link + '?method=download'
  download_link = download_link + '&marketType=' + market_type_param

  df = pd.read_html(download_link, header=0)[0]
  return df;

# kospi 종목코드 목록 다운로드
def get_stock_code_kospi():
  df = get_stock_code('kospi')
  df.종목코드 = df.종목코드.map('{:06d}.KS'.format)
  return df

# kosdaq 종목코드 목록 다운로드
def get_stock_code_kosdaq():
  df = get_stock_code('kosdaq')
  df.종목코드 = df.종목코드.map('{:06d}.KQ'.format)
  return df

# Fast %K = ((현재가 - n기간 중 최저가) / (n기간 중 최고가 - n기간 중 최저가)) * 100
def get_stochastic_fast_k(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

# Slow %K = Fast %K의 m기간 이동평균(SMA)
def get_stochastic_slow_k(fast_k, n=3):
  slow_k = fast_k.rolling(n).mean()
  return slow_k

# Slow %D = Slow %K의 t기간 이동평균(SMA)
def get_stochastic_slow_d(slow_k, n=3):
  slow_d = slow_k.rolling(n).mean()
  return slow_d


# kospi, kosdaq 종목코드 각각 다운로드
kospi_df = get_stock_code_kospi()
kosdaq_df = get_stock_code_kosdaq()

# data frame merge
code_df = pd.concat([kospi_df, kosdaq_df])

# data frame정리
code_df = code_df[['회사명', '종목코드']]

# data frame title 변경 '회사명' = name, 종목코드 = 'code'
code_df = code_df.rename(columns={'회사명': 'name', '종목코드': 'code'})

code = get_code(code_df, '삼성전자')

start = datetime.datetime(2019,1,1)
end = datetime.date(2019,12,31)

# 수정주가를 반영
df = pdr.get_data_yahoo(code, start, end, adjust_price=True)

df['Close'].plot()


# fast_k, slow_k, slow_d를 획득
df['fast_k'] = get_stochastic_fast_k(df['Close'], df['Low'], df['High'], 5)
df['slow_k'] = get_stochastic_slow_k(df['fast_k'], 3)
df['slow_d'] = get_stochastic_slow_d(df['slow_k'], 3)


df.plot(y=['Close'], figsize = (20, 5))

# Slow %K, Slow %D를 그려서 확인
df.plot(y=['slow_k', 'slow_d'], figsize = (20, 5))

 

각 코드마다 주석처리가 되어있기 때문에 어려움 없이 보실 수 있을 거예요

여기서 핵심 코드는 get_stochastic_fast_k를 획득하고 그 값으로 slow_k, slow_d를 획득하는 방법입니다.

위에 나와있는 공식이 어렵지 않다 보니 간단하게 구현이 가능하네요

 

반응형