본문 바로가기
Python

추세 지표와 변동성 지표의 조합을 통한 가상 화폐 매매 전략

by 아짱이아빠 2022. 2. 20. 21:21
반응형

파이썬을 이용하여 추세 지표와 변동성 지표를 조합한 가상 화폐 매매 전략에 대해 알아보겠다.

주식이나 가상 화폐 거래에 있어서 보조 지표를 활용할 때에 많이 하는 얘기가 하나의 지표에 의존하는 것보다는 다른 여러 지표들과 같이 적용하는 것이 false 신호로 인한 손해를 조금이라도 막을 수 있다는 것이다.

그래서 이번에는 가격의 추세를 보여준다는 추세 지표와 가격의 변동성을 파악할 때 사용되는 변동성 지표를 조합하는 방법에 대해 얘기해 보겠다.

참고로 여러번 얘기하였지만 주식이나 가상 화폐 거래에 대해 전문적인 지식이 있지 않으며 파이썬 공부를 하다가 가상 화폐 실시간 매매 전략에 관심이 생겨 개인적으로 공부한 것과 생각을 정리한 것임을 알아두길 바란다.

 

[추세 지표]

추세 지표에는 여러 가지가 있는데 여기서는 대표적인 지표인 MACD와 이를 정규화한 Normalized MACD, 그리고 TRIX를 이용한다.

MACD와 Normalized MACD에 대해서는 아래의 링크에 관련 내용이 있으니 참고하길 바란다.

 

 

파이썬을 이용한 주식 및 가상 화폐 매매 전략 - Normalized MACD

주식이나 가상화폐 매매 전략에 있어서 정규화된(Normalized) MACD를 적용하는 방법과 효과에 대한 내용을 파이썬을 통해 알아본다. [MACD] MACD는 Moving Average Convergence & Divergence의 약자로 주가나 시세..

superhky.tistory.com

 

TRIX는 종가를 3번에 걸쳐 지수이동평균을 취함으로써 이동평균선이 완만하게 바뀌어 불필요하게 튀는 값을 제거한 지표라 할 수 있다. 

즉, 다음과 같이 구할 수 있다.

 

- EMA(1) = 종가의 N일 지수이동평균

- EMA(2) = EMA(1)의 N일 지수이동평균

- EMA(3) = EMA(2)의 N일 지수이동평균

TRIX 지표를 구하는 공식
(TRIX 지표를 구하는 공식)

 

TRIX 지표를 통한 매매는 Signal 선을 구하여 TRIX 값이 Signal 값을 상향 돌파할 때에 매수를 하고 반대로 하향 돌파할 때에 매도를 하는 것이 대표적인 방법이다.

Signal 선은 TRIX를 단순이동평균을 통해 구할 수 있다.

 

이를 파이썬 코드로 구현한 것은 아래와 같다.

EMA1 = df['close'].ewm(span=9).mean() 
EMA2 = EMA1.ewm(span=9).mean()
EMA3 = EMA2.ewm(span=9).mean()

df['TRIX'] = EMA3.pct_change()*100
df['TRIX_Sig'] = df['TRIX'].rolling(7).mean()

 

df[‘close’]는 가상 화폐 거래소에서 다운로드한 ohlcv 데이터를 df 이름의 데이터프레임에 저장한 것이고 그중에서 종가를 나타내는 ‘close’ column의 값들을 의미한다.

위의 코드는 9일의 지수이동평균을 구한 것이며 앞의 TRIX 지표를 구하는 식이 의미하는 수익률은 파이썬 코드 .pct_change()로 구할 수 있다.

Signal선은 7일 단순이동평균으로 구한다.

 

[변동성 지표 - RMI]

RMI(Relative Momentum Index) 지표는 변동성 지표 중 대표적인 지표인 RSI(Relative Strength Index)를 개선한 지표라고 한다.

RSI와의 차이점은 RSI는 현재의 가격과 전일의 가격을 비교하여 계산하지만 RMI는 현재의 가격과 N일전의 가격을 비교하여 계산한다는 것이다.

이를 통해 RSI 지표가 갖는 신호 등락의 빈번함을 보완한다.

RMI 지표를 통한 매매기법은 RSI와 유사하게 30 이하를 과매도로 보고 70 이상을 과매수 상태로 판단하여 매매를 한다.

RMI 지표를 계산하는 파이썬 코드는 아래와 같다.

