재무와 차트

반응형

 

Backtrader 매개변수 설정

params = (
    ('myparam', 27),
    ('exitbars', 5),
)

 

 

Backtrader 매매단위 설정

cerebro = bt.Cerebro()
cerebro.addsizer(bt.sizers.SizerFix, stake=20)  # default sizer for strategies

stake는 한번에 매수할 단위

 

 

사용할 데이터

orcl-1995-2014.txt
0.33MB

 

 

Backtrader 매개변수, 매매단위 설정

 


# Create a Stratey
class TestStrategy(bt.Strategy):
    params = (
        ('exitbars', 5),
    )

  								""
    def next(self):
        # Simply log the closing price of the series from the reference
        self.log('Close, %.2f' % self.dataclose[0])

        # Check if an order is pending ... if yes, we cannot send a 2nd one
        if self.order:
            return

        # Check if we are in the market
        if not self.position:

            # Not yet ... we MIGHT BUY if ...
            if self.dataclose[0] < self.dataclose[-1]:
                    # current close less than previous close

                    if self.dataclose[-1] < self.dataclose[-2]:
                        # previous close less than the previous close

                        # BUY, BUY, BUY!!! (with default parameters)
                        self.log('BUY CREATE, %.2f' % self.dataclose[0])

                        # Keep track of the created order to avoid a 2nd order
                        self.order = self.buy()

        else:

            # Already in the market ... we might sell
            if len(self) >= (self.bar_executed + self.params.exitbars):
                # SELL, SELL, SELL!!! (with all possible default parameters)
                self.log('SELL CREATE, %.2f' % self.dataclose[0])

						""
    # Add a FixedSize sizer according to the stake
    cerebro.addsizer(bt.sizers.FixedSize, stake=10)

   						""

 

매개변수를 통해 self.params.exitbars를 사용하였습니다. addsizer를 통해 매매단위를 추가하여 주었습니다. 매매단위는 기본적으로 1로 설정되어 있으며 10으로 변경한 결과 수익이 10배 늘어난것을 확인할 수 있습니다.

 

 

Backtrader 매매전략 수정

앞에 사용해 왔던 3번 하락후 매수가 아닌 단순이동평균을 기준으로 매매하여 봅시다.

self.sma = bt.indicators.MovingAverageSimple(self.datas[0], period=self.params.maperiod)

 

15일 종가기준 단순이동평균선을 이용하여 매매를 진행합니다.

종가가 이동평균선보다 높아졌다면 매수(골든크로스)

종가가 이동평균선보다 낮아졌다면 매도(데드크로스)

# Create a Stratey
class TestStrategy(bt.Strategy):
    params = (
        ('maperiod', 15),
    )

    

    def __init__(self):
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close

        # To keep track of pending orders and buy price/commission
        self.order = None
        self.buyprice = None
        self.buycomm = None

        # Add a MovingAverageSimple indicator
        self.sma = bt.indicators.SimpleMovingAverage(
            self.datas[0], period=self.params.maperiod)

   								
                                ""
                                
    def next(self):
        # Simply log the closing price of the series from the reference
        self.log('Close, %.2f' % self.dataclose[0])

        # Check if an order is pending ... if yes, we cannot send a 2nd one
        if self.order:
            return

        # Check if we are in the market
        if not self.position:

            # Not yet ... we MIGHT BUY if ...
            if self.dataclose[0] > self.sma[0]:

                # BUY, BUY, BUY!!! (with all possible default parameters)
                self.log('BUY CREATE, %.2f' % self.dataclose[0])

                # Keep track of the created order to avoid a 2nd order
                self.order = self.buy()

        else:

            if self.dataclose[0] < self.sma[0]:
                # SELL, SELL, SELL!!! (with all possible default parameters)
                self.log('SELL CREATE, %.2f' % self.dataclose[0])

                # Keep track of the created order to avoid a 2nd order
                self.order = self.sell()

									
                                    ""

 

로그를 보면 24일전에 기록이 없는데 기본적으로 15일 이동평균을 활용하였기때문에 16일부터 매매가 시작됩니다.

 

 

Backtrader 그래프를 통한 매매확인

