주식차트는 캔들이라는 녀석의 시계열로 이루어져 있습니다.
그날의 시작가격(시가), 최고가격(고가), 최저가격(저가), 종료가격(종가) 를 그림으로 표현한 것인데요, 시가와 종가를 비교하여 양봉(종가> 시가) 또는 음봉(시가> 종가)으로 분류하고, 양봉은 빨간색, 음봉은 파란색으로 표현하여 구분하게 되죠.
하루의 주가 움직임을 나타내는 네 개의 수 시가, 고가, 저가, 종가를 줄여서
시고저종
이라 하고 영어로는 시가(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를 상향 돌파하여 위에 머무는 구간을 하이라이트 처리하여 시각적으로 한눈에 볼 수도 있습니다. 그런데, 시그널이 맞아 보이시나요?
'주식분석 > Quant 분석(프로그래밍)' 카테고리의 다른 글
모여라 이평선! (0) | 2023.03.12 |
---|---|
반응형 그래프와 티스토리에 붙이기 (0) | 2023.03.09 |
지지선과 저항선 (0) | 2023.03.05 |
주식 데이터 불러오기 : FinanceDataReader 라이브러리 (0) | 2023.03.02 |
주식 차트 그리기 #2: candlestick_ohlc 시고저종 봉차트 (0) | 2022.07.16 |
댓글