본문 바로가기
Python

파이썬을 이용한 가상 화폐 매매 전략 - Heikin Ashi 차트

by 아짱이아빠 2021. 9. 19. 14:37
반응형

여기서는 Heikin Ashi 차트에 대해 알아보고 이를 가상화폐 매매 전략으로 했을 때 얼마큼 이익이 되는지 backtesting을 해보도록 하겠다.

 

Heikin Ashi 차트는 일본말로 “평균 막대”란 의미이다.

기존의 캔들 차트는 많은 노이즈를 가지고 있어서 추세를 파악하기 힘들 수 있다. 

Heikin Ashi 차트는 캔들 차트 값들의 평균을 통해 새로운 차트로 바꾸어 주고 이 차트는 좀 더 쉽게 추세를 파악할 수 있게 해 준다.

 

일반 캔들 차트 - 비트코인
(일반 캔들 차트 - 비트코인)
Heikin Ashi 차트 - 비트코인
(Heikin Ashi 차트 - 비트코인)

 

위의 두 그림은 비트코인(BTC)의 일반 캔들 차트와 Heikin Ashi로 변환된 차트를 나타낸 것이다.

일반 캔들 차트에 비해 상승 구간과 하락 구간이 좀더 명확해진 것을 볼 수 있다.

 

이제 파이썬을 이용하여 일반 캔들 차트에서 Heikin Ashi 차트로 바꾸는 코드에 대해 알아보고 매매전략을 구현한 후 backtesting을 통해 얼마 큼의 이익이 있을 수 있는지 알아보겠다.

매매전략은 여러 가지가 있겠으나 여기서는 가장 단순한 방법으로서 붉은색(하락) 캔들이 초록색(상승) 캔들로 바뀔때바뀔 때 매수를 하고 거꾸로 초록색에서 붉은색으로 캔들이 바뀔 때 매도를 하는 것이다.

 

 

[Heikin Ashi 차트]

일반 캔들 차트에서 Heikin Ashi 차트로 바꾸는 수식은 아래와 같다.

Heikin Ashi 차트 수식
(Heikin Ashi 차트 수식)

 

여기서 소문자로 시작하는 값은 일반 캔들 데이터에서의 값이고 대문자로 시작하는 값은 Heikin Ashi로 계산된 값이다.

 

가상화폐의 분 봉 데이터를 불러오는 파이썬 코드는 다른 포스트에서 많이 설명하였으므로 여기서는 바로 Heikin Ashi 차트로 변환하는 코드로 넘어가도록 하겠다.

new_df01 = new_df[['open', 'high', 'low', 'close' ]]
new_df01['close'] = round(((new_df['open'] + new_df['high'] + new_df['low'] + new_df['close'])/4),2)

for i in range(len(new_df)):
  if i == 0:
    new_df01.iat[0,0] = round(((new_df['open'].iloc[0] + new_df['close'].iloc[0])/2),2)
  else:
    new_df01.iat[i,0] = round(((new_df01.iat[i-1,0] + new_df01.iat[i-1,3])/2),2)

new_df01['high'] = new_df01.loc[:,['open', 'close']].join(new_df['high']).max(axis=1)
new_df01['low'] = new_df01.loc[:,['open', 'close']].join(new_df['low']).min(axis=1)

 

위의 코드를 통해 가상 화폐나 주식의 데이터를 Heikin Ashi 차트로 바꿀 수 있다.

불러온 기존의 데이터는 “new_df”에 저장되어 있으며 Heikin Ashi로 바뀐 데이터를 저장할 “new_df01”을 만들고 기존 데이터를 모두 저장한다.

먼저 Heikin Ashi Close(종가)를 계산하며 앞에서의 수식처럼 기존 데이터의 평균을 취하고 여기서는 round 함수를 이용하여 소수점 2자리수 까지만 표현한다.

그다음에 있는 for 문은 Heikin Ashi Open(시작가)을 계산한다.