delta = df['close'].diff(6)
delta = delta.dropna()
up = delta.copy()
down = delta.copy()
up[ up < 0 ] = 0
down[ down > 0 ] = 0
time_period = 14
AVG_Gain = up.rolling(window=time_period).mean()
AVG_Loss = abs(down.rolling(window=time_period).mean())
RM = AVG_Gain / AVG_Loss
RMI = 100.0 - (100.0/(1.0 + RM))
df['RMI'] = RMI

 

현재의 가격과 6일 전 가격의 차를 구하고 .dropna() 함수를 통해 데이터 중 NaN 값을 제거하여 변수 delta에 저장한다.

이 변수 delta에 저장된 값에서 당일의 값이 6일 전보다 상승한 값만을 저장하고 나머지는 0으로 채워 up에 저장하고 반대로 하락한 값만을 가지고 나머지는 0으로 채워 down에 저장한다.

그전에 변수 delta 에서 .copy() 함수를 사용하여 변수 up과 down에 서로 다른 메모리 id를 부여하여 혹시라도 데이터가 서로 영향을 주지 않도록 하였다.

그다음은 RSI 계산과 동일하다.

 

[매매 전략]

추세 지표와 변동성 지표를 이용한 매매 전략은 추세 지표에서 매수 조건이 되었을 때에 변동성 지표인 RMI 값이 여전히 과매도 상태 즉, 30 미만인 경우에만 매수를 하는 것이다.

그리고 크게 상승하고 있을 때에도 수익을 낼 수 있도록 추세 지표가 매수 조건이 되면서 RMI가 70 이상이고 이전의 RMI 값이 계속 상승하고 있다면 매수를 할 수 있도록 한다. 

 

매도는 매수할 때의 가격에서 1% 가격이 상승하면 매도를 한다.

이전에 여러 지표를 통해 매도 조건을 시험해 봤지만 항상 실제의 가격 흐름보다 지표는 늦기 때문에 큰 상승세가 아니고서는 매수할 때와 동일 가격 또는 더 낮은 가격에 매도를 하게 된다.

그래서 여기서는 단순한 매도 조건을 설정하였다.

또한, 매수를 했지만 가격이 오르지 않고 하락을 하면 물릴 수 있기 때문에 매수했던 가격에서 1%가 떨어지면 매도를 하는 조건을 추가한다.

 

이러한 전략을 파이썬 함수로 정의한 것은 아래와 같다.

def buy_sell(data, case1, case2, case3):
  BuySignal = []
  SellSignal = []
  buy_price=0
  sell_price=0
  flag = 1

  for i in range(0, len(data)):
    if (data[case1][i-2] < data[case2][i-2]) and (data[case1][i-1] > data[case2][i-1]) and ((data[case1][i] > data[case2][i]) and (data[case3][i] < 30)) and flag == 1:
      BuySignal.append(data['close'][i])
      SellSignal.append(np.nan)
      buy_price=data['close'][i]
      flag = 0

    elif (data[case1][i-2] < data[case2][i-2]) and (data[case1][i-1] > data[case2][i-1]) and ((data[case1][i] > data[case2][i]) and (data[case3][i] >= 70)) and (data[case3][i-1]-data[case3][i-2]>0) and (data[case3][i]-data[case3][i-1]>0) and flag == 1:
      BuySignal.append(data['close'][i])
      SellSignal.append(np.nan)
      buy_price=data['close'][i]
      flag = 0

    elif (df['close'][i] > buy_price * 1.01) and flag == 0:
      SellSignal.append(data['close'][i])
      BuySignal.append(np.nan)
      flag = 1

    elif (df['close'][i] < buy_price * 0.99) and flag == 0:
      SellSignal.append(data['close'][i])
      BuySignal.append(np.nan)
      flag = 1

	else:
      SellSignal.append(np.nan)
      BuySignal.append(np.nan)

  return(BuySignal, SellSignal)



[매매 전략 Backtesting]

(엑시인피니티(ASX))

추세 지표는 TRIX와 MACD, 그리고 Normalized MACD가 각각 특징이 있고 어떤 것이 무조건 좋다는 것이 없으므로 이 세 가지 지표를 각각 적용했을 때의 수익률을 비교해 본다.

먼저 투자를 했다가 현재까지 물려있는 가상 화폐 엑시인피니티의 5분 봉 데이터를 분석해 본다. 

추세 지표별 결과 및 RMI - 엑시인피니티(AXS)
(추세 지표별 결과 및 RMI - 엑시인피니티(AXS))

 

위는 2월 19일 08시부터 19일 23시까지의 데이터이며 각 추세 지표가 Signal 선을 상향 돌파하는 시점이 조금씩 다른 것을 볼 수 있다.

TRIX와 MACD는 그래도 좀 유사하지만 Normalized MACD는 많이 다른 모습을 볼 수 있다.

