관리 메뉴

Leo's Garage

우한 코로나 주가 관련 역추세 매매 백 테스팅 본문

파이프라인 만들기/Algo Trading

우한 코로나 주가 관련 역추세 매매 백 테스팅

LeoBehindK 2020. 1. 28. 22:46
728x90
반응형

두동간 난 KOSPI

금일 오전, 우려는 현실이 되었다. KOSPI는 중국발 우한 폐렴의 영향으로 3% 떨어지는 결과를 보여주었다. 

이전 포스팅에서 SARS 유행 당시 KOSPI 주가 지수를 확인하였다. 당시 약 28.8% 가까이 주가가 떨어지는 모습을 보여줬는데, 이번 우한 폐렴은 얼른 정상화되었으면 하는 바람이다.

 

이번 포스팅에서는 SARS 발생 당시 KOSPI 주가 데이터에 역추매 매매 알고리즘을 적용 시, 어떤 결과를 가져오는지 백테스팅해보도록 하겠다. 

역추매 매매란?

역추매 매매란 최근에 지수가 급락한 경우에 평균 회귀 성질에 따라 재 반등하는 현상을 이용하여 단기 매매하는 전략을 말한다. 쉽게 말해서 "떨어질 때, 사서 오를 때 판다" 정도로 이해하면 될 것 같다. 사실 이 경우에 예상과 빗나갈 경우 손절을 해야 하지만, 대다수에 사람들은 손절이 쉽지 않다.

간단하게 구현하기 위하여, 아래와 같은 조건으로 구성하였다.

  • 기간 : 2002년 11월 1일 ~ 2003년 12월 31일 (SARS 발생일 포함)
  • 조건 : 
    1. BUY : SMA(20) < 전일종가
    2. SELL : SMA(20) > 전일종가
  • 대상 : KOSPI 지수
  • 시작금액 : 1,000,000원
import datetime
import backtrader as bt

#Create a subclass to define the indicators and Logic
class Momentum(bt.Strategy):
    #list of parameters which are configurable for the strategy
    params = dict(
        pfast = 5, # period for the fast moving average
        pslow = 20  # period for the slow moving average
    )

    def __init__(self):
        self.dataclose = self.datas[0].close
        self.smaSlow = bt.ind.SimpleMovingAverage(period=self.p.pslow)
        self.smaFast = bt.ind.SimpleMovingAverage(period=self.p.pfast)
        self.order = None

    def log(self,txt, dt=None):
        ''' Logging function for this strategy'''
        dt = dt or self.datas[0].datetime.date(0)
        print('%s,%s' % (dt.isoformat(), txt))

    def notify_order(self, order):
        # 1. If order is submitted/accepted, do nothing
        if order.status in [order.Submitted, order.Accepted]:
            return
        # 2. If order is buy/sell executed, report price executed
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log('BUY EXECUTED, Price: {0:8.2f} Cost : {2:8.2f}, Comm: {3:8.2f}'.format(
                    order.executed.price,
                    order.executed.size,
                    order.executed.value,
                    order.executed.comm
                ))

                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
            else :
                self.log('SELL EXECUTED. Price: {0:8.2f} Cost : {2:8.2f}, Comm: {3:8.2f}'.format(
                    order.executed.price,
                    order.executed.size,
                    order.executed.value,
                    order.executed.comm
                ))
                self.bar_executed = len(self) # when was trade executed
            # 3. If order is canceled/margin/rejected, report order canceled
        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Order Canceled/Margin/Rejected')
        self.order = None

    def next(self):
        cash = self.broker.get_cash()
        value = self.broker.get_value()
        size = int(cash / self.data.close[0])
        if self.order :
            return

        if not self.position: # not in the market
            if self.smaSlow > self.data.close[0]:
                self.order = self.buy(size=size)

        elif self.getposition().size > 0: # in the market
            if self.smaSlow < self.data.close[0]:
                self.order = self.sell(size=self.getposition().size)

def run(args=None):
    cerebro = bt.Cerebro() # create a "Cerebro" engine instance
    cerebro.broker.setcash(1000000)
    data = bt.feeds.YahooFinanceData(dataname = '^KS11',
                                     fromdate = datetime.datetime(2002,11,1),
                                     todate = datetime.datetime(2003,12,31))
    cerebro.adddata(data)
    cerebro.addstrategy(Momentum)
    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
    cerebro.run()
    print('Final Portfollio Value: %.2f' % cerebro.broker.getvalue())
    cerebro.plot()

if __name__ == '__main__':
    run()

 

백테스팅 결과는 아래와 같다. 

상기 매매법으로 거래한 결과, 최종 자산은 1,112,123원이 되었다. 

 

 

위 그래프에서 초록색 화살표 지점이 BUY 지점, 빨간색 화살표 지점이 SELL 지점이다.

사실 역추매 매매의 경우, 단기 매매에 사용하는 기법이라 SMA(20)과 같은 이평선을 가지고 매매하지는 않는다고 들었다. 보통 단기 반등을 노리는 매매법이라 길어도 일주일 내에 결과를 보는 방법이라고 하니 참고하시길 바란다. 

 

 

 

베베숲 저자극 센시티브 엠보싱 물티슈 캡형, 80매, 10팩

파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음

728x90
반응형
Comments