Open 가격은 바로 이전 데이터를 이용하므로 이전 데이터가 없는 첫 번째 데이터는 버리고 두 번째 데이터부터 차트에 적용할 수도 있지만 여기서는 Heikin Ashi 변환 전의 open과 close 데이터를 평균하여 첫 번째 Open 데이터로 사용한다.

Heikin Ashi의 High와 Low는 앞에서의 수식과 같이 구한 Heikin Ashi Open과 Close에 기존 데이터의 high와 low를 고려한 max값과 min값으로 구한다.

 

반응형

 

이렇게 계산된 Heikin Ashi 차트는 다음의 코드를 통해 시각화한다.

import plotly.graph_objects as go

fig = go.Figure(data=[go.Candlestick(x=new_df01.index,open=new_df01.open,
                high=new_df01.high, low=new_df01.low, close=new_df01.close)])

fig.update_layout(title = 'TBD', xaxis_title = 'TBD', yaxis_title = 'Price')

fig.show()

 

그래프는 plotly를 사용하여 그렸다. 

plotly는 기존의 많이 썼던 matplotlib 보다 좀 더 반응적인 그래프를 표현할 수 있는 라이브러리이다.

여기서는 plotly를 이용한 많은 그래프 종류 중에 candlestick을 이용하였으며 plotly에 대한 더욱 자세한 내용은 인터넷상에 많이 있으므로 참고하면 되겠다.

 

이더리움(ETH)의 15분 봉 캔들 차트(위)와 Heikin Ashi 차트(아래)
(이더리움(ETH)의 15분 봉 캔들 차트(위)와 Heikin Ashi 차트(아래))

앞의 코드로 이더리움(ETH)의 15분 봉 데이터를 Heikin Ashi 차트로 표현한 것은 위의 그림 중 아래에 있는 것이다.

위에 있는 기존 캔들 차트와 유사하면서 자세히 보면 상승 캔들과 하향 캔들이 확실히 구분되면서 추세를 쉽게 파악할 수 있다.



[매매 전략]

Heikin Ashi 차트를 이용한 매매전략은 다양하게 만들 수 있지만 일단 여기서는 가장 단순히 캔들의 색이 변경되었을 때에 매수와 매도를 하도록 구성해보겠다.

 

def buy_sell(signal, col1, col2):

  sigPriceBuy = []
  sigPriceSell = []
  flag = 1

  for i in range(0, len(signal)):
    if (signal[col1][i] > signal[col2][i]) and (signal[col1][i-1] < signal[col2][i-1]) and flag == 1:      
      sigPriceBuy.append(signal['close'][i])
      sigPriceSell.append(np.nan)
      flag = 0

    elif (signal[col1][i] < signal[col2][i]) and (signal[col1][i-1] > signal[col2][i-1]) and flag == 0:
      sigPriceSell.append(signal['close'][i])
      sigPriceBuy.append(np.nan)
      flag = 1

    else:
      sigPriceSell.append(np.nan)
      sigPriceBuy.append(np.nan)

  return(sigPriceBuy, sigPriceSell)

 

매수는 붉은색 캔들이 녹색의 캔들로 바뀌는 시점이고 이는 즉, 이전 데이터는 종가보다 시작가가 높고 현재 시점의 데이터는 종가가 시작가보다 높은 시점이 된다.

매도는 이와 반대로 녹색의 캔들이 붉은색 캔들로 바뀌는 시점이고 이전 데이터 종가가 시작가보다 높고 현재 시점의 데이터는 종가보다 시작가가 높은 시점이다.

 

이 매매전략을 다음의 코드로 실행시킨다.

x = buy_sell(new_df01, 'close', 'open')

new_df01['Buy_Signal_Price'] = x[0]
new_df01['Sell_Signal_Price'] = x[1]

Heikin Ashi 데이터를 넣어주고 각 매수와 매도 이벤트의 결과 데이터를 새로운 column에 넣어준다.

 

