본문 바로가기
AyoProject/Ayotera-Trade

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

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

이번에는 지난 시간에 구현한 MACD와 MACD Signal의 Cross 상태를 자동으로 찍어준 결과에 대해서 12가지 조건에 대해서 기간별로 실제 발생이 가능한 수익에 대해서 백테스팅(Back Testing)을 수행해 보겠습니다. 이 시뮬레이션으로 아마 가장 SMA (Single Moving Average)를 통해서 구현한 MACD로 최적의 구현 식이 어떤 것이지를 확인 할 수 있을 것 입니다.

 

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

 

우선 백테스팅(Back Testing)을 위한 프로그램을 만들고, Parameter를 조정하면서 결과를 확인해 보겠습니다.

 

 

1. 백테스팅(Back Testing) 프로그램


바로전에 우리는 아래의 조건에 대해서 고려하였습니다. 따라서, 이 조건들을 변수로 빼서 값을 수정하면 코드의 수정이 없이 바로 확인가능하도록 구성하겠습니다.

 

  • MACD와 MACD Signal의 Cross(교차, 만난는 점) 여부
  • MACD가 0선에 위에 있는지... 아래 있는지 여부
  • 매매시점을 시초가로 할지 종가로 할지 여무

 

제가 선정한 Parameter는 아래와 같습니다.

# chk**Price 1은 시초가, 4는 종가
chkBuyPrice = 4
chkSellPrice = 4
# zeroLine -1은 미만, 0을 상관없고, 1은 이상
zeroLine = -1

사실 GC (Golden Cross)와 DC (Dead Cross)는 코드내에서 매수와 매도를 위한 기준이기 때문에 따로 변수로 빼지않고, 나머지 2개항목만 변수로 뺐습니다. 아참!!! 그리고 DB에서 Table을 불러오기 위한 종목명은 따로 Parameter로 뺐습니다. 

(※ DB의 Table 호출 부분은 이전 글에서 자세히 확인하실 수 있어서 생략하겠습니다.)

 

그 밖에 주요한 부분은 아래와 같으며, 세부적인 내용은 코드로 확인해 보시죠~~

 

(1) 매수 혹은 매도가는 익일을 기준으로 하기 때문에 sList[i+1]로 적용하고,  

(2) for로 구현 시 가장 최근일까지 적용하면, 익일 기준의 가격이 없어 error가 발생하기 때문에 loop는 전체 길이의 -1

    즉, for i in range(len(sList)-1): 로 적용한다

def MACDTestLogic(sList):
    cntGC = 0
    cntDC = 0
    # chk**Price 1은 시초가, 4는 종가
    chkBuyPrice = 4
    chkSellPrice = 4
    # zeroLine -1은 미만, 0을 상관없고, 1은 이상
    zeroLine = -1
    totalEarn = 0
    chkBuy = 0
    chkPrice = 0
    startTime = '20200501'
    # 익일 시초가로 작업을 하기 때문에 for는 전체 길이에서 1을 뺌
    for i in range(len(sList)-1):
        if sList[i][0] >= startTime:
            if zeroLine == -1:
                # GC와 DC의 개수 추출
                if sList[i][16] == 'GC' and sList[i][15] < 0: cntGC += 1
                elif sList[i][16] == 'DC': cntDC += 1

                if chkBuy == 1 and sList[i][16] == 'DC':
                    temp = int(sList[i+1][chkSellPrice]) - chkPrice
                    totalEarn += temp
                    chkBuy = 0
                    chkPrice = 0
                    print(sList[i][0], ' 매도가 : ', sList[i+1][chkSellPrice], ', 수익 : ', temp)
                elif chkBuy == 0 and sList[i][16] == 'GC' and sList[i][15] < 0:
                    chkBuy = 1
                    chkPrice = int(sList[i+1][chkBuyPrice])
                    print(sList[i][0], ' 매수가 : ', sList[i+1][chkBuyPrice])
            elif zeroLine == 0:
                # GC와 DC의 개수 추출
                if sList[i][16] == 'GC':
                    cntGC += 1
                elif sList[i][16] == 'DC':
                    cntDC += 1

                if chkBuy == 1 and sList[i][16] == 'DC':
                    temp = int(sList[i + 1][chkSellPrice]) - chkPrice
                    totalEarn += temp
                    chkBuy = 0
                    chkPrice = 0
                    print(sList[i][0], ' 매도가 : ', sList[i + 1][chkSellPrice], ', 수익 : ', temp)
                elif chkBuy == 0 and sList[i][16] == 'GC':
                    chkBuy = 1
                    chkPrice = int(sList[i + 1][chkBuyPrice])
                    print(sList[i][0], ' 매수가 : ', sList[i + 1][chkBuyPrice])
            if zeroLine == 1:
                # GC와 DC의 개수 추출
                if sList[i][16] == 'GC' and sList[i][15] >= 0:
                    cntGC += 1
                elif sList[i][16] == 'DC':
                    cntDC += 1

                if chkBuy == 1 and sList[i][16] == 'DC':
                    temp = int(sList[i + 1][chkSellPrice]) - chkPrice
                    totalEarn += temp
                    chkBuy = 0
                    chkPrice = 0
                    print(sList[i][0], ' 매도가 : ', sList[i + 1][chkSellPrice], ', 수익 : ', temp)
                elif chkBuy == 0 and sList[i][16] == 'GC' and sList[i][15] >= 0:
                    chkBuy = 1
                    chkPrice = int(sList[i + 1][chkBuyPrice])
                    print(sList[i][0], ' 매수가 : ', sList[i + 1][chkBuyPrice])

    print('Total GC count : ', cntGC, ', Total DC count : ', cntDC)
    print('Total Earn count : ', totalEarn)

 

 

