본문 바로가기
Python

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

by 아짱이아빠 2021. 12. 22. 21:39
반응형

주식이나 가상화폐 매매 전략에 있어서 정규화된(Normalized) MACD를 적용하는 방법과 효과에 대한 내용을 파이썬을 통해 알아본다.

 

[MACD]

MACD는 Moving Average Convergence & Divergence의 약자로 주가나 시세의 추세를 파악하는 대표적인 보조 지표이다.

주가의 단기이동평균선과 장기이동평균선을 이용하며 이 두 개의 선은 수렴하고 환산하는 정도를 나타내 준다.

MACD는 단기지수이동평균에서 장기지수이동평균을 뺀 것이고 Signal 선은 이 MACD의 n일 지수이동평균이다.

이를 이용한 대표적인 거래전략은 MACD 선이 Signal 선을 상향 돌파할 때에 매수를 하고 MACD 선이 Signal 선을 하향 돌파할 때에 매도를 하는 것이다.

 

MACD를 구하는 파이썬 코드는 아래의 링크에 있다.

 

 

Python을 이용한 주식 및 가상화폐 분석 - MACD & Fibonacci 전략

이전 글에서 Fibonacci Retracement Level을 통해 주식 시세나 가상화폐 시세 분석을 하는 것에 대해 알아봤다. 그리고 그 이전에는 MFI와 OBV와 같은 보조 지표 분석을 통해 매수와 매도 시점을 알아내는

superhky.tistory.com

 

그러나 대부분의 보조 지표가 그러하듯 MACD 역시 실제의 추세보다 느리다는 단점이 있다.

그렇기 때문에 MACD만을 이용하여 거래를 하면 오히려 손해를 보는 거래를 할 수 있다.

일반 MACD를 통한 거래 시 - 비트코인(BTC)
(일반 MACD를 통한 거래 시 - 비트코인(BTC))

위는 MACD 신호선에 따라서 파란색 부분에서 매수를 하고 빨간색 부분에서 매도를 하게 된다.

손해를 보는 거래를 한 것은 아니지만 수수료를 고려하면 거의 이득은 없었을 것이다. 

앞에서 얘기한 것과 같이 MACD는 실제 추세보다 느리기 때문에 매도 조건에서는 가격이 많이 내려와 있는 상황이 될 수 있게 된다.

 

이러한 문제는 MACD를 정규화하여 조금 개선할 수 있다.  

 

[정규화 MACD]

정규화는 데이터를 일정한 크기로 맞추는 작업을 말한다.

이 정규화를 통해 값이 크게 튄 데이터로 인해 데이터 전체가 overfitting 되는 것을 방지한다.

그래서 정규화는 머신 러닝 시에 많이 사용된다.

a에서 b 사의 값으로 데이터를 정규화하는 공식은 아래와 같다. 

a부터 b까지의 범위내에서 정규화하는 공식
(a부터 b까지의 범위내에서 정규화하는 공식)

 

아래의 그림은 위에서의 일반적인 MACD 대신 정규화된 MACD를 적용해본 것으로서 약간이나마 위에서 본 일반 MACD 보다 조금 빠르게 매도를 할 수 있다. 

정규화 MACD를 통한 거래 시 - BTC
(정규화 MACD를 통한 거래 시 - 비트코인(BTC))

 

[파이썬 코드]

분석하고자 하는 가상화폐 또는 주식 데이터를 불러오고 이를 시각화하며 Backtesting 하는 코드는 아래의 링크에 있으니 넘어가도록 하겠다.

 

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

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

superhky.tistory.com

 

MACD를 정규화하는 코드는 다음과 같다.

def normalization(x):
    min_value = min(x)
    max_value = max(x)
    return list(map(lambda x: 2*(x-min_value)/(max_value-min_value)-1, x))

df['norm_MACD'] = normalization(MACD)
df['norm_Signal'] = normalization(Signal)

 

‘map’ 함수는 리스트의 요소를 지정된 함수로 처리하도록 하고 새로운 리스트를 만들게 하며 코드를 단순하게 구성할 수 있게 해 준다.

또한 ‘lambda’ 함수 역시 코드를 간단하게 만들어 준다.

여기서 ‘lambda x’는 -1부터 1까지의 범위로 정규화하는 수식을 정의하고 입력되는 x의 값을 계산하여 그 결과를 리스트로 만들어 주는 내용이다.

x에는 MACD와 Signal의 값이 입력되고 정규화된 MACD와 Signal은 column ‘norm_MACD’와 ‘norm_Signal’에 저장된다.

 

