[기술적 분석] 지표/전략 : CFO (Chande Forecast Oscillator)

반응형

 

  CFO(Chande Forecast Oscillator)는 앞서 CMO(Chande Momentum Oscillator)처럼 투샤르 샹드(Tushar Chande)에 의해 개발된 지표이다. CFO에서 F는 Forecast(예측)이며 이 지표에서는 선형 회귀(Linear Regression)를 의미한다. 선형 회귀를 사용하게 되면 관찰 기간 내에 가격 흐름을 가장 잘 설명하는, 관찰 기간 내의 가격들과의 오차가 가장 적은 단 하나의 직선을 그리게 되는데, 간단히 이야기하면 추세선이라고 이해하면 된다. 이 추세선에 따라 다음 가격이 찍힐 것이라고 예측(Forecast)하는 것을 의미하며 CFO는 이 추세선과 현재 가격의 차이를 표시한다. 

 

  CFO는 선형 회귀를 이용하기 때문에 장기간에 걸쳐 점진적으로 상승하거나 하락하는 종목의 경우, 즉, 매일 비슷한 폭의 상승, 혹은 하락을 보이는 경우에는 값이 매우 작게 나온다. 반면에 가격 변동이 큰 경우(어제는 상승, 오늘은 하락하는 등)에는 CFO 값의 변화가 크다. 매일 일정 수준씩 상승하는 종목과 주가 변화가 거의 없다가 직전일에 큰 상승을 보여 결국 기간 내 주가 상승은 비슷한 두 종목의 CFO는 큰 차이를 보이며, 하락하다가 직전일에 큰 상승을 내며 결국 비슷한 수익률을 기록한 종목의 경우 이 차이는 더 크다. 예를 들어, 20일간 매일 10%씩 상승한 종목이 있다고 가정해 보자. CFO는 통상 9일 혹은 14일을 설정하여 사용하는데, 이 경우, CFO의 값은 거의 0이 나온다. 반면에 19일간 가격변동이 아예 없다가 마지막 날에 30% 상승한 종목의 경우에는 마찬가지로 19일까지는 CFO 값이 0이다가 마지막에는 굉장히 큰 값을 보이게 된다. 또 다른 예시로, 매일 10%씩 19일간 상승하다가 마지막 날에 5%를 상승했을 경우, 19일까지는 CFO 값이 0이다가 마지막 날에는 굉장히 큰 음의 값을 보이게 된다. 이는 추세를 10%로 잡고 예측했으나, 마지막 5% 상승이 이 추세의 하단에 위치했기 때문이다.

 

  이런 CFO의 특징은 과매수, 과매도를 잡아내기보다는 단기간 내의 급등과 급락을 포착하기 용이하다는 뜻이며, CFO를 이용해 과매수, 과매도를 잡아 매매에 적용할 때는 상대 강도 지수(RSI, Relative Strangth Index)나 스토캐스틱 오실레이터(Stochastic Oscillator), 그리고 투샤르 샹드 본인이 만든 또 다른 지표인 CMO(Chande Momentum Oscillator)와 결합하여 사용하는 것을 추천한다.

 

반응형

CFO (Chande Forecast Oscillator) 보조 지표

 

  매매법은 상하단에 밴드를 설정하고 하단 밴드를 상향 돌파하는 경우 매수, 상단 밴드를 하향 돌파하는 경우 매도하는 전략이 가장 일반적이다. 단, 앞서 설명했다시피, 해당 지표는 단기간의 급등과 급락에 민감하며 값이 크다고 해서 과매수, 과매도라기보다 급등, 급락을 포착하는 지표이기 때문에 CFO를 독자적으로 적용 시, 이런 부분을 감안해야 한다. 다만, 통상 주식은 상승과 하락 중간이 가장 가파르며 끝물에는 그 기울기가 완만해지는 경향을 보이는데, 그런 지점에 CFO는 반응을 하기 때문에 이런 포인트에서 인사이트를 얻어 적용한다 하면 굉장히 주효할 수 있다.

 

  마지막으로 CFO(Chande Forecast Oscillator)의 트레이딩 뷰 파인 스크립트 소스와 pandas-ta 소스를 공유하며 마친다.

 

 

  • CFO(Chande Forecast Oscillator) 트레이딩 뷰 파인 스크립트 지표 소스
//@version=5
indicator(title="Chande Forecast Oscillator", shorttitle="CFO", format=format.price, precision=4, timeframe="", timeframe_gaps=true)

sourceInput = input(defval=close, title="Source")
lengthInput = input.int(defval=14, title="CFO Length")
upperInput = input.float(3.0, title="Upper", group="Band Settings")
lowerInput = input.float(-3.0, title="Lower", group="Band Settings")

cfo = (sourceInput - ta.linreg(sourceInput, lengthInput, 0)) * 100 / sourceInput

cfoPlot = plot(cfo, title="CFO", color=color.yellow)
hline(0, "Middle Line", linestyle=hline.style_dotted, color=color.gray)
midLinePlot = plot(0, color = na, editable = false, display = display.none)
upperBand = hline(upperInput, "Upper Band", color=color.gray)
lowerBand = hline(lowerInput, "Lower Band", color=color.gray)
fill(upperBand, lowerBand, title="Background", color=color.new(color.gray, 90))
fill(cfoPlot, midLinePlot, 3, 0, top_color = color.green, bottom_color = color.new(color.green, 100), title = "Overbought Gradient Fill")
fill(cfoPlot, midLinePlot, 0, -3, top_color = color.new(color.red, 100), bottom_color = color.red, title = "Oversold Gradient Fill")

 

 

  • CFO(Chande Forecast Oscillator) 트레이딩 뷰 파인 스크립트 전략 소스
//@version=5
strategy(title="Chande Forecast Oscillator", shorttitle="CFO", 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)

sourceInput = input(defval=close, title="Source")
lengthInput = input.int(defval=14, title="CFO Length")
upperInput = input.float(3.0, title="Upper", group="Band Settings")
lowerInput = input.float(-3.0, title="Lower", group="Band Settings")

cfo = (sourceInput - ta.linreg(sourceInput, lengthInput, 0)) * 100 / sourceInput

cfoPlot = plot(cfo, title="CFO", color=color.yellow)
hline(0, "Middle Line", linestyle=hline.style_dotted, color=color.gray)
midLinePlot = plot(0, color = na, editable = false, display = display.none)
upperBand = hline(upperInput, "Upper Band", color=color.gray)
lowerBand = hline(lowerInput, "Lower Band", color=color.gray)
fill(upperBand, lowerBand, title="Background", color=color.new(color.gray, 90))
fill(cfoPlot, midLinePlot, 3, 0, top_color = color.green, bottom_color = color.new(color.green, 100), title = "Overbought Gradient Fill")
fill(cfoPlot, midLinePlot, 0, -3, top_color = color.new(color.red, 100), bottom_color = color.red, title = "Oversold Gradient Fill")

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 ta.crossover(cfo, lowerInput)
        strategy.entry("매수", strategy.long, oca_type=strategy.oca.cancel, comment="매수")
    if ta.crossunder(cfo, upperInput)
        strategy.close_all('매도')
	
bgcolor(strategy.position_size > 0 ? color.new(color.yellow,90) : na)

 

 

  • CFO(Chande Forecast Oscillator) pandas-ta 소스
import pandas as pd
import pandas_ta as ta
import FinanceDataReader as fdr

data = fdr.DataReader('005930')
cfo = ta.cfo(close=data['Close'], length=9)
data = pd.concat([data, cfo], axis=1)
data.dropna(inplace=True)
반응형