기술/지표 알림

Parabolic SAR 계산 및 알림

금붕맨 2023. 5. 24. 20:44
반응형

Parabolic SAR 계산 및 알림

Parabolic SAR

 

Parabolic SAR란?

이슈가 되고 관심이 쏠린 차트를 보면 세력이 붙었다, 힘이 좋다 등 강한 추세를 이어가는 모습을 볼 수 있습니다. 만약 그것이  상승 추세라면 계속해서 고점을 갱신하는 것도 보신 적이 있을 것입니다. 반대로 하락 추세라면 계속해서 저점을 갱신하는 모양을 예상할 수 있습니다.

 

파라볼릭 SAR은 이런 특징을 이용하여 추세의 모멘텀을 감지하도록 Welles Wilder라는 사람이 설계한 지표입니다. 모멘텀이 상승추세면 계속해서 상승 곡선을 그리며 나타내다가 상승이 끝나면 그대로 반전되는 지표의 모습으로 추세를 예측하는 방식입니다. 이러한 방식으로 인하여 Stop and Reverse라는 이름이 붙여진 Parabolic SAR 지표입니다.

 

파라볼릭 SAR

일반적으로 SAR이 가격보다 아래에 있으면 상승추세, 가격보다 위에 있으면 하락추세라고 판단할 수 있습니다. 정말 간단하게 추세를 판단할 수 있는 도구로 사용될 수 있지만, 가격이 횡보를 할 경우 지표의 전환이 빈번하게 일어나면서 오히려 판단을 그르칠 수 있는 단점이 있습니다. 개인적으로 위의 차트만을 보았을 때 매수시점의 판단보다는 매도시점의 판단기준으로 사용하는 것이 좋다고 생각합니다.

 

바이낸스 지표

바이낸스 지표 설정창에 들어가 보시면 조정할 수 있는 값이 두 종류가 보입니다. Start는 가속계수의 초기값으로 0.02가 기본값이고, Maximum은 가속계수의 최댓값으로 0.2가 기본값입니다. SAR지표를 고안한 Welles Wilder는 0.02, 0.2가 가장 신뢰할 수 있는 수치라고 자신의 책에서 정의하였기 때문에 굳이 변경할 일은 없다고 생각합니다.

 

 

계산식

SAR을 구하는 계산자체는 어렵지 않으나 그 과정에서 규칙이 많이 있기 때문에 복잡할 수 있습니다.

 

1) 초기 추세 결정 및 3일 차 SAR값

상향 추세 : (2일 차 고가 - 1일 차 고가) > (1일 차 저가 - 2일 차 저가) 

하향 추세 : (2일 차 고가 - 1일 차 고가) < (1일 차 저가 - 2일 차 저가)

초기 추세는 1일 차와 2일 차의 고가, 저가에 의해 결정됩니다. 즉 고가와 저가 중 무엇이 더 큰 폭으로 갱신되었는가에 따라 초기 추세가 결정됩니다. 처음에만 이 방식을 쓰고 그 이후로는 reversal 조건에 충족될 때마다 추세가 바뀌어 계산해 주어야 합니다.

 

초기 추세를 결정하였다면 이제는 3일 차의 SAR값을 구해야 합니다.

상향 추세 : SAR = min(1일 차의 저가, 2일 차의 저가)

하향 추세 : SAR = max(1일 차의 고가, 2일 차의 고가)

상향 추세라면 1일 차와 2일 차의 저가 중 가장 작은 값이, 반대로 하향 추세라면 1일 차와 2일 차의 고가 중 가장 높은 값이 3일 차의 SAR이 됩니다.

 

2) 3일 차 이후 SAR값

상하향 추세 : SAR4' = SAR3 + AF3(EP3 - SAR3)