이 결과를 도식화하면 다음과 같다.

 

Heikin Ashi 차트를 통한 매매 결과
(Heikin Ashi 차트를 통한 매매 결과)

 

대략 30회에 가까운 매매가 발생한다.

이 그림으로는 얼마의 수익 또는 손해가 발생했는지 확인이 불가하므로 backtesting을 해보겠다.



[Heikin Ashi Backtesting]

매매 전략에 대해 backtesting을 하는 코드는 아래 링크의 글에서 자세히 설명하였으니 넘어가도록 하겠다.

 

 

 

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

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

superhky.tistory.com

 

Backtesting의 결과는 아래와 같다.

이더리움 Backtesting 결과 - Heikin Ashi
(이더리움 Backtesting 결과 - Heikin Ashi)

2021년 9월 16일 16:30분부터 18일 18:15분까지 총 28번의 매매가 이루어지고 누적 수익률은 약 2%이다.

결과는 이익이 나는 것으로 나왔고 더욱 고무적인 것은 이 테스트 기간은 시작보다 마지막 가격이 낮으므로 가격이 떨어지는 구간의 데이터이고 매수를 걸어놨다면 손해를 보는 것이었지만 Heikin Ashi 차트로 변경하여 거래를 하면 오히려 이익을 볼 수 있었다는 것이다.

 

그러나 여기에는 큰 오류가 한 가지 있다.

(어떤 분들은 이 글을 읽으면서 이미 눈치챘을지 모르겠는데 사실 이전에는 이 부분을 놓치고 있고 글을 올리기 위해 정리하면서 이 오류를 알게 되었다.)

 

위의 오류란 것은 Heikin Ashi 차트는 실제의 데이터와 다르다는 것이다.

즉, Heikin Ashi 차트의 매수 가격과 매도 가격은 실제랑 다르다.

그렇기 때문에 backtesting을 할 때에 Heikin Ashi 차트로 매매 시점을 구하면 실제 매매 시에는 실제 데이터의 가격을 적용해야 한다.

이렇게 바꾸어 다시 backtesting을 해보면 결과는 아래와 같다.

이더리움 Backtesting 결과 - Heikin Ashi에 실제 가격 데이터 적용
(이더리움 Backtesting 결과 - Heikin Ashi에 실제 가격 데이터 적용)

 

실제 이익을 본 거래는 30%도 되지 않으며 결국 총 누적수익률은 약 -3.5%로 손해이다.

그냥 가만히 두었을 때보다 더 손해를 보는 결과이다.



[결 론]

Heikin Ashi 차트를 구현하는 파이썬 코드를 알아봤고 backtesting을 통해 실제 매매에 적용 시 어떤 결과를 가져올지 알아봤다.

결과는 손해를 볼 수 있다는 것이다.

그러나 test 데이터의 기간이 짧고 가상 화폐 하나에 대한 것이었으므로 매매에 전혀 도움이 되지 않는다고 단정 지을 수는 없을 것이다.

 

Heikin Ashi는 분명 일반 캔들 차트보다 경향을 파악하기에 아주 유용하다.

다만 매매 전략이 여기서 했던 것과 같이 단순히 캔들 색이 바로 바뀔 때에 매매를 하는 것이 아니고 이전의 데이터를 활용하여 확실한 상승 또는 하락이 있는지를 확인 후 거래를 한다던가 또는 다른 보조 지표, 예를 들면 이동평균선부터 MACD, 또는 RSI, 거래량 지표 등을 같이 조합하여 전략을 구성하면 좋은 결과가 있을 수 있다고 생각한다. 

 

그럼에도 불구하고 마지막으로 한 가지 아쉬운 점은 우리나라의 주식 앱이나 가상화폐 거래소에서 Heikin Ashi로 바꿔서 보여주는 기능을 제공하지 않기 때문에 실시간으로 확인이 불가하다.

 

반응형

댓글