이러한 서로 다른 특징이 앞에서 얘기한 매매 전략에 어떤 영향을 줄지는 다음에서 알아보겠다.

참고로, backtesting을 하는 파이썬 코드는 아래의 링크에 있다.

 

 

SMA와 MACD 이용 Python 가상화폐 자동매매(2/2)-backtesting

지난번에 알아본 자동매매 프로그램을 backtesting 하는 방법과 그 결과에 대한 분석을 해보겠다. 먼저 backtesting 코드를 알아본 후 dp이다(ADA)와 이더리움클래식(ETC)에 대해 자동매매 프로그램의 누

superhky.tistory.com

 

TRIX 추세 지표 기반 매매전략 backtesting 결과 - 엑시인피니티(AXS)
(TRIX 추세 지표 기반 매매전략 backtesting 결과 - 엑시인피니티(AXS))

먼저 위는 TRIX 지표를 기반으로 RMI 지표와 조합하여 매매를 했을 때의 결과이며 분석한 데이터 기간 동안 엑시인피니티는 하락을 했으며 총 5번의 매매가 이루어지고 2번은 1% 이상의 이익이 나는 거래이고 3번은 1% 이하 손해를 보는 거래가 되어 전체 누적 수익률은 약 1.5% 손해를 본다는 결과이다.

엑시인피니티의 가격은 약 67,500원에서 66,500원이 되었으므로 그냥 뒀어도 비슷한 손해를 봤을 것이다.

 

다음은 MACD를 기반으로 RMI 지표와 조합하여 매매를 했을 때의 결과이다.

MACD 추세 지표 기반 매매전략 backtesting 결과 - 엑시인피니티(AXS)
(MACD 추세 지표 기반 매매전략 backtesting 결과 - 엑시인피니티(AXS))

MACD를 기반으로 했을 때에는 총 두 번의 매매가 있었고 한 번은 이익, 한 번은 손해여서 결국 0.4%의 손해를 본다는 결과이다.

1.5%의 손해를 보는 결과보다는 우수하다고 할 수 있다.

 

다음은 Normalized MACD를 기반으로 RMI 지표와 조합하여 매매를 했을 때의 결과이다.

Normalized MACD 추세 지표 기반 매매전략 backtesting 결과 - 엑시인피니티(AXS)
(Normalized MACD 추세 지표 기반 매매전략 backtesting 결과 - 엑시인피니티(AXS))

총 세 번의 거래가 모두 손해를 봤고 그래서 4%대의 가장 큰 손해를 보는 결과가 나왔다.

 

엑시인피니티의 데이터 경우에서는 MACD를 추세 지표로 사용하는 것이 가장 좋은 결과를 내는 것으로 보인다.

 

(이더리움(ETH))

이번에 이더리움의 데이터를 가지고 backtesting을 해본다.

앞에서와 동일하게 같은 시간대의 데이터를 가지고 비교를 해봤다.

추세 지표별 결과 및 RMI - 이더리움(ETH)
(추세 지표별 결과 및 RMI - 이더리움(ETH))

세 가지 추세 지표가 모두 조금씩 다른 매수 시점을 보인다.

이러한 결과가 RMI 조건과 조합되어 어떤 결과를 보이는지 아래에서 살펴보겠다.

TRIX 추세 지표 기반 매매전략 backtesting 결과 - 이더리움(ETH)
(TRIX 추세 지표 기반 매매전략 backtesting 결과 - 이더리움(ETH))

이더리움 역시 backtesting 기간은 하락하는 추세이다.

여기서 TRIX 지표 기반은 모두 손해를 보는 두 번의 거래가 발생하고 그래서 약 4%의 손해를 본다는 결과이다.

그냥 두었어도 약 2.5% 하락하는 추세의 데이터인데 이보다 더 손해를 본다.

 

MACD 추세 지표 기반 매매전략 backtesting 결과 - 이더리움(ETH)
(MACD 추세 지표 기반 매매전략 backtesting 결과 - 이더리움(ETH))

MACD를 기반으로 한 결과는 두 번의 손해나는 거래 후 마지막에 한 번 이익을 보는 거래가 이루어져 누적 수익률은 2%의 손해이다.

어떻게 보면 하락하는 추세에서 잘 버티는 거래를 했다고도 볼 수 있겠다.

 

Normalized MACD 추세 지표 기반 매매전략 backtesting 결과 - 이더리움(ETH)
(Normalized MACD 추세 지표 기반 매매전략 backtesting 결과 - 이더리움(ETH))

