캡스톤

SMA 전략

코블리_vv 2021. 9. 13. 17:48
728x90
반응형

SMA (Simple Moving Average, 단순 이동평균)

 

전략

  • 주어진 n일 동안의 종가를 모두 합해 n으로 나눈 값
  • 최근 데이터를 넣어 평균을 구함
  • 단기 이동 평균선이 장기 이동 평균선을 상향 돌파 시 매수 (골든 크로스 오버)
  • 단기 이동 평균선이 장기 이동 평균선을 하향 돌파 시 매도 (데쓰 크로스 오버)
  • 서로 교차하는 지점을 매매 시점으로 한다.

특징

  • 단순 이동 지평선이 내려가고 있다면 현재 가격이 내려간다는 뜻
  • 단순 이동 지평선이 올라가고 있다면 현재 가격이 올라가고 있다는 뜻

장점

  • n일 간의 평균값을 보여주기 때문에 시장의 변동성을 부드럽게 해 주고 추세를 쉽게 판단할 수 있다.
  • 긴 기간의 이동 지평선은 더 부드럽고 느리게 가격 표시해주고 짧은 기간의 이동 지평선은 변동성을 보인다.

단점

  • 짧은 기간의 가격 변동(노이즈)에 취약하다.
  • 추세가 전개되고 있다고 나오지만 실제로는 큰 변화가 없을 수도 있다.
  • 과거에 큰 가격 변동이 있고 현재는 가격변동이 없더라도 평균 값에서는 가격변동이 있는 것처럼 보일 수 있다.
    (최근에 입력된 데이터와 오래된 데이터가  동일하게 계산돼서 생기는 문제)
  • 최신 데이터 관련성이 높다고 생각하는 트레이더들은 SMA가 해가 된다고 생각한다.

코드

backtrader 함수를 이용하여 코드로 구현

## SMA
from datetime import datetime
import backtrader as bt

class SmaCross(bt.Strategy):
    params = dict(
        pfast=10,  # period for the fast moving average
        pslow=30   # period for the slow moving average
    )

    # 초기화 메서드
    def __init__(self):
        sma1 = bt.ind.SMA(period=self.p.pfast)  # fast moving average
        sma2 = bt.ind.SMA(period=self.p.pslow)  # slow moving average
        self.crossover = bt.ind.CrossOver(sma1, sma2)  # crossover signal

    def next(self):
        if not self.position:  # 아직 주식을 사지 않았을 때
            if self.crossover > 0:  # 단기 이동 평균선이 장기 이동 평균선을 상향 돌파시 매수
                self.buy()

        elif self.crossover < 0:  # 단기 이동 평균선이 장기 이동 평균선을 하향 돌파시 매도
            self.close()

# cerebro 가져오기
cerebro = bt.Cerebro()

# 야후 금융 데이터 불러오기
data = bt.feeds.YahooFinanceData(dataname='036570.KS',
                                 fromdate=datetime(2017, 1, 1),
                                 todate=datetime(2020, 12, 31))

# 데이터 추가
cerebro.adddata(data)

#cerebro 실행
cerebro.addstrategy(SmaCross)  # 투자 전략 추가
cerebro.broker.setcash(10000000)  # 브로거 설정

# 매매 단위 설정하기
cerebro.addsizer(bt.sizers.SizerFix, stake=30) # 한번에 30주 설정

# 초기 투자금
init_cash = cerebro.broker.getvalue()
cerebro.run()

# 최종 금액
final_cash = cerebro.broker.getvalue()

print("최종 금액 : ", final_cash, "\\")
print("수익률 : ", float(final_cash - init_cash) / float(init_cash) *100., "%")

cerebro.plot()

728x90
반응형