cerebro.plot()

 

아래와 같이 지표를 추가할 수 있습니다.

 def __init__(self):
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close

        # To keep track of pending orders and buy price/commission
        self.order = None
        self.buyprice = None
        self.buycomm = None

        # Add a MovingAverageSimple indicator
        self.sma = bt.indicators.SimpleMovingAverage(
            self.datas[0], period=self.params.maperiod)

        # Indicators for the plotting show
        bt.indicators.ExponentialMovingAverage(self.datas[0], period=25)
        bt.indicators.WeightedMovingAverage(self.datas[0], period=25,
                                            subplot=True)
        bt.indicators.StochasticSlow(self.datas[0])
        bt.indicators.MACDHisto(self.datas[0])
        rsi = bt.indicators.RSI(self.datas[0])
        bt.indicators.SmoothedMovingAverage(rsi, period=10)
        bt.indicators.ATR(self.datas[0], plot=False)

plot = False를 준다면 화면에 지표가 표시되지는 않습니다. 또 rsi처럼 변수에 넣어준다면 따로 화면에 표시되지 않으며 다른지표(SmootedMovingAverage)에 활용할 수 있습니다. 

또 전략은 같은데 이전과 다르게 결과가 나오는것을 볼 수 있는데 추가지표가 모두 생성된 지점부터 매매가 시작되는것을 알 수 있습니다.

 

 

Backtrader 최적화

이동평균선의 기간을 변경해가며 결과를 확인할 수 있습니다. 이때 하나의 종목에 과적화 되지 않도록 주의해야하며 여러 전략을 합쳐서 사용할 수 있습니다.

 

										""
# Create a Stratey
class TestStrategy(bt.Strategy):
    params = (
        ('maperiod', 15),
        ('printlog', False),
    )


    def __init__(self):
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close

        # To keep track of pending orders and buy price/commission
        self.order = None
        self.buyprice = None
        self.buycomm = None

        # Add a MovingAverageSimple indicator
        self.sma = bt.indicators.SimpleMovingAverage(
            self.datas[0], period=self.params.maperiod)

								""

    def stop(self):
        self.log('(MA Period %2d) Ending Value %.2f' %
                 (self.params.maperiod, self.broker.getvalue()), doprint=True)



if __name__ == '__main__':
    # Create a cerebro entity
    cerebro = bt.Cerebro()

    # Add a strategy
    strats = cerebro.optstrategy(
        TestStrategy,
        maperiod=range(10, 31))

    # Datas are in a subfolder of the samples. Need to find where the script is
    # because it could have been called from anywhere
    modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
    datapath = os.path.join(modpath, 'orcl-1995-2014.txt')
    
    
    								""

    # Run over everything
    cerebro.run(maxcpus=1)

 

cerebro.optstrategy를 통해 파라미터를 변경해 가며 최적화값을 확인해 볼 수 있습니다.

 

run 옵션에 maxcpus옵션은 cpu코어를 제어합니다.

maxcpus를 사용하지 않을시 모든 cpu사용

maxcpus=1 인경우 멀티코어 사용금지

maxcpus=2 인경우 표시된 코어수를 사용

결과를 살펴보면 18~25 구간의 이동평균선을 사용시 수익이 나는것을 확인 할 수 있습니다.

이제 다양한 데이터를 이용하여 전략을 세우고 최적화하여 자신만의 매매방법을 찾으시면 됩니다.

 

참고사이트

 

Quickstart Guide - Backtrader

Quickstart Note The data files used in the quickstart guide are updated from time to time, which means that the adjusted close changes and with it the close (and the other components). That means that the actual output may be different to what was put in t

www.backtrader.com

 

 

 

Backtrader 튜토리얼 | 데이터접근, 전략설정, 매수, 매도, 수수료설정

Backtrader는 투자전략을 세우고 과거데이터들을 통해 투자전략을 검증하기 위해 사용되는 파이썬 프레임워크 입니다. Backtrader 튜토리얼 | 설치, 기본설정, 금액설정, 데이터입력 Backtrader는 투자전

stockfinancediary.tistory.com

 

반응형