AF3은 3일 차의 가속계수로 설정할 때 start에 해당하는 0.02 값입니다. 처음 시작하거나 추세가 반전되었을 때 0.02로 시작하며 조건을 만족할 때마다 0.02씩 늘어나는 값입니다. EP3는 3일 차의 극점으로 상향추세에서는 그 사이클에서 고가의 최댓값에 해당합니다. 반대로 하향추세에서는 저가들 중 최저값에 해당합니다.

 

그리고 중요한 것은 이 극점이 갱신될 때마다 AF값이 0.02씩 늘어나는 규칙이 있습니다. 0.02씩 늘어나다 최댓값인 0.2에 도달하면 더 이상 늘어나지 않습니다. SAR값을 결정하는 계수이므로 이 값을 조정함으로써 추세의 민감도를 설정할 수 있습니다. 이 값은 클수록 SAR 추세의 전환을 더욱 민감하게, 빈번하게 일어나니 참고하시길 바랍니다.

 

위와 같은 방식대로 SAR값을 구했다고 해서 바로 넣는 것은 아닙니다.

상향 추세 : SAR4 = min(SAR4', low3, low2)

하향 추세 : SAR4 = max(SAR4', high3, high2)

이전 두 행의 저가 및 고가와 비교하여 가장 작거나 큰 값이 4일 차의 SAR값으로 결정됩니다. 이런 방식으로 추세 전환(reversal)이 일어날 때까지 반복하면 됩니다.

 

3) 추세 전환(reversal)

상향 추세 : SAR(t) > Low(t)

하향 추세 : SAR(t) < High(t)

위와 같은 결과가 나올 때 추세가 전환됩니다. 추세가 전환되면 AF는 초기화되어 0.02부터 시작하게 되고, EP는 t캔들의 고가 또는 저가가 됩니다. 여기서부터 계속 반복 계산하시면 됩니다.

 

 

The Complete Guide to Calculating the Parabolic SAR in Python

Step-by-step tutorial to understand and start trading the PSAR

medium.com

계산 방식은 이 글에서 가져온 것이며 데이터프레임으로 하나하나 예시를 잘 나타내었으니 이해가 안 되시면 참고하시길 바랍니다.

 

 

파이썬 코드

import binance as bn
from numpy import nan as npNaN
from pandas import DataFrame, Series

def psar(high, low, close=None, af0=0.02, af=0.02, max_af=0.2):
    """Indicator: Parabolic Stop and Reverse (PSAR)"""
    # Validate Arguments

    def trend(high, low, drift:int=1):
        up = high - high.shift(drift)
        dn = low.shift(drift) - low
        _dmn = (((dn > up) & (dn > 0)) * dn).iloc[-1]
        return _dmn > 0

    # Falling if the first NaN -DM is positive
    trend = trend(high.iloc[:2], low.iloc[:2])
    if trend:
        sar = high.max()
        ep = low.min()
    else:
        sar = low.min()
        ep = high.max()

    if close is not None:
        sar = close.iloc[0]

    long = Series(npNaN, index=high.index)
    short = long.copy()
    reversal = Series(0, index=high.index)
    _af = long.copy()
    _af.iloc[0:2] = af0

    # Calculate Result
    m = high.shape[0]
    for row in range(1, m):
        high_ = high.iloc[row]
        low_ = low.iloc[row]

        if trend:
            _sar = sar + af * (ep - sar)
            reverse = high_ > _sar

            if low_ < ep:
                ep = low_
                af = min(af + af0, max_af)

            _sar = max(high.iloc[row - 1], high.iloc[row - 2], _sar)
        else:
            _sar = sar + af * (ep - sar)
            reverse = low_ < _sar

            if high_ > ep:
                ep = high_
                af = min(af + af0, max_af)

            _sar = min(low.iloc[row - 1], low.iloc[row - 2], _sar)

        if reverse:
            _sar = ep
            af = af0
            trend = not trend # Must come before next line
            ep = low_ if trend else high_

        sar = _sar # Update SAR

        # Seperate long/short sar based on falling
        if trend:
            short.iloc[row] = sar
        else:
            long.iloc[row] = sar

        _af.iloc[row] = af
        reversal.iloc[row] = int(reverse)



    # Prepare DataFrame to return
    _params = f"_{af0}_{max_af}"
    data = {
        f"long": long,
        f"short": short,
        f"af": _af,
        f"reversal": reversal,
    }
    psardf = DataFrame(data)
    psardf.name = f"PSAR{_params}"
    psardf.category = long.category = short.category = "trend"

    return psardf

df = bn.get("BTC","1d")
high = df['high']
low = df['low']
close = df['close']

print(psar(high, low, af0=0.02, af= 0.02, max_af=0.2))

github에서 올라와 있는 코드로 위의 계산 규칙을 생각하며 한 줄 한 줄 읽으시면 이해가 되실 겁니다.

 

           long         short    af  reversal
0           NaN           NaN  0.02         0
1    11008.5000           NaN  0.02         0
2           NaN  69000.000000  0.02         1
3           NaN  67849.160000  0.02         0
4           NaN  66721.336800  0.02         0
..          ...           ...   ...       ...
995         NaN  27763.147001  0.08         0
996         NaN  27607.012041  0.08         0
997         NaN  27463.367878  0.08         0
998  25811.4600           NaN  0.02         1
999  25845.1474           NaN  0.02         0

23년 5월 24일 비트코인 1일 봉의 SAR 데이터프레임입니다. 추세전환이 이루어진 행에는 reversal열에 1(True) 값으로 나타내어졌습니다. 

 

 

전략

ARPA코인

금일 많이 상승한 아르파체인 코인의 1일 봉 차트입니다. 사실 SAR지표는 횡보를 할 때 추세전환이 빈번하게 일어난다는 큰 약점이 있습니다. 그렇기 때문에 저는 큰 추세의 시작의 대표적인 지표인 거래량을 같이 결합해 보려고 합니다. 거래량이 전날 대비 3배 이상 나온 캔들에서 추세전환이 이루어진다면 알림이 오도록 설정하겠습니다.

 

import binance as bn
import threading

tickers = bn.tickers("all")

def run():
    for i in tickers:
        df = bn.get(i,"1d")
        high = df['high']
        low = df['low']
        vol = df['volume']
        psar = bn.psar(high,low)
        reversal = psar['reversal']

        reversal_2 = reversal.iloc[-2]
        vol_2 = vol.iloc[-2]
        vol_3 = vol.iloc[-3]
        vol_ratio = round(vol_2 / vol_3 , 1)

        if vol_ratio > 3 and reversal_2:
            bn.tel_text(i + "  PSAR 추세전환")

    threading.Timer(86400, run).start()

run()

 

 

결과물

코인 텔레그램

USDP의 경우는 스테이블코인이기 때문에 따로 확인은 하지 않도록 하겠습니다.

 

PSAR

DF코인만 눈여겨 볼만한 것 같습니다. 상승 추세로 전환되었는데 그날의 캔들이 음봉이라면 신뢰도가 많이 떨어지는 그림이기 때문에 조금 수정해야겠습니다. DF코인은 1주일 ~ 2주일 정도 지켜보면 좋겠네요.

 

CTXC를 보면 추세의 전환이 이루어지지 않았습니다. 계산에 약간 문제가 있는 듯합니다. 하지만 바이낸스가 PC의 경우에는 close값을 적용하지 않다가 모바일 어플에서는 close를 적용하는 것처럼 정확한 규칙이나 알고리즘이 없어 무엇이 맞는지 잘 모르겠습니다.  또한 공식 홈페이지에 계산 공식만 올라와 있기 때문에 SAR의 규칙이 그렇게 딱딱한 것은 아니라고 봅니다. 그래도 최근값은 거의 일치하니 그렇게 큰 문제는 아닐 것이라고 믿고 있으며 새로 알게 되는 정보가 있으면 수정해서 올리도록 하겠습니다. 알고 계신 분은 댓글 달아주시면 감사하겠습니다.

반응형