2. 각 조건 별 백테스트 수행 및 검증


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

 

측정기간 : 2020년 05월 01일 ~ 2020년 11월 12일 (약 6개월, 반기기준)

 

(1) 조건 : MACD가 0선 아래서 MACD Signal과 GC(Golden Cross)하고, 매수는 시초가, 매도는 시초가

    # chk**Price 1은 시초가, 4는 종가
    chkBuyPrice = 1
    chkSellPrice = 1
    # zeroLine -1은 미만, 0을 상관없고, 1은 이상
    zeroLine = -1
    startTime = '20200501'
==================================================

[결과]
20200527  매수가 :  51100
20200619  매도가 :  52000 , 수익 :  900
20200709  매수가 :  53100
20200814  매도가 :  58900 , 수익 :  5800
20200909  매수가 :  59900
20200929  매도가 :  57500 , 수익 :  -2400
Total GC count :  3 , Total DC count :  4
Total Earn count :  4300

(2) 조건 : MACD가 0선 아래서 MACD Signal과 GC(Golden Cross)하고, 매수는 시초가, 매도는 종가

 

    # chk**Price 1은 시초가, 4는 종가
    chkBuyPrice = 1
    chkSellPrice = 4
    # zeroLine -1은 미만, 0을 상관없고, 1은 이상
    zeroLine = -1
    startTime = '20200501'
================================================

[결과]
20200527  매수가 :  51100
20200619  매도가 :  52000 , 수익 :  900
20200709  매수가 :  53100
20200814  매도가 :  58400 , 수익 :  5300
20200909  매수가 :  59900
20200929  매도가 :  58700 , 수익 :  -1200
Total GC count :  3 , Total DC count :  4
Total Earn count :  5000

(3) 조건 : MACD가 0선 아래서 MACD Signal과 GC(Golden Cross)하고, 매수는 종가, 매도는 시초가

    # chk**Price 1은 시초가, 4는 종가
    chkBuyPrice = 4
    chkSellPrice = 1
    # zeroLine -1은 미만, 0을 상관없고, 1은 이상
    zeroLine = -1
    startTime = '20200501'
================================================

[결과]
20200527  매수가 :  50400
20200619  매도가 :  52000 , 수익 :  1600
20200709  매수가 :  52700
20200814  매도가 :  58900 , 수익 :  6200
20200909  매수가 :  59200
20200929  매도가 :  57500 , 수익 :  -1700
Total GC count :  3 , Total DC count :  4
Total Earn count :  6100

(4) 조건 : MACD가 0선 아래서 MACD Signal과 GC(Golden Cross)하고, 매수는 종가, 매도는 종가

    # chk**Price 1은 시초가, 4는 종가
    chkBuyPrice = 4
    chkSellPrice = 4
    # zeroLine -1은 미만, 0을 상관없고, 1은 이상
    zeroLine = -1
    startTime = '20200501'
================================================

[결과]
20200527  매수가 :  50400
20200619  매도가 :  52000 , 수익 :  1600
20200709  매수가 :  52700
20200814  매도가 :  58400 , 수익 :  5700
20200909  매수가 :  59200
20200929  매도가 :  58700 , 수익 :  -500
Total GC count :  3 , Total DC count :  4
Total Earn count :  6800

