본문 바로가기
AyoProject/Ayotera-Trade

[AT] 17. MACD 지표에 대한 구현 및 매매시점 예측 (1)

by 청양호박이 2020. 11. 11.

바로 전에는 이동평균선(MA)에 대한 구현 및 매매시점 예측이라는 타이틀로 진행을 하고 있었습니다. 매매시점 예측에 대해서는 좀더 고민이 필요하다고 판단되어, 이동평균선(MA)의 구현만 우선 마무리하고 나머지는 이후에 기회가 되면 추가로 정리해 보도록 하겠습니다.

 

제가 오랜시간 글을 올리지 못했는데... 그 사유는 따로 언급은 하지 않도록 하겠습니다. 건강상의 문제도 있었고, 개인적으로도 너무 많은일이 있었습니다. 이제는 어느정도 정리가 되어 꼭 매일 올린다고 할 수는 없지만 자주 올려보도록 하겠습니다. 

이번에 구현해 보고자 하는 부분은 MACD 지표에 대한 구현 및 매매시점 예측입니다. 아무래도 MACD에 대한 방식은 사용하는 지표가 상대적으로 적기 때문에, 실험을 통해서 매매시점의 최적화를 하기에는 좀 더 빠른 판단하기가 쉽습니다. 이번에 진행하는 타이틀은 아래의 단계로 진행해 보겠습니다.

 

  • MACD에 대한 정의 및 구현
  • 구현된 결과에 대한 정합성 확인
  • MACD를 활용한 매매기법 확인 및 적용
  • 매매기법 별 시뮬레이션 및 실험실
  • 향상된 이동평균산정 법칙 적용 및 실험실

 

자 그럼 첫번째 시간으로 MACD에 대한 정의 및 구현을 시작해 보겠습니다.


1. MACD란?


MACD의 약어를 풀이해 보면, Moving Average Convergence & Divergence 로써 기존에 많이 봤던 이동평균을 뜻하는 Moving Average(MA)에 대한 수렴과 확산이라는 의미를 가지고 있습니다. 눈치로 맞춰보면 MA가 들어가니 이동평균선을 가지고 만나고 멀어지는 것으로 뭔가 수치화를 하는 것인가?? 라고 생각해 볼 수 있겠습니다.
MACD는 제럴드 아펠(Gerald Appel)이라는 사람에 의해서 개발이 되었다고 합니다. 이 지표의 원리는 장기 이동평균선과 단기 이동평균선은 항상 서로 가까워졌다가(Convergence) 멀어졌다가(Divergence)를 반복하고, 이 두개의 이동평균선은 서로 교차하는 점을 항상 만들게 된다는 것을 그 시작으로 합니다.


2. MACD의 기본 지표


MACD에는 기본적으로 3가지 지표를 가지고 매매시점을 판단하게 됩니다. 첫번째는 MACD 그 자체이고, 두번째는 MACD Signal, 마지막으로는 0을 나타내는 기준선이 그것입니다. 각각의 정의는 아래와 같습니다.


MACD = MA12 (12일 이동평균선) - MA26 (26일 이동평균선)
MACD Signal = MACD자체를 가지고 MA9 (9일 이동평균선)를 구한 값
0선 =  각 지표의 양과 음의 값을 나타내는 기준선 (0의 값이 그 기준인 직선)

 

이렇게만 말하면 도데체가 MACD는 이동평균선의 차이를 수치화한 값이다... 이 정도만 이해가 되고 그게 의미하는 바를 알 수가 없습니다. 그렇다면 실제로 차트에서는 어떻게 그것이 적용되는지 확인해 보겠습니다.


3. MACD의 의미


[종목코드 : 005930, 종목명 : 삼성전자]

 

측정기간 : 2020년 11월 10일 기준으로 업무일 기준 60일 전까지의 Data

위의 그림은 삼성전자의 차트들로 2개의 차트로 구성이 되어있습니다. 그 중 위의 차트는 삼성전자의 12일 이동평균선 (MA12)을 파란색으로, 26일 이동평균선 (MA26)을 주황색으로 나타낸 표 입니다. 그리고 아래 차트는 MACD를 나타낸 표 입니다. 0선도 같이 잘 보이네요.

그림에서 (1) 번을 살표보겠습니다. (1)은 MACD가 음수에서 양수에서 변하는 지점이고, 26일선을 12일선이 상향 돌파하는 지점입니다. 이것을 흔히 골든크로스(Golden Cross)라고 하며, 주가상승의 매수신호도 판단할 수 있습니다. 

그렇다면 (2) 번에서는... MACD가 양수에서 음수로 변하는 지점이고, 26일선을 12일선이 하향 돌파하고 있습니다. 이것을 우리는 데드크로스(Dead Cross)라고 하고, 주가하락의 신호로 판단할 수 있습니다. 바로 이것이 MACD의 의미입니다. 


4. MACD와 MACD Signal의 관계


[종목코드 : 005930, 종목명 : 삼성전자]


측정기간 : 2020년 11월 10일 기준으로 업무일 기준 60일 전까지의 Data 

위의 그림은 아까와 동일한 그림입니다. 변경된 내용은 아래 차트에 주황색으로 MACD Signal 선이 추가되었습니다.

 

