본문 바로가기
Quant Stock

파이썬 - 스토캐스틱(Stochastic Oscillator)이해와 차트 만들기

by quantWhale 2023. 3. 20.
반응형

안녕하세요. 지식을 공유하는 투자자 인천고래입니다.

 

오늘은 파이썬을 이용해서 스토캐스틱(Stochastic Oscillator) 보조지표 차트 만들기에 대한 주제로 스토캐스틱을 만드는 파이썬 코드를 알아보도록 하겠습니다.

스토캐스틱은 내부 구조가 복잡하므로 우선 스토캐스틱이 사용하는 변수에 대한 이해와 생성되는 원리를 설명을 먼저 드리도록 하겠습니다.

 

1. 스토캐스틱에 대한 이해

스토캐스틱은 주가의 상대적인 위치를 통해 과매수/과매도 상황을 판단하는 데 사용되는 보조지표로서

%K, %D, %J 세 가지 값으로 구성되며 각각의 의미는 다음과 같습니다.

  1. %K (스토캐스틱 %K): 주가의 상대적 위치를 나타내는 값으로, 주어진 기간 동안의 최고가와 최저가를 기준으로 현재 종가가 어디에 위치하는지를 백분율로 나타낸 것입니다.
    %K 값이 80 이상이면 과매수 상황, 20 이하면 과매도 상황으로 판단할 수 있습니다.

  2. %D (스토캐스틱 %D): %K의 m일 이동평균값으로, %K를 부드럽게 만든 선으로 생각할 수 있습니다. %D 값은 %K 값의 추세를 파악하는 데 도움이 되며, %K와 %D가 교차하는 지점에서 매수/매도 신호가 발생할 수 있습니다.
    %K가 %D를 상향 돌파하면 매수 신호, %K가 %D를 하향 돌파하면 매도 신호로 볼 수 있습니다.

  3. %J (스토캐스틱 %J): %D의 t일 이동평균값으로, %D를 더 부드럽게 만든 선으로 볼 수 있습니다. %J 값은 %D 값의 추세를 좀 더 장기적으로 분석하는 데 도움이 되며, %J 값을 이용해 %K와 %D의 교차 지점에 대한 확증을 얻을 수 있습니다. %J 값이 더욱 확실한 매수/매도 신호를 제공할 수 있습니다.

계산법에 대해서는 맨 아래 코드에 추가로 설명을 해 놓았습니다. 참고 바랍니다.

 

 

2. 코드 실행 결과 화면