아래는 정규화된 MACD를 통한 거래 전략 부분이다.

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

	elif (data[case1][i] < data[case2][i]) 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)

 

앞에서 얘기한 것과 같이 정규화된 MACD 선이 정규화된 Signal 선을 상향 돌파할 때에 매수를 하고 반대로 하향 돌파하면 매도를 하는 것이다.



[Backtesting]

기존 MACD를 이용하여 매매했을 때와 정규화된 MACD를 통해 했을 때의 결과를 비교해보았다.

먼저 이더리움(ETH)의 30분 차트를 이용한 매매 결과는 다음과 같다.

일반 MACD 결과 - 이더리움(ETH)
(일반 MACD 결과 - 이더리움(ETH))
Normalized MACD 결과 - 이더리움(ETH)
(Normalized MACD 결과 - 이더리움(ETH))

이더리움은 15일부터 19일 사이 4,768,594원에서 4,940,327원으로 약 3% 올랐는데 일반 MACD로는 약 5% 그리고 정규화된 MACD로는 약 7%의 수익을 볼 수 있었다는 결과이다.

 

다음은 디센트럴랜드(MANA)에 대한 분석 결과이다.

 

일반 MACD 결과 - 디센트럴랜드(MANA)
(일반 MACD 결과 - 디센트럴랜드(MANA))
Normalized MACD 결과 - 디센트럴랜드(MANA)
(Normalized MACD 결과 - 디센트럴랜드(MANA))

최근 거래량도 많아지고 가격도 오른 디센트렐랜드의 경우에는 15일 기준 약 3,924원에서 19일에는 4,286원으로 약 9% 올랐다.

이를 일반 MACD 기준으로 거래를 했다면 약 8.8%의 수익으로 그냥 두었을 때와 비슷한 수준이지만 정규화 MACD 기준으로 거래를 했다면 약 11%의 수익을 볼 수 있었다는 결과이다.

 

주식의 데이터에도 적용해봤다.

삼성전자(005930)의 올해 1년의 데이터를 가지고 분석을 한 결과는 아래와 같다.

 

일반 MACD 결과 - 삼성전자(005930)
(일반 MACD 결과 - 삼성전자(005930))
Normalized MACD 결과 - 삼성전자(005930)
(Normalized MACD 결과 - 삼성전자(005930))

 

삼성전자는 1월 4일 83,000원이었으며 12월 17일 기준으로는 78,000원이 되어 약 6%가 빠졌다.

일반 MACD를 적용하여 거래를 했다면 20% 손해를 보았을 것이나, 정규화된 MACD를 적용하여 거래를 했다면 약 4%의 손해만 보았을 것이라는 결과이다.

 

 

[결 과]

일반 MACD를 기준으로 거래를 했을 때와 정규화시킨 MACD를 기준으로 거래를 했을 때의 결과를 비교해보았다.

일반 MACD보다 조금 더 빠르게 가격의 변화에 대응하는 경향이 있기 때문에 그만큼 수익률도 높은 것으로 나왔다.

또한, 전체적으로 하락하는 경우에도 중간중간 수익을 내는 거래를 통해 전체 손해보다 좀 적게 손해를 보는 결과도 확인할 수 있었다.

 

그러나 MACD는 MACD선이 Signal 선을 상향 돌파해도 가격은 떨어지는 false 신호들이 존재한다.

그렇기 때문에 가격이 횡보를 하거나 하락을 하는 경우에는 계속해서 손해를 보는 거래들을 하게 된다.

이러한 경우를 어느 정도 방지하기 위해서는 RSI나 200일 EMA와 같은 추가적인 보조 지표를 조건에 적용하는 것이 필요할 수 있다.

그렇지만 여러 보조 지표를 같이 적용하면 매수의 조건이 타이트해서져서 수익을 낼 수 있는 확률은 높아져도 한 번 거래 시의 수익액은 줄어들 수 있으며 또한 여러 보조 지표 적용에도 false 신호는 여전히 존재한다.

그러므로 여러 보조 지표를 동시에 적용하는 것이 반드시 수익률이 높다고 보기 힘들 수 있다는 것이 개인적인 생각이다.

 

마지막으로 위의 backtesting에서 좋은 결과가 있었지만 이를 만약 자동 매매 시스템에 적용하려면 아래의 링크에 있는 내용을 주의해야 할 것이다.

 

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

이번에는 Python을 이용한 가상화폐의 자동매매에 대해 알아본다. 최근 2개월간 자동매매 프로그램을 짜고 실제로 투자를 해보았으며 이를 통해 알게 된 것들을 포함하여 정리해보고자 한다. 처

superhky.tistory.com

 

반응형

댓글