(5) 조건 : MACD가 0선 상관없이 MACD Signal과 GC(Golden Cross)하고, 매수는 시초가, 매도는 시초가

    # chk**Price 1은 시초가, 4는 종가
    chkBuyPrice = 1
    chkSellPrice = 1
    # zeroLine -1은 미만, 0을 상관없고, 1은 이상
    zeroLine = 0
    startTime = '20200501'
================================================

[결과]
20200527  매수가 :  51100
20200619  매도가 :  52000 , 수익 :  900
20200709  매수가 :  53100
20200814  매도가 :  58900 , 수익 :  5800
20200909  매수가 :  59900
20200929  매도가 :  57500 , 수익 :  -2400
20201020  매수가 :  61200
20201029  매도가 :  58000 , 수익 :  -3200
Total GC count :  4 , Total DC count :  4
Total Earn count :  1100

(6) 조건 : MACD가 0선 상관없이 MACD Signal과 GC(Golden Cross)하고, 매수는 시초가, 매도는 종가

    # chk**Price 1은 시초가, 4는 종가
    chkBuyPrice = 1
    chkSellPrice = 4
    # zeroLine -1은 미만, 0을 상관없고, 1은 이상
    zeroLine = 0
    startTime = '20200501'
================================================

[결과]
20200527  매수가 :  51100
20200619  매도가 :  52000 , 수익 :  900
20200709  매수가 :  53100
20200814  매도가 :  58400 , 수익 :  5300
20200909  매수가 :  59900
20200929  매도가 :  58700 , 수익 :  -1200
20201020  매수가 :  61200
20201029  매도가 :  56600 , 수익 :  -4600
Total GC count :  4 , Total DC count :  4
Total Earn count :  400

(7) 조건 : MACD가 0선 상관없이 MACD Signal과 GC(Golden Cross)하고, 매수는 종가, 매도는 시초가

    # chk**Price 1은 시초가, 4는 종가
    chkBuyPrice = 4
    chkSellPrice = 1
    # zeroLine -1은 미만, 0을 상관없고, 1은 이상
    zeroLine = 0
    startTime = '20200501'
================================================

[결과]
20200527  매수가 :  50400
20200619  매도가 :  52000 , 수익 :  1600
20200709  매수가 :  52700
20200814  매도가 :  58900 , 수익 :  6200
20200909  매수가 :  59200
20200929  매도가 :  57500 , 수익 :  -1700
20201020  매수가 :  60900
20201029  매도가 :  58000 , 수익 :  -2900
Total GC count :  4 , Total DC count :  4
Total Earn count :  3200

(8) 조건 : MACD가 0선 상관없이 MACD Signal과 GC(Golden Cross)하고, 매수는 종가, 매도는 종가

    # chk**Price 1은 시초가, 4는 종가
    chkBuyPrice = 4
    chkSellPrice = 4
    # zeroLine -1은 미만, 0을 상관없고, 1은 이상
    zeroLine = 0
    startTime = '20200501'
===============================================

[결과]
20200527  매수가 :  50400
20200619  매도가 :  52000 , 수익 :  1600
20200709  매수가 :  52700
20200814  매도가 :  58400 , 수익 :  5700
20200909  매수가 :  59200
20200929  매도가 :  58700 , 수익 :  -500
20201020  매수가 :  60900
20201029  매도가 :  56600 , 수익 :  -4300
Total GC count :  4 , Total DC count :  4
Total Earn count :  2500

(9) 조건 : MACD가 0선 위에서 MACD Signal과 GC(Golden Cross)하고, 매수는 시초가, 매도는 시초가

    # chk**Price 1은 시초가, 4는 종가
    chkBuyPrice = 1
    chkSellPrice = 1
    # zeroLine -1은 미만, 0을 상관없고, 1은 이상
    zeroLine = 1
    startTime = '20200501'
================================================

[결과]
20201020  매수가 :  61200
20201029  매도가 :  58000 , 수익 :  -3200
Total GC count :  1 , Total DC count :  4
Total Earn count :  -3200

(10) 조건 : MACD가 0선 위에서 MACD Signal과 GC(Golden Cross)하고, 매수는 시초가, 매도는 종가

    # chk**Price 1은 시초가, 4는 종가
    chkBuyPrice = 1
    chkSellPrice = 4
    # zeroLine -1은 미만, 0을 상관없고, 1은 이상
    zeroLine = 1
    startTime = '20200501'
================================================

[결과]
20201020  매수가 :  61200
20201029  매도가 :  56600 , 수익 :  -4600
Total GC count :  1 , Total DC count :  4
Total Earn count :  -4600

