유명한 보조지표 중 하나인 스토캐스틱 오실레이터(Stochastic Oscillator)는 이를 활용한 스토캐스틱 슬로우(Stochastic Slow)와 구별하기 위해 스토캐스틱 패스트(Stochastic Fast)라는 이름으로 더 자주 불린다. 스토캐스틱은 윌리엄 더니건(William Dunnigun)에 의해 개발되었으며 조지 레인(George Lane)이 이를 널리 확산시켰다. 가장 비슷한 지표는 앞서 소개했던 윌리엄의 %R(William's % Range)인데, 둘 다 관찰 기간 내 최저가와 최고가 사이에서 현재 가격을 표시하는 점은 같으나 스토캐스틱의 경우에는 최저가 대비 현재가, 윌리엄의 %R은 최고가 대비 현재가를 표시한다. 또한, 윌리엄의 %R은 그 자체로 사용되나 스토캐스틱의 경우에는 이동 평균을 한번 씌워 오실레이터로 사용되는 게 큰 차이점. 산식에 의해 계산된 기간 내 현재 가격의 위치를 %K, 그리고 이를 이동평균한 것을 %D라고 하여 이 두 가지를 이용하여 오실레이터를 만들고 거래 신호를 포착한다.
%K를 산출하기 위한 관찰 기간은 보통 14일이 사용되며 변경한다 하더라도 5~30 내에서 사용하는 게 적절하다고 알려져 있으며, %K를 이동 평균한 %D의 경우에는 보통 단순 이동 평균을 사용하며 이동 평균 기간을 통상 3일을 사용한다. 이 역시 3~10 내에서 변경하는 게 적절하다고 한다.
워낙 유명한 지표이고 다방면으로 연구가 되어 다양한 매매 전략이 존재하는데, 우선 윌리엄의 %R 처럼 이동평균을 이용하지 않고 %K만 이용하여 과매도, 과매수를 측정하여 매매하는 방법이 있다. %K가 20을 상향 돌파하면 매수, 80을 하향 돌파하면 매도하는 전략을 취할 수 있다.
오실레이터이다 보니 %K가 %D를 상향 돌파하면 매수, %K가 %D를 하향 돌파하면 매도하는 전략을 취하기도 한다. 단, %K가 민감하게 움직이다 보니 허위 시그널이 자주 발생하는 문제가 생길 수 있으며 이런 문제를 해소하기 위해 스토캐스틱 슬로우라는 지표가 만들어져서 더 널리 사용되고 있다. 이건 다음에 소개하도록 하겠다.
선물과 같은 파생상품 거래에서는 앞서 과매수, 과매도 전략과 반대로 %K가 80을 상향 돌파하면 매수 포지션을 잡고, %K가 %D를 하향 돌파할 경우 매수 포지션을 청산, 반대로 %K가 20을 하향 돌파하면 매도 포지션을 잡고 %K가 %D를 상향 돌파할 경우 매도 포지션을 청산하는 전략을 사용하기도 한다. 이는 소위 말하는 추세와 모멘텀에 기반한 투자 전략으로 스토캐스틱 팝(POP) 전략이라고도 한다.
이 외에 전략으로 만들어 적용하기는 어렵지만 다이버전스(Divergence)라고 해서 가격은 상승하나 스토캐스틱은 상승하지 못하고 하락하는 경우, 가격은 하락하나 스토캐스틱은 완만하게 상승하는 경우, 추세전환의 신호로 인식하기도 한다. 보통 다이버전스 전에 스토캐스틱의 기울기가 가파르게 움직이다가 둔화되는데 이것을 힌지(Hinge)라고 하며 추세 전환의 선행 신호로 본다. 이 외에 스토캐스틱 %K, %D 모두 최상단이나 최하단을 빠르게 찍고 돌아오는 경우, 최하단을 찍고 돌아올 때는 무릎(Knee), 최상단을 찍고 돌아올 때는 어깨(Shoulder)라고 하며 이 무릎과 어깨(Knee & Shoulder)가 발생하면 추세전환이 되었다고 보기도 한다.
워낙 유명하고 다방면으로 연구가 돼서 다양한 베리에이션이 존재하며, 지표가 뛰어나 독자적으로도 많이 쓰이고 적당한 움직임을 보이는 장세나 종목에 특히 주효하다. 단, 추세가 강력할 경우, 스토캐스틱 패스트의 경우 민감하게 반응하기 때문에 스토캐스틱 슬로우를 많이 쓰거나 다른 지표와 결합하여 사용되며 특히 RSI와 궁합이 좋은 것으로 유명하다. 근대 대충 기본적인 스토캐스틱만 적용해도 수익률이 다른 지표에 비해 월등하게 잘 나오는 지표 중 하나.
마지막으로 트레이딩 뷰 파인 스크립트 소스와 pandas-ta 소스를 공유하며 마친다.
- 스토캐스틱 패스트(Stochastic Fast) 트레이딩 뷰 파인 스크립트 지표 소스
//@version=5
indicator(title="Stochastic Fast", shorttitle="StochF", format=format.price, precision=2, timeframe="", timeframe_gaps=true)
import TradingView/ta/7 as ta7
import blackcat1402/pandas_ta/7 as pta
ma(source, length, _type) =>
switch _type
"SMA" => ta.sma(source, length)
"EMA" => ta.ema(source, length)
"DEMA" => ta7.dema(source,length)
"TEMA" => ta7.tema(source,length)
"FRAMA" => ta7.frama(source,length)
"T3" => ta7.t3(source,length)
"TRIMA" => ta7.trima(source,length)
"RMA" => ta.rma(source, length)
"WMA" => ta.wma(source, length)
"HMA" => ta.hma(source, length)
"VWMA" => ta.vwma(source * volume, length)
"ALMA" => pta.alma(source, length)
"JMA" => pta.jma(source, length)
"SINWMA" => pta.sinwma(source, length)
"FWMA" => pta.fwma(source, length)
"LINREG" => pta.linreg(source, length)
"SWMA" => pta.swma(source)
"YIDYA" => pta.vidya(source, length)
"VWAP" => pta.vwap(source)
"ZLMA" => pta.zlma(source, length)
periodK = input.int(14, title="%K Length", minval=1)
periodD = input.int(3, title="%D Smoothing", minval=1)
maTypeInput = input.string("SMA", title="MA Type", options = ["SMA", "EMA", "DEMA", "TEMA", "FRAMA", "T3", "TRIMA", "RMA", "WMA", "HMA", "VWMA", "ALMA", "JMA", "SINWMA", "FWMA", "LINREG", "SWMA", "VIDYA", "VWAP", "ZLMA"], group="MA Settings", display = display.data_window)
lower = input.int(80, title="Lower", group="Band Settings")
upper = input.int(20, title="Upper", group="Band Settings")
k = ta.stoch(close, high, low, periodK)
d = ma(k, periodD, maTypeInput)
plot(k, title="%K", color=color.blue)
plot(d, title="%D", color=color.red)
upperBand = hline(upper, "Upper Band", color=color.gray)
hline(50, "Middle Band", linestyle=hline.style_dotted, color=color.gray)
lowerBand = hline(lower, "Lower Band", color=color.gray)
fill(upperBand, lowerBand, title="Background", color=color.new(color.gray, 80))
- 스토캐스틱 패스트(Stochastic Fast) 트레이딩 뷰 파인 스크립트 전략 소스
//@version=5
strategy(title="Stochastic Fast", shorttitle="StochF", margin_long=100, margin_short=100, default_qty_type=strategy.percent_of_equity, default_qty_value=50, commission_type=strategy.commission.percent, commission_value=0.2, pyramiding=0)
import TradingView/ta/7 as ta7
import blackcat1402/pandas_ta/7 as pta
ma(source, length, _type) =>
switch _type
"SMA" => ta.sma(source, length)
"EMA" => ta.ema(source, length)
"DEMA" => ta7.dema(source,length)
"TEMA" => ta7.tema(source,length)
"FRAMA" => ta7.frama(source,length)
"T3" => ta7.t3(source,length)
"TRIMA" => ta7.trima(source,length)
"RMA" => ta.rma(source, length)
"WMA" => ta.wma(source, length)
"HMA" => ta.hma(source, length)
"VWMA" => ta.vwma(source * volume, length)
"ALMA" => pta.alma(source, length)
"JMA" => pta.jma(source, length)
"SINWMA" => pta.sinwma(source, length)
"FWMA" => pta.fwma(source, length)
"LINREG" => pta.linreg(source, length)
"SWMA" => pta.swma(source)
"YIDYA" => pta.vidya(source, length)
"VWAP" => pta.vwap(source)
"ZLMA" => pta.zlma(source, length)
periodK = input.int(14, title="%K Length", minval=1)
periodD = input.int(3, title="%D Smoothing", minval=1)
maTypeInput = input.string("SMA", title="MA Type", options = ["SMA", "EMA", "DEMA", "TEMA", "FRAMA", "T3", "TRIMA", "RMA", "WMA", "HMA", "VWMA", "ALMA", "JMA", "SINWMA", "FWMA", "LINREG", "SWMA", "VIDYA", "VWAP", "ZLMA"], group="MA Settings", display = display.data_window)
lower = input.int(80, title="Lower", group="Band Settings")
upper = input.int(20, title="Upper", group="Band Settings")
indi = input.string("%K-Band", title="Strategy Indicator", options = ["%K-Band", "%D-Band", "%K-%D"])
k = ta.stoch(close, high, low, periodK)
d = ma(k, periodD, maTypeInput)
plot(k, title="%K", color=color.blue)
plot(d, title="%D", color=color.red)
upperBand = hline(upper, "Upper Band", color=color.gray)
hline(50, "Middle Band", linestyle=hline.style_dotted, color=color.gray)
lowerBand = hline(lower, "Lower Band", color=color.gray)
fill(upperBand, lowerBand, title="Background", color=color.new(color.gray, 80))
startDate = input.time(defval=timestamp("01 Jan 1970 00:00 +0000"), group = "Test Range")
finishDate = input.time(defval=timestamp("31 Dec 2025 24:00 +0000"), group = "Test Range")
time_condition = time >= startDate and time <= finishDate
if(time_condition)
if (indi == "%K-Band")
if ta.crossover(k, lower)
strategy.entry("매수", strategy.long, oca_type=strategy.oca.cancel, comment="매수")
if ta.crossunder(k, upper)
strategy.close_all('매도')
if (indi == "%D-Band")
if ta.crossover(d, lower)
strategy.entry("매수", strategy.long, oca_type=strategy.oca.cancel, comment="매수")
if ta.crossunder(d, upper)
strategy.close_all('매도')
if (indi == "%K-%D")
if ta.crossover(k, d)
strategy.entry("매수", strategy.long, oca_type=strategy.oca.cancel, comment="매수")
if ta.crossunder(k, d)
strategy.close_all('매도')
bgcolor(strategy.position_size > 0 ? color.new(color.yellow,90) : na)
- 스토캐스틱 패스트(Stochastic Fast) pandas-ta 소스
import pandas as pd
import pandas_ta as ta
import FinanceDataReader as fdr
data = fdr.DataReader('005930')
stochf = ta.stochf(high=data['High'], low=data['Low'], close=data['Close'], k=14, d=3, mamode='SMA')
data = pd.concat([data, stochf], axis=1)
data.dropna(inplace=True)