기본 콘텐츠로 건너뛰기

[matplotlib]quiver()함수

[stock]볼린져밴드(Bolinger Band, BB), Band%B,bandwidth

볼린져밴드(Bolinger Band, BB)와 Band%B

볼린져밴드(Bolinger Band, BB)

볼린저 밴드(BB, Bollinger Bands)는 시장 변동성을 평가하고 잠재적인 과매수와 과매도 조건을 파악하는 데 사용됩니다.

볼린저 밴드는 가격 차트에 표시되는 세 개의 선으로 구성되며, 이는 단순 이동 평균(SMA)과 SMA 위아래로 두 배의 표준 편차를 포함합니다. 밴드는 시장 변동성에 따라 확장되고 수축되어 트레이더에게 잠재적 가격 움직임에 대한 통찰력을 제공합니다.

구성 요소: 볼린저 밴드는 일반적으로 세 개의 선으로 구성됩니다.

  • 중심선 (Middle Band): 일반적으로 20일 단순이동평균선(SMA)을 사용합니다. 이는 주가의 중기 추세를 나타냅니다.
  • 상한선 (Upper Band): 중심선에서 위로 2 표준편차 떨어진 선입니다.
  • 하한선 (Lower Band): 중심선에서 아래로 2 표준편차 떨어진 선입니다.

계산 방법:

  • 중심선 (20일 SMA) 계산: 지난 20일 동안의 종가를 모두 더한 후 20으로 나눕니다.
  • 표준편차 계산: 지난 20일 동안의 종가의 표준편차를 계산합니다. 표준편차는 가격 변동성의 정도를 나타냅니다.
  • 상한선 계산: 중심선 + (표준편차 x 2)
  • 하한선 계산: 중심선 - (표준편차 x 2)

볼린저 벤드는 주가가 통계저긍로 상한선과 하한선 사이에서 움직일 가능성이 높다는 전제를 기반으로 합니다. 약 95%의 주가 움직임이 이 밴드내에서 발생한다고 알려 있습니다.

  • 과매수 및 과매도 판단:
    • 주가가 상한선에 근접하거나 상향 돌파 → 과매수 상태로 간주되어 매도 시점으로 볼 수 있습니다.
    • 주가가 하한선에 근접하거나 하향 돌파 → 과매도 상태로 간주되어 매수 시점으로 볼 수 있습니다.
    • 하지만 강한 추세가 형성될 때는 주가가 밴드 밖에서 지속될 수도 있으므로 다른 지표와 함께 확인하는 것이 좋습니다.
  • 변동성 파악:
  • 밴드의 폭이 넓어질 때: 주가의 변동성이 커지고 있음을 의미하며, 추세 전환이나 급격한 가격 움직임이 발생할 수 있습니다.
  • 밴드의 폭이 좁아질 때 (스퀴즈): 주가의 변동성이 낮아지고 있으며, 이후 큰 가격 움직임이 발생할 가능성이 있습니다. 밴드 폭이 좁아진 후 주가가 상한선이나 하한선을 돌파하는 방향으로 추세가 형성될 가능성이 높다고 해석합니다.
  • 추세 확인:
    • 주가가 중심선 위에서 지속적으로 움직이면 상승 추세, 중심선 아래에서 지속적으로 움직이면 하락 추세로 볼 수 있습니다.
    • 상승 추세에서는 주가가 주로 상한선 근처에서 움직이는 경향이 있으며, 하락 추세에서는 주로 하한선 근처에서 움직이는 경향이 있습니다.
  • 지지 및 저항: 볼린저 밴드의 중심선, 상한선, 하한선은 지지선 또는 저항선 역할을 할 수 있습니다.
  • 차트 패턴 분석: 볼린저 밴드는 W-바닥, M-천장과 같은 차트 패턴을 식별하는 데 도움을 줄 수 있습니다.

매매 전략

  • 평균 회귀 전략: 횡보장에서 주가가 하한선에 닿으면 매수, 상한선에 닿으면 매도하는 전략입니다.
  • 추세 추종 전략: 강한 추세가 발생했을 때 주가가 밴드를 돌파하는 방향으로 매매하는 전략입니다. 상한선 돌파 시 매수, 하한선 돌파 시 매도합니다.
  • 스퀴즈 전략: 밴드 폭이 좁아진 후 주가가 밴드를 벗어나는 방향으로 매매하는 전략입니다.