(11) 조건 : MACD가 0선 위에서 MACD Signal과 GC(Golden Cross)하고, 매수는 종가, 매도는 시초가

    # chk**Price 1은 시초가, 4는 종가
    chkBuyPrice = 4
    chkSellPrice = 1
    # zeroLine -1은 미만, 0을 상관없고, 1은 이상
    zeroLine = 1
    startTime = '20200501'
================================================

[결과]
20201020  매수가 :  60900
20201029  매도가 :  58000 , 수익 :  -2900
Total GC count :  1 , Total DC count :  4
Total Earn count :  -2900

(12) 조건 : MACD가 0선 위에서 MACD Signal과 GC(Golden Cross)하고, 매수는 종가, 매도는 종가

    # chk**Price 1은 시초가, 4는 종가
    chkBuyPrice = 4
    chkSellPrice = 4
    # zeroLine -1은 미만, 0을 상관없고, 1은 이상
    zeroLine = 1
    startTime = '20200501'
================================================

[결과]
20201020  매수가 :  60900
20201029  매도가 :  56600 , 수익 :  -4300
Total GC count :  1 , Total DC count :  4
Total Earn count :  -4300

 

 

3. 결과


물론 다양한 종목으로 다양한 기간으로 테스트를 해봐야겠지만, 삼성전자로 적용한 결과는 아래의 조건일때, 생각하지않고 단순 투자를 할 경우 SMA상황에서 가장 큰 수익을 얻을 수 있습니다.

 

(4) 조건 : MACD가 0선 아래서 MACD Signal과 GC(Golden Cross)하고, 매수는 종가, 매도는 종가

 

그럼 다음 시간에는 EMA를 적용해서 좀 더 나은 수익률을 얻을 수 있는 매매신호를 기대해 보겠습니다.

감사합니다.

 

- Ayotera Lab -

 

 

0. 기본 매매기법 Remind


 

[MACD를 활용한 기본 매매기법 조건 - 매수]

  조건 식 매매 유무
조건 1 - MACD가 MACD Signal을 아래서 위로 교차하고 (GC, Golden Cross)
- MACD가 0선 아래에 있고
- MA는 항상 이전일 종가를 기준으로 하기때문에, 실제 매매는 익일
  이루어 지며, 매매 기준은 시초가로 함
매수
조건 2 - MACD가 MACD Signal을 아래서 위로 교차하고 (GC, Golden Cross)
- MACD가 0선 아래에 있고
- MA는 항상 이전일 종가를 기준으로 하기때문에, 실제 매매는 익일
  이루어 지며, 매매 기준은 종가로 함
매수
조건 3 - MACD가 MACD Signal을 아래서 위로 교차하고 (GC, Golden Cross)
- MACD가 0선 위에에 있고
- MA는 항상 이전일 종가를 기준으로 하기때문에, 실제 매매는 익일
  이루어 지며, 매매 기준은 시초가로 함
매수
조건 4 - MACD가 MACD Signal을 아래서 위로 교차하고 (GC, Golden Cross)
- MACD가 0선 위에에 있고
- MA는 항상 이전일 종가를 기준으로 하기때문에, 실제 매매는 익일
  이루어 지며, 매매 기준은 종가로 함
매수
조건 5 - MACD가 MACD Signal을 아래서 위로 교차하고 (GC, Golden Cross)
- MACD가 0선 상관없이
- MA는 항상 이전일 종가를 기준으로 하기때문에, 실제 매매는 익일
  이루어 지며, 매매 기준은 시초가로 함
매수
조건 6 - MACD가 MACD Signal을 아래서 위로 교차하고 (GC, Golden Cross)
- MACD가 0선 상관없이
- MA는 항상 이전일 종가를 기준으로 하기때문에, 실제 매매는 익일
  이루어 지며, 매매 기준은 종가로 함
매수

[MACD를 활용한 기본 매매기법 조건 - 매도]

  조건 식 매매 유무
조건 1 - MACD가 MACD Signal을 위에서 아래로 교차하고 (DC, Dead Cross)
- MA는 항상 이전일 종가를 기준으로 하기때문에, 실제 매매는 익일
  이루어 지며, 매매 기준은 시초가로 함
매도
조건 2 - MACD가 MACD Signal을 위에서 아래로 교차하고 (DC, Dead Cross)
- MA는 항상 이전일 종가를 기준으로 하기때문에, 실제 매매는 익일
  이루어 지며, 매매 기준은 종가로 함
매도

 

댓글