중년 플머 김씨 2020. 11. 8. 00:14

소스파일은 github.com/galaxywiz/StockCrawler_py 에서 확인 가능합니다.

 

MACD(Moving Average Convergence & Divergence) 약자이며, 이동 평균선들 간의 수렴 확산을 보기 좋게 나타낸 지표입니다.

각각의 이동평균선은 확산(Divergence)와 수렴(Convergence)하는 성질을 이용한 매매 지표로, 시간이 흐름에 따라 이동평균선들의 수렴, 확산하는 시기를 포착하여 매수 / 매도 포지션을 취하는 방식입니다.

보통 EMA 9, 12, 26일 이동평균선을 사용합니다.


MACD
선은 EMA12– EMA26일 값이고, 시그널선은 EMA9 선을 사용하며, 오실레이트 값은 MACD선과 시그널선의 차로 계산해서 그래프상 보기 좋은 용도로 사용합니다.

 

일반적으로 MACD가 시그널을 상향 돌파하면 골든 크로스로 판단하여 매수하고,
반대로 하양돌파 하면, 데드 크로스로 판단하여 매도하는 전략입니다.

 

아래 차트는 이 전략을 사용해서 뽑아낸 차트입니다. 실제 hts 앱의 주식 차트 지표와 비교했을 때 같은 결과임을 알 수 있습니다.

[2020-10-30][롯데케미칼]
[MACDStrategy] long(
매수) 신호가 잡혔을 때 차트입니다.

#//---------------------------------------------------//
class MACDTradeStrategy(TradeStrategy):
    TERM = 1
    def __buySignal(self, timeIdx):
        if timeIdx < self.TERM:
            return False
            
        chartData = self.stockData_.chartData_
        prevCandle = chartData.iloc[timeIdx - 1]
        macd = prevCandle["MACD"]
        signal = prevCandle["MACDSignal"]
        if macd > signal:
            nowCandle = chartData.iloc[timeIdx]
            macd = nowCandle["MACD"]
            signal = nowCandle["MACDSignal"]

            if macd < signal:
                return True

        return False

    def __sellSignal(self, timeIdx):
        if timeIdx < 1:
            return False
            
        chartData = self.stockData_.chartData_
        prevCandle = chartData.iloc[timeIdx - 1]
        macd = prevCandle["MACD"]
        signal = prevCandle["MACDSignal"]
        if macd < signal:
            nowCandle = chartData.iloc[timeIdx]
            macd = nowCandle["MACD"]
            signal = nowCandle["MACDSignal"]

            if macd > signal:
                return True

        return False

    def buy(self, timeIdx):
        chartData = self.stockData_.chartData_
        if len(chartData) <= self.TERM:
            return False

        if self.stockData_.position_ == BuyState.STAY:
            if self.__buySignal(timeIdx):
                return True
        return False

    def sell(self, timeIdx):
        chartData = self.stockData_.chartData_
        if len(chartData) <= self.TERM:
            return False

        if self.stockData_.position_ == BuyState.STAY:
            if self.__sellSignal(timeIdx):
                return True
        return False

    def buyList(self):
        signalList = []
        for i in range(0, self.TERM):
            signalList.append(np.nan)
        
        chartData = self.stockData_.chartData_

        for i in range(self.TERM, len(chartData)):
            nowCandle = chartData.iloc[i]
            if self.__buySignal(i):
                signalList.append(nowCandle["close"])
            else:
                signalList.append(np.nan)

        return signalList

    def sellList(self):
        signalList = []
        for i in range(0, self.TERM):
            signalList.append(np.nan)
        
        chartData = self.stockData_.chartData_

        for i in range(self.TERM, len(chartData)):
            nowCandle = chartData.iloc[i]
            if self.__sellSignal(i):
                signalList.append(nowCandle["close"])
            else:
                signalList.append(np.nan)

        return signalList

 

 

코드를 읽어 보시면 이전의 골든 크로스 코드랑 많이 비슷하게 느껴 지실 겁니다. 골든 크로스는 2개의 EMA값을 크로스 하냐 마냐로 판단하고, MACD역시 MACD랑 시그널의 크로스를 하냐 마냐로 판단하기 때문에 코드가 유사하게 작성됩니다.