주의사항:

  • 볼린저 밴드는 단독으로 사용하기보다는 다른 기술적 지표(MACD, RSI 등)와 함께 사용하여 분석의 신뢰도를 높이는 것이 좋습니다.
  • 시장 상황과 분석 대상에 따라 볼린저 밴드의 기간 및 표준편차 설정을 조정해야 할 수 있습니다.
  • 과거의 패턴이 미래에도 반복된다는 보장은 없으므로 맹신해서는 안 됩니다.
  • 볼린저 밴드는 유용한 기술적 분석 도구이지만, 투자 결정을 내릴 때는 항상 신중하게 판단하고 다양한 요소를 종합적으로 고려해야 합니다.

다음은 BBand를 계산하기 위한 UDF를 사용한 결과입니다.

import numpy as np
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt
import matplotlib.dates as mpl_dates

st=pd.Timestamp(2025,1, 1)
et=pd.Timestamp(2025, 4,16)
trgnme="000660.KS"
trg=yf.download(trgnme,  st, et)
trg.columns=[i[0] for i in trg.columns]
#볼린져 밴드 계산, 기본적으로 종가를 사용합니다. 
def calculate_bollinger_bands(da, period=20, std_dev=2):
    if type(da) == pd.core.series.Series:
        data = da
    else:
        data = da["Close"] 
    result=pd.DataFrame()
    # 중심선 (Moving Average) 계산
    result["ma"] = data.rolling(window=period, min_periods=1).mean()
    # 표준편차 계산
    std = data.rolling(window=period, min_periods=1).std()
    # 상한선 계산
    result["upper"] = result["ma"] + (std * std_dev)
    # 하한선 계산
    result["lower"] = result["ma"] - (std * std_dev)
    result["%B"]=(data-result["lower"])/(result["upper"]-result["lower"])*100
    result["bwidth"]=(result["upper"]-result["lower"])/result["ma"] * 100
    return result
bb=calculate_bollinger_bands(trg)
bb.head(3)
ma upper lower %B bwidth
Date
2025-01-02 170100.265625 NaN NaN NaN NaN
2025-01-03 175415.898438 190450.778470 160381.018405 67.677670 17.141981
2025-01-06 183116.114583 211830.984479 154401.244688 76.816128 31.362472

Band%B

BBand에서 파생된 지표로 현재가격이 BBand 상단과 하단밴드 대비 어느위치에 있는지를 백분율로 나타냅니다.

$$\text{Band%B} = \frac{\text{price} - \text{Lower Band}}{\text{Uper Band} - \text{Lower Band}}$$
  • price: 현재가격으로 현재 종가 또는 마지막 거래 가격
  • Lower Band: 중간 이평선의 2 표준편차 아래에 위치
  • Uper Band: 중간 이평선의 2 표준편차 위에 위치

Band%B 값은 0에서 100 사이의 값을 가지며, 다음과 같이 해석할 수 있습니다.

> 100 가격이 상단 밴드를 상향 돌파하여 강한 상승 추세 암시
= 100 현재 가격이 상단 볼린저 밴드에 위치
> 80 가격이 상단 밴드에 가까워 과매수 상태일 가능성을 시사
= 50현재 가격이 중간 볼린저 밴드 (일반적으로 단순 이동평균선)에 위치
< 20 가격이 하단 밴드에 가까워 과매도 상태일 가능성을 시사
= 0 현재 가격이 하단 볼린저 밴드에 위치
< 0 가격이 하단 밴드를 하향 돌파하여 강한 하락 추세 암시

Band%B는 다음과 같은 목적으로 활용될 수 있습니다.

  • 과매수 및 과매도 상태 식별: Band%B 값이 극단적인 수준에 도달했을 때 단기적인 추세 반전 가능성을 예측하는 데 도움을 줄 수 있습니다.
  • 추세 강도 확인: 가격이 상단 또는 하단 밴드 근처에서 지속적으로 움직이는 것은 추세의 강도를 나타낼 수 있습니다.
  • 매매 시점 포착: 다른 기술적 지표와 함께 사용하여 매수 또는 매도 시점을 포착하는 데 활용될 수 있습니다. 예를 들어, 상승 추세에서 Band%B가 과매도 수준으로 하락한 후 반등할 때 매수 신호로 해석할 수 있습니다.
  • 다이버전스 분석: 가격 움직임과 Band%B 움직임 간의 불일치 (다이버전스)를 통해 추세 전환 가능성을 예측할 수 있습니다.

