본문 바로가기
주식분석/Quant 분석(프로그래밍)

기술적 지표 #1. AB Ratio

by hustler78 2023. 3. 8.
728x90
반응형

 

 

 

 

주식차트는 캔들이라는 녀석의 시계열로 이루어져 있습니다.

 

캔들의 모습

 

그날의 시작가격(시가), 최고가격(고가), 최저가격(저가), 종료가격(종가) 를 그림으로 표현한 것인데요, 시가와 종가를 비교하여 양봉(종가> 시가) 또는 음봉(시가> 종가)으로 분류하고, 양봉은 빨간색, 음봉은 파란색으로 표현하여 구분하게 되죠. 

 

떡상을 기대하는 미국과, 곱버스에 베팅한 중국?

 

하루의 주가 움직임을 나타내는 네 개의 수 시가, 고가, 저가, 종가를 줄여서 

 

 

시고저종

이라 하고 영어로는 시가(Open), 고가(High), 저가(Low), 종가(Close)의 첫 문자를 따서

 

OHLC

 

라고도 합니다. python에서 제공하는 candlestick_ohlc 함수 이름에도 등장하는 단어입니다.

 

이제 AB Ratio로는 기술적 지표의 정의를 살펴보죠.

 

 

 

AB Ratio의 정의

 

주가의 시고저종을 각각 기호로 $ O, H, L, C$라 합시다. 그리고 $i$일 전의 시고저종을 $O_i, H_i, L_i, C_i$라고 합시다. 오늘 당일의 시고저종은 $i=0$인 상황이 되겠습니다.

 

A Ratio

A Ratio를 구할 때는 여러 개의 시계열 데이터가 필요합니다. 필요한 데이터의 개수를 period라고 하는데요, period의 개수를 $N$개라 할 때, A Ratio는 다음과 같이 정의합니다.

 

$$ {\rm{A  ~Ratio}} = \sum_{i=0}^{N-1} \frac{H_i-O_i}{O_i-L_i}$$

 

이를 알기 쉽게 수식으로 써보면 아래와 같이도 쓸 수 있습니다.

 

A Ratio = 100 × Sum( H-O , N) / Sum( O-L, N)

 

 

B Ratio

B Ratio를 구할 때 역시 $N$개의 주가 시계열 데이터가 필요합니다. 아래와 같이 정의합니다.

 

$$ {\rm{B  ~Ratio}} = \sum_{i=0}^{N-1} \frac{H_i-C_{i+1}}{C_{i+1}-L_i}$$

 

A Ratio와 거의 비슷한데, A Ratio의 시가($O_i$)가 들어갈 자리에 전일 종가($C_{i+1}$)를 넣는 것이 특징입니다.

 

B Ratio = 100 × Sum( H-C(1) , N) / Sum( C(1)-L, N)

여기서 C(1)은 전일종가

 

 

분석

A Ratio, B Ratio 공히 분자에 위치한 양을 강에너지, 분모에 위치한 양을 약에너지라 합니다. AB Ratio는 그래서 약에너지 대비 강에너지의 비율을 따지는 것입니다.

 

또한 A Ratio, B Ratio 모두 정의된 수식을 보면, 함수

$$ f(x) = \frac{h-x}{x-l}$$

의 형태의 합임을 알 수 있는데요. A Ratio는 $f(O_i)$들이 근간을 이루고, B Ratio는 $f(C_{i+1})$이 베이스가 됩니다. 그런데 함수 $f(x)$는

$$ f(x) = \frac{h-l}{x-l}-1$$ 형태이므로 $x$에 대한 감소함수이죠. 따라서

$f(O_i) >f(C_{i+1})$의 뜻은 $O_i < C_{i+1}$이고 $f(O_i)<f(C_{i+1})$는 $O_i>C_{i+1}$이 됩니다. 결과적으로

 

B Ratio가 A Ratio를 상향 돌파한다는 뜻은?
시가가 어제의 종가보다 크게 출발한다.  강에너지가 확장될 수 있다. 즉, 주가 상승의 시그널이다.
B Ratio가 A Ratio를 하향 돌파한다는 뜻은?
시가가 어제의 종가보다 작게 출발한다.  약에너지가 확장될 수 있다. 즉, 주가 하락의 시그널이다.

 