Normalized MACD를 기반으로 한 backtesting 결과는 이번에도 4%대의 손해를 보는 것으로 나왔다.

 

계속 하락하는 추세에 있을 때는 어떤 전략을 써도 손해를 볼 것이다.

그래서 마지막으로 상승장에 있었던 가상 화폐의 데이터로 backtesting을 해봤다.  

 

반응형

 

(저스트(JST))

가상 화폐 저스트는 그나마 이 시기에 상승을 하고 있었다.

다음의 그림은 추세 지표별 결과 및 RMI 지표 결과이다.

추세 지표별 결과 및 RMI - 저스트(JST)
(추세 지표별 결과 및 RMI - 저스트(JST))

 

TRIX 추세 지표 기반 매매전략 backtesting 결과 - 저스트(JST)
(TRIX 추세 지표 기반 매매전략 backtesting 결과 - 저스트(JST))

TRIX 기반의 결과는 두 번의 이익 거래와 세 번의 손해 거래를 통해 누적 수익률은 약 2%의 손해이다.

상승 추세에 있는 가상 화폐이고 그냥 두었어도 약 6%의 이익을 볼 수 있었지만 TRIX 지표와 RMI 지표를 기반으로 매매를 하면 2%의 손해를 보니 이 전략은 적당해 보이지 않는다.

 

MACD 추세 지표 기반 매매전략 backtesting 결과 - 저스트(JST)
(MACD 추세 지표 기반 매매전략 backtesting 결과 - 저스트(JST))

MACD를 기반으로한 매매는 누적 수익률 4%로 준수한 결과가 나왔다.

그냥 두었을 때보다는 적지만 그래도 손해보지 않았다는 것은 한 번 실제로 적용해 볼만하다는 생각을 갖게 한다.

위의 그림을 보면 중간에 높게 치솟는 구간에 매매가 이뤄지지 않는 것은 아쉽지만 어쩔 수 없다.

거래가 이뤄지지 않은 이유는 앞의 그림에서 분명 MACD 선이 Signal 선을 돌파했지만 RMI 값이 30보다 커진 상태였기 때문이다.

RMI 값이 30보다 커진 상태는 이미 가격이 어느 정도 올랐다고 보고 매수 진입이 늦었다는 의미이기 때문에 이 경우처럼 그럼에도 불구하고 가격이 계속 오를 때는 어쩔 수 없이 거래 없이 보낼 수밖에 없다.

이런 경우도 매수에 포함하기 위해 조건을 수정하면 분명 가격이 오르지 못하고 바로 하락하는 케이스에 노출되어 손해를 볼 확률이 높아진다.

 

Normalized MACD 추세 지표 기반 매매전략 backtesting 결과 - 저스트(JST)
(Normalized MACD 추세 지표 기반 매매전략 backtesting 결과 - 저스트(JST))

Normalized MACD 기반의 backtesting 결과도 1%의 손해를 보는 것이었다.

앞의 두 가지 가상 화폐의 경우보다는 손해 정도가 작았지만 상승하는 추세에 있는 경우에도 손해를 봤으니 역시 실제 적용하기에는 무리가 있어 보인다.

 

[결 론]

추세 지표 중 RMI 지표를 구하는 방법을 파이썬 코드로 알아보고 추세 지표와 변동성 지표를 조합하여 매매 전략을 만들어봤다.

추세 지표는 TRIX와 MACD, Normalized MACD가 각기 조금씩 다른 매수 타이밍을 보이며 어떤 경우에서는 다른 지표는 매수 시점이지만 또 다른 지표는 매수를 하지 않는 경우도 나타난다.

매수가 일어나지만 결국 손해를 보는 결과를 낼 수 있기 때문에 매수를 하지 않는 것이 더 좋은 영향을 줄 수 있고 이는 또한 반대의 경우가 발생할 수도 있다.

 

Backtesting을 통해 세 가지의 추세 지표 중 MACD가 가장 우수한 결과를 보였으나, backtesting을 하는 데이터가 너무 적었기 때문에 무조건 MACD가 제일 좋다고 결론을 지을 수는 없을 것 같다.

 

처음에는 파이썬을 공부하려고 시작했는데 요즘에는 계속 가상 화폐 매매만 쳐다보게 된다.

이렇게 된 이유가 만약 자동매매 프로그램을 만들어 하루에 딱 5%씩만 수익을 낸다면 50,000원을 가지고 8개월 후면 60억이 된다는 생각을 하면서부터인 것 같다.

정말 이렇게만 되면 바랄 게 없겠지만 이제는 이런 생각에서 벗어나야 할 때인 것 같다.

 

반응형

댓글