주의사항:

  • Band%B는 단독으로 사용하기보다는 다른 기술적 지표 및 분석 방법과 함께 사용하는 것이 좋습니다.
  • 과매수 또는 과매도 신호가 항상 추세 반전을 의미하는 것은 아닙니다. 강한 추세에서는 가격이 과매수 또는 과매도 상태를 유지하면서 계속 움직일 수 있습니다.
  • 볼린저 밴드의 기간 및 표준편차 설정에 따라 Band%B 값의 해석이 달라질 수 있습니다.

bandwidth

볼린저 밴드의 상단과 하단 사이의 거리의 변화를 나타내는 지표로 주가의 변동성의 확대와 축소시점을 파악하는데 도움을 줍니다.

$$\text{band width} = \frac{\text{upper} - \text{lower}}{\text{meddle or ma} }\cdot 100 (\%)$$
  • 폭 확대
    • 변동성 증가로 추세의 시작 또는 강화되는 시점으로 고려할 수 있음.
    • 시장의 불확실성의 커지는 시점에 나타날 수 있음
    • 확대가 멈추거나 감소하면 추세 종료의 가능성 고려
  • 폭 축소
    • 변동성 감소로 횡보 국면의 지속
    • 추세전환을 암시할 수 있음. 역사적으로 매우 좁아진 수준으로 수축 후 확대의 시작은 추세전환의 가능성 높음
    • 밴드 폭이 좁은 상태에서 주가가 상단 또는 하단 밴드를 돌파하는 방향으로 매매전략 설정

위에서 소개한 UDF calculate_bollinger_bands()의 결과에 대한 볼린저 밴드와 %B의 그래프를 작성합니다. 이 그래프들과의 비교를 위해 macd, RSI을 같이 작성합니다.

locator = mpl_dates.DayLocator(interval=20)
formatter = mpl_dates.DateFormatter('%y/%m/%d')
plt.subplots_adjust(hspace=0)

plt.subplot(511)
candleChart(trg)
bband_plot(trg)
plt.grid(True)
ax=plt.gca()
ax.xaxis.set_major_locator(locator)
ax.set_xticklabels([])

plt.subplot(512)
macd_plot(trg)
plt.grid(True)
ax=plt.gca()
ax.xaxis.set_major_locator(locator)
ax.set_xticklabels([])

plt.subplot(513)
rsi_plot(trg)
plt.grid(True)
ax=plt.gca()
ax.xaxis.set_major_locator(locator)
ax.set_xticklabels([])

plt.subplot(514)
percentB_plot(trg)
ax=plt.gca()
ax=plt.gca()
ax.xaxis.set_major_locator(locator)
ax.set_xticklabels([])

plt.subplot(515)
plt.plot(bb["bwidth"], label="bandwidth")
plt.legend(loc="upper left")
ax.xaxis.set_major_locator(locator)
plt.xticks(rotation = 45)
plt.show()

볼린져 벤드에서 주가는 하한선을 교차하여 상승을 보이지만 중간선 하위에서 다시 감소됨을 보입니다. 이것은 %B지표에서 과매도 구간을 벗어나지만 20근처에서 머물다가 다시 아래로의 하향 가능성을 나타내고 있습니다. 일정한 추세를 결정하기 어렵지만 BandWidth의 결과는 확대로 변동성의 증가인 상태임을 나타냅니다. 그러나 그 확대 속도가 감소한 것으로 변동성은 조금씩 감소하며 현재 추세가 강화된 상태로 진행될 것으로 고려할 수 있습니다. 이것은 macd와 signal 선이 음의 영역에 위치하며 macd가 signal에 대한 상향 교차 가능성이 짙어지는 것으로 확인할 수 있습니다. 또한 RSI의 경우 %B와 같이 하향 가능성을 보입니다. 그러므로 봉차트의 이전저점에 비해 다음의 저점의 위치를 보고 상승과 하락을 결정할 수 있습니다.

댓글

이 블로그의 인기 게시물

[Linear Algebra] 유사변환(Similarity transformation)