이라고 분석을 할 수 있습니다. 그럼 python으로 AB Ratio를 알아보도록 합시다.

 

 

 

Python Code : AB Ratio

import pandas as pd
import numpy as np
import yfinance
from mpl_finance import candlestick_ohlc
import mplfinance
import matplotlib.dates as mpl_dates
import matplotlib.pyplot as plt
import datetime
from dateutil.relativedelta import relativedelta
import FinanceDataReader as fdr
from matplotlib import gridspec

def ABratio():

    end_date = datetime.datetime.today()
    start_date = end_date - relativedelta(years=1)

    stk_code = '005930'
    # stk_code = '065770'
    # stk_code = '008350'  # 남선알미늄
    df = load_data(stk_code, start_date, end_date)  # stock data load
    df.index = df.index.map(mpl_dates.date2num)     # dataframe index의 date형식을 숫자형식으로 변환
    df['Date'] = df.index                           # Date라는 이름의 column 생성/추가
    df = df.loc[:, ['Date', 'Open', 'High', 'Low', 'Close']]
    
    # A/B Ratio formula
    df['A_ratio'] = 100 * (df.High - df.Open).rolling(window=20).sum() / (df.Open - df.Low).rolling(window=20).sum()
    df['B_ratio'] = 100 * (df.High - df.Close.shift(1)).rolling(window=20).sum() / (df.Close.shift(1) - df.Low).rolling(
        window=20).sum()
        
    # B Ratio가 A Ratio를 상향돌파하여 위에 머무르는 signal 포착을 위한 플래그
    df['Signal'] = df.A_ratio < df.B_ratio

 
    signal_list = []    # 주식 상승 시그널 분석을 위한 list
    prevVal = False
    
    # B ratio가 A ratio를 상향돌파하여 위에머무는 즉,
    # Signal 이 False에서 True로 바뀌는 시점을 start라는 변수에 기입
    # 계속 True로 유지하다가 다시 False로 바뀌는 시점을 inxㄹ는 변수에 기입하여
    # tuple (start, inx)를 signal list에 넣음
    for inx, val in df['Signal'].iteritems():  # Signal column의 index와 각 열의 value를 돌리며
        if prevVal != val:
            if val:
                start = inx
            else:
                signal_list.append((start, inx))
        
        # 데이터 끝부분이 True이면 그 앞의 True발생일부터 끝까지를 signal list에 따로 처리하여 넣어줌 
        elif (val == True) and (inx == df.index[-1]): 
            signal_list.append((start, inx))

        prevVal = val


    fig = plt.figure()
    gs = gridspec.GridSpec(nrows=2, ncols=1, height_ratios=[5, 2]) # two subplot의 그림크기 조정 그리드
    ax = fig.add_subplot(gs[0])
    ax1 = fig.add_subplot(gs[1], sharex=ax)   # 첫번째 그림과 x축 공유 (sharex)

    df_ohlc = df[['Date', 'Open', 'High', 'Low', 'Close']]
    candlestick_ohlc(ax, df_ohlc.values, width=0.6, \
                     colorup='red', colordown='blue', alpha=0.8)  # candle chart
    date_format = mpl_dates.DateFormatter('%y/%b/%d')
    ax.xaxis.set_major_formatter(date_format)
    ax1.plot(df.Date, df.A_ratio, color='silver', linewidth=3, label='A ratio')  # Aratio Chart
    ax1.plot(df.Date, df.B_ratio, color='dimgray', linewidth=3, label='B ratio') # Bratio Chart
    ax1.xaxis.set_major_formatter(date_format)
    for (start, end) in signal_list:      #axvspan 기능으로 signal포착 구간을 수직범위표시
        ax1.axvspan(start, end, facecolor='lightsteelblue', alpha=0.5)
    plt.legend()
    plt.show()

if __name__ == '__main__':
    ABratio()

 

 

위는 삼성전자(005930)의 예시입니다. 결과를 보시죠.

 

 

 

제 애증의 종목 CS(065770)입니다.

 

 

이처럼, B Ratio 가 A Ratio를 상향 돌파하여 위에 머무는 구간을 하이라이트 처리하여 시각적으로 한눈에 볼 수도 있습니다. 그런데, 시그널이 맞아 보이시나요?

 

728x90
반응형

댓글