아래와 같은 스토캐스틱 결과물을 만들기 위해서는 다음의 항목을 사용해야 합니다.

  • 데이터 : FinanceDataReader를 사용해서 데이터 가져옵니다. (DB를 사용하고 있다면 해당 DB로 가져오시거나 엑셀 파일로 되어 있다면 엑셀로 가져오는 함수를 사용하셔도 됩니다.
  • 차트 생성 : Matplotlib 라이브러리를 사용하여 주가 데이터와 하단에 스토캐스틱 보조지표 차트를 구현하였습니다.
  • 매개 변수 : 하단에 입력 필드와 버튼을 만듦으로 매개변숫값을 받아서 스토캐스틱 차트가 변동될 수 있도록 하였습니다.

삼성전자 주가차트 + 스토캐스틱 보조지표

 

핀치 줌 아웃을 하면 차트나 글자를 확대해서 보실 수 있습니다.

스토캐스틱도 종목마다 적용되는 수치를 다르게 적용해야 정확도가 높아지기 때문에

기존에 사용하던 HTS와 같이 손쉽게 수치를 바꾸면서 원하는 값을 찾을 수 있도록 사용자가 매개변수 값을 입력할 수 있게 해 두었습니다. 원하시는 기간을 입력하신 후 버튼을 클릭하면 하단의 스토캐스틱 차트에 값이 반영이 되도록 되어 있습니다.

 

 

3. 파이썬으로 차트에 스토캐스틱 지표 추가하기

아래의 코드를 실행하면, 주가 데이터 차트와 스토캐스틱 차트가 각각 생성됩니다.

코드는 이전에 작성한 RSI와 큰 틀에서 큰 차이가 없으며

2개의 차트를 만들어야 하기 때문에 subplots을 2,1로 설정하여 위, 아래에 2개의 차트가 보이도록 하였습니다.

또한 확대할 때 2개의 차트가 같이 확대가 되도록 sharex=True로 설정해 놨습니다.

# 2023년 3월 20일 인천고래 (상업적 이용을 금지합니다.)
# ============================================================
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.widgets import TextBox, Button
import FinanceDataReader as fdr
import matplotlib.font_manager as fm

# 사용 가능한 한글 폰트 목록을 확인합니다.
for font in fm.fontManager.ttflist:
    if 'Nanum' in font.name:
        print(font.name)

# 사용할 한글 폰트를 설정합니다.
plt.rcParams['font.family'] = 'Malgun Gothic'

def compute_stochastic_oscillator(data, n=14, m=3, t=3):
    low_min = data['Low'].rolling(window=n).min()
    high_max = data['High'].rolling(window=n).max()
    K = (data['Close'] - low_min) / (high_max - low_min) * 100
    D = K.rolling(window=m).mean()
    J = D.rolling(window=t).mean()
    return K, D, J

def onclick(event):
    input_n = int(text_box_n.text)
    input_m = int(text_box_m.text)
    input_t = int(text_box_t.text)
    K, D, J = compute_stochastic_oscillator(df, input_n, input_m, input_t)

    ax2.clear()
    ax2.plot(df.index, K, label='%K')
    ax2.plot(df.index, D, label='%D')
    ax2.plot(df.index, J, label='%J')
    ax2.legend()
    plt.draw()


stock_code = '005930'
df = fdr.DataReader(stock_code)

fig, (ax1, ax2) = plt.subplots(2, 1, gridspec_kw={'height_ratios': [3, 1]}, sharex=True)
ax1.plot(df.index, df['Close'])

K, D, J = compute_stochastic_oscillator(df)
ax2.plot(df.index, K, label='K')
ax2.plot(df.index, D, label='D')
ax2.plot(df.index, J, label='J')
ax2.legend()

plt.subplots_adjust(bottom=0.2)
axbox_n = plt.axes([0.1, 0.05, 0.1, 0.075])
axbox_m = plt.axes([0.3, 0.05, 0.1, 0.075])
axbox_t = plt.axes([0.5, 0.05, 0.1, 0.075])
axbox_button = plt.axes([0.7, 0.05, 0.1, 0.075])

text_box_n = TextBox(axbox_n, 'n (기간)', initial='14')
text_box_m = TextBox(axbox_m, 'm (%D)', initial='3')
text_box_t = TextBox(axbox_t, 't (%J)', initial='3')
button = Button(axbox_button, 'Apply')
button.on_clicked(onclick)

plt.show()

그리고 버튼을 클릭하면 onclick 함수를 호출하여 차트를 다시 생성하도록 코드를 작성하였습니다.

차트가 확대된 상태에서 매개변수 값을 변경하더라도 차트에 반영이 잘 되도록 되어 있습니다.

혹시라도 코드에 오류가 있다면 알려주세요. 반영하여 다시 올려드리도록 하겠습니다. ^^

 

 

4. 스토캐스틱 생성 코드에 대한 설명

스토캐스틱 함수는 주어진 주가 데이터와 사용할 기간(일수)을 인자로 받아 값을 계산하고 반환합니다.

함수의 구성은 아래와 같습니다.

def compute_stochastic_oscillator(data, n=14, m=3, t=3):
    low_min = data['Low'].rolling(window=n).min()
    high_max = data['High'].rolling(window=n).max()
    K = (data['Close'] - low_min) / (high_max - low_min) * 100
    D = K.rolling(window=m).mean()
    J = D.rolling(window=t).mean()
    return K, D, J

위의 함수를 기능별로 구분을 하자면 다음과 같은 과정을 거쳐 스토캐스틱을 계산합니다.

  • 최저가 계산: min()를 사용하여 주어진 기간(n일)의 최저가를 구합니다.
  • 최고가 계산: max()를 사용하여 주어진 기간(n일)의 최고가를 구합니다.
  • 스토캐스틱 %K 계산: (data['Close'] - low_min) / (high_max - low_min) * 100를 사용하여 스토캐스틱 %K를 계산합니다.
  • 스토캐스틱 %D 계산: K.rolling(window=m).mean()를 사용하여 스토캐스틱 %D를 계산합니다.
  • 스토캐스틱 %J 계산: D.rolling(window=t).mean()를 사용하여 스토캐스틱 %J를 계산합니다.

 

 

5. 마무리

오늘은 FinanceDataReader로 데이터를 불러오고 Matplotlib라이브러리를 이용해서 주가 차트를 만들고 스토캐스틱 보조지표를 추가해 보는 코드를 작성해 봤습니다.

 

스토캐스틱이 RSI 생성하는 코드보다 살짝 어려워 보일 수는 있으나

근본적으로는 최고값과  최저값을 찾은 뒤 %K값을 도출한 뒤 2번에 거쳐서 이동평균선화 시키는 작업입니다.

특별히 어려울만한 코드는 없어 보입니다.

 

파이썬 코드로 작성한 이유는 매매를 함에 있어서 확률을 높이기 위함이고

확률을 높이기 위해서는 우선 분석하고자 하는 매매기법의 기반이 되는 보조지표 또는 그 대상이 되는 지표를 코드로 만들어놔야 합니다. 관심 있으신 분들의 많은 활용 바라겠습니다.

 

오늘도 제 글을 읽어주신 모든 분들께 감사의 말씀을 드립니다. 감사합니다.

반응형
-

댓글