유사변환(Similarity transformation) n×n 차원의 정방 행렬 A, B 그리고 가역 행렬 P 사이에 식 1의 관계가 성립하면 행렬 A와 B는 유사행렬(similarity matrix)이 되며 행렬 A를 가역행렬 P와 B로 분해하는 것을 유사 변환(similarity transformation) 이라고 합니다. $$\tag{1} A = PBP^{-1} \Leftrightarrow P^{-1}AP = B $$ 식 2는 식 1의 양변에 B의 고유값을 고려한 것입니다. \begin{align}\tag{식 2} B - \lambda I &= P^{-1}AP – \lambda P^{-1}P\\ &= P^{-1}(AP – \lambda P)\\ &= P^{-1}(A - \lambda I)P \end{align} 식 2의 행렬식은 식 3과 같이 정리됩니다. \begin{align} &\begin{aligned}\textsf{det}(B - \lambda I ) & = \textsf{det}(P^{-1}(AP – \lambda P))\\ &= \textsf{det}(P^{-1}) \textsf{det}((A – \lambda I)) \textsf{det}(P)\\ &= \textsf{det}(P^{-1}) \textsf{det}(P) \textsf{det}((A – \lambda I))\\ &= \textsf{det}(A – \lambda I)\end{aligned}\\ &\begin{aligned}\because \; \textsf{det}(P^{-1}) \textsf{det}(P) &= \textsf{det}(P^{-1}P)\\ &= \textsf{det}(I)\end{aligned}\end{align} 유사행렬의 특성 유사행렬인 두 정방행렬 A와 B는 'A ~ B' 와 같...

[sympy] Sympy객체의 표현을 위한 함수들

Sympy객체의 표현을 위한 함수들 General simplify(x): 식 x(sympy 객체)를 간단히 정리 합니다. import numpy as np from sympy import * x=symbols("x") a=sin(x)**2+cos(x)**2 a $\sin^{2}{\left(x \right)} + \cos^{2}{\left(x \right)}$ simplify(a) 1 simplify(b) $\frac{x^{3} + x^{2} - x - 1}{x^{2} + 2 x + 1}$ simplify(b) x - 1 c=gamma(x)/gamma(x-2) c $\frac{\Gamma\left(x\right)}{\Gamma\left(x - 2\right)}$ simplify(c) $\displaystyle \left(x - 2\right) \left(x - 1\right)$ 위의 예들 중 객체 c의 감마함수(gamma(x))는 확률분포 등 여러 부분에서 사용되는 표현식으로 다음과 같이 정의 됩니다. 감마함수는 음이 아닌 정수를 제외한 모든 수에서 정의됩니다. 식 1과 같이 자연수에서 감마함수는 factorial(!), 부동소수(양의 실수)인 경우 적분을 적용하여 계산합니다. $$\tag{식 1}\Gamma(n) =\begin{cases}(n-1)!& n:\text{자연수}\\\int^\infty_0x^{n-1}e^{-x}\,dx& n:\text{부동소수}\end{cases}$$ x=symbols('x') gamma(x).subs(x,4) $\displaystyle 6$ factorial 계산은 math.factorial() 함수를 사용할 수 있습니다. import math math.factorial(3) 6 a=gamma(x).subs(x,4.5) a.evalf(3) 11.6 simpilfy() 함수의 알고리즘은 식에서 공통사항을 찾아 정리하...

sympy.solvers로 방정식해 구하기

sympy.solvers로 방정식해 구하기 대수 방정식을 해를 계산하기 위해 다음 함수를 사용합니다. sympy.solvers.solve(f, *symbols, **flags) f=0, 즉 동차방정식에 대해 지정한 변수의 해를 계산 f : 식 또는 함수 symbols: 식의 해를 계산하기 위한 변수, 변수가 하나인 경우는 생략가능(자동으로 인식) flags: 계산 또는 결과의 방식을 지정하기 위한 인수들 dict=True: {x:3, y:1}같이 사전형식, 기본값 = False set=True :{(x,3),(y,1)}같이 집합형식, 기본값 = False ratioal=True : 실수를 유리수로 반환, 기본값 = False positive=True: 해들 중에 양수만을 반환, 기본값 = False 예 $x^2=1$의 해를 결정합니다. solve() 함수에 적용하기 위해서는 다음과 같이 식의 한쪽이 0이 되는 형태인 동차식으로 구성되어야 합니다. $$x^2-1=0$$ import numpy as np from sympy import * x = symbols('x') solve(x**2-1, x) [-1, 1] 위 식은 계산 과정은 다음과 같습니다. $$\begin{aligned}x^2-1=0 \rightarrow (x+1)(x-1)=0 \\ x=1 \; \text{or}\; -1\end{aligned}$$ 예 $x^4=1$의 해를 결정합니다. solve() 함수의 인수 set=True를 지정하였으므로 결과는 집합(set)형으로 반환됩니다. eq=x**4-1 solve(eq, set=True) ([x], {(-1,), (-I,), (1,), (I,)}) 위의 경우 I는 복소수입니다.즉 위 결과의 과정은 다음과 같습니다. $$x^4-1=(x^2+1)(x+1)(x-1)=0 \rightarrow x=\pm \sqrt{-1}, \; \pm 1=\pm i,\; \pm1$$ 실수...