자 그렇다면, MACD와 Signal선이 크로스 되는 지점을 살펴보겠습니다... (1) 번은 MACD선이 MACD Signal 선을 상향 돌파하는 지점입니다. 이를 골든크로스라고 하며, 이것의 의미는... 곧 있으면 26일선을 12일선이 상향돌파 할 가능성이 보인다는 의미입니다. 이는 곧 주가상승의 매수신호로 판단이 가능하겠죠.

그럼 (2) 번에서는 반대로... MACD선이 MACD Signal 선을 하향 돌파하는 지점입니다. 이를 데드크로스라고 하며, 이것의 의미는... 곧 있으면 26일선을 12일선이 하향돌파 할 가능성이 보인다는 의미입니다. 하지만 그림에서 보면 하향돌파는 하지 않지만 약간의 감소추세는 있었습니다. 역시나 확률이고, 그럴 가능성이 더 크다는 것이지 반드시 그렇다는 것은 아니라는 점은 꼭 명심하셔야 합니다.


5. MACD와 관련 지표 구현


그렇다면 이제... 이 로직을 프로그램으로 적용해 보고자 합니다. 바로 전에, 이동평균선(MA)에 대한 구현 및 매매시점 예측이라는 타이틀로는 각종 Moving Average에 대해서 DataFrame을 통해서 구현하고, 그 값을 DB에 저장하였습니다. 

이번에는 MACD와 MACD Signal 항목을 추가하여 그 DB에 저장해 보도록 하겠습니다. 기존에 이동평균선들을 구해서 해당 종목의 DB에 저장하는 방법은 이전글들을 참조부탁드리고, 이번에는 MACD와 관련지표를 위해서 추가되는 코드만 추가해 보겠습니다.

 

작성하는 단계는 아래와 같습니다.

 

(1) MA12와 MA26을 추가로 구하기

(2) MACD를 구하기 위해서 각 일별 MA12 - MA26을 구하고, 이를 DataFrame에 추가

(3) MACD Signal을 구하기 위해서 MACD에 대한 MA9를 추가로 구하기

첫번째로, 우선 MA12 (12일 이동평균선)과 MA26 (26일 이동평균선)을 기존 이동평균선 구하는 로직에서 추가를

해줍니다.

ma5 = opt10081_res_pd['finish'].rolling(5).mean()
ma10 = opt10081_res_pd['finish'].rolling(10).mean()

# 추가항목
ma12 = opt10081_res_pd['finish'].rolling(12).mean()
ma20 = opt10081_res_pd['finish'].rolling(20).mean()

# 추가항목
ma26 = opt10081_res_pd['finish'].rolling(26).mean()
ma60 = opt10081_res_pd['finish'].rolling(60).mean()
ma120 = opt10081_res_pd['finish'].rolling(120).mean()
ma240 = opt10081_res_pd['finish'].rolling(240).mean()

두번째로, MACD를 구하는 함수를 하나 만들어 줍니다.

    # ETC Func : Calc MACD
    def CalcMACD(self, ma12, ma26):
        maMACD = []
        for i in range(len(ma12)):
            if math.isnan(ma12[i]) or math.isnan(ma26[i]):
                maMACD.append(0)
            else:
                maMACD.append(ma12[i] - ma26[i])
        return maMACD[::-1]

해당 함수는 총 2개의 파라메터를 받습니다. MA12 (12일 이동평균선)과 MA26 (26일 이동평균선)을 받으면, 각 행별로 둘의 차를 구해줍니다. 여기서 주의할 점은... DataFrame에서 rolling으로 값을 구하면 데이터가 없어서 구하지 못하는 부분은 아래와 같이 nan으로 표시가 됩니다.

따라서, nan에 대한 처리를 해줘야 합니다. 그것이 바로 아래 코드이며... 이 경우 0값을 넣어줍니다.

if math.isnan(ma12[i]) or math.isnan(ma26[i]):
    maMACD.append(0)

그리고 전달받은 값을... 아래와 같이 DataFrame에 추가해줍니다.

maMACD = kd.CalcMACD(ma12, ma26)

opt10081_res_pd['maMACD'] = maMACD

 

이제 마지막 단계입니다. 세번째로는... MACD Signal을 구하기 위해서 MACD에 대한 MA9를 추가로 구현해줍니다. 이미 많이 해봤기 때문에 코드만 추가해 보도록 하겠습니다.

    # 위에서 구한 MACD의 signal MA를 구하기 위해서 dataframe에 넣고 돌리고 추가
    signal = opt10081_res_pd['maMACD'].rolling(9).mean()
    opt10081_res_pd['signal'] = signal

이렇게 하면 아래와 같이 MACD에 대한 지표가 추가되어, 해당 종목의 테이블에 착착 저장이 되게 됩니다.

 

[최종구현 테이블]

오늘은 여기까지 진행하고, 다음 시간에는 여기서 구한 MACD지표들을 가지고 실제로 증권사에서 제공하는 데이터와 일치하는지 정합성을 체크해 보도록 하겠습니다.

 

- Ayotera Lab -

댓글