For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Multiple data feeds - different order gives different trades



  • Hi,

    I have 3 different data feeds but when I change the order of those around, my strategy gives different trades/ results. I have been able to narrow this down to the Startegy Class itself, but am not sure why this is happening.

    Can someone please help? Thanks in advance.

    import backtrader as bt
    from datetime import datetime
    from datetime import timedelta

    class maCross(bt.Strategy):
    '''
    oneplot = Force all datas to plot on the same master.
    '''
    params = (
    ('ema50', 50),
    ('ema200', 200),
    ('cci20', 20),
    ('oneplot', True)
    )

    def __init__(self):
        '''
        Create an dictionary of indicators so that we can dynamically add the
        indicators to the strategy using a loop. This mean the strategy will
        work with any number of data feeds.
        '''
        self.inds = dict()
        for i, d in enumerate(self.datas):
            self.inds[d] = dict()
            self.inds[d]['ema50'] = bt.indicators.ExponentialMovingAverage(
                d.close, period=self.params.ema50)
            self.inds[d]['ema200'] = bt.indicators.ExponentialMovingAverage(
                d.close, period=self.params.ema200)
            self.inds[d]['cci20'] = bt.indicators.CommodityChannelIndex(
                period=self.params.cci20)
            self.inds[d]['crossUp'] = bt.indicators.CrossOver(self.inds[d]['cci20'], -100)  # crossup = 1
            self.inds[d]['EMAcross'] = bt.indicators.CrossOver(self.inds[d]['ema50'], self.inds[d]['ema200'])
            self.inds[d]['crossDown'] = bt.indicators.CrossOver(self.inds[d]['cci20'], 100)  # crossdown = -1
    
            if i > 0:  # Check we are not on the first loop of data feed:
                if self.p.oneplot == True:
                    d.plotinfo.plotmaster = self.datas[0]
    
    def prenext(self):
        self.next()
    
    def next(self):
        feeds_with_data = [(i, d) for i, d in enumerate(self.datas) if len(d)]
        for i, d in feeds_with_data:
            # calculate risk/ stop price
            risk = 100  # risk = 100 dollars
            stop = 0.05  # stop 5% below close
            stop_price = self.datas[i].close[0] * (1 - stop)
    
            dt, dn = self.datetime.date(), d._name
            pos = self.getposition(d).size
            if not pos:  # no market / no orders
                if self.inds[d]['ema50'] >= self.inds[d]['ema200']:
                    if self.inds[d]['crossUp'][0] == 1:  # if CCI crosses up -100
                        if self.datas[i].close[0] - stop_price > 0:  # check if risk is acceptable/ valid
                            qty = round(risk / (self.datas[i].close[0] - stop_price), 0)  # get no. of shares to trade
                            eofthisday = self.datas[i].datetime.date()  #get current date
                            expiry = eofthisday + timedelta(days=4) #keep order active for 4 days (over weekend + public hol)
                            self.buy_bracket(data=d, limitprice=10000, price=self.datas[i].close[0],
                                             stopprice=stop_price, exectype=bt.Order.Limit, size=qty, valid=expiry)
                        else:
                            pass
                    else:
                        pass
                else:
                    pass
    
            else:
                if self.inds[d]['crossDown'][0] == -1:  # if cci crosses down 100
                    self.close(data=d)
    
    def notify_trade(self, trade):
        dt = self.data.datetime.date()
        if trade.isclosed:
            print('{} {} Closed: PnL Gross {}, Net {}'.format(
                dt,
                trade.data._name,
                round(trade.pnl, 2),
                round(trade.pnlcomm, 2)))
    

    datalist = [
    ('data_adjusted/CBA.AX.csv', 'CBA.AX'),
    ('data_adjusted/CSL.AX.csv', 'CSL.AX'),
    ('data_adjusted/BSL.AX.csv', 'BSL.AX'),
    ]

    For example when I swap the order of CBA and BSL with each other, the trades taken are different and I get a different end result.

    Thanks again, appreciate any help available.


  • administrators

    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
    


  • @backtrader

    Apologies, I wasn't aware of that. Will definitely use it next time.

    Regarding the data feed order though, where do you think the problem is?

    Thank you.



  • @howardhh said in Multiple data feeds - different order gives different trades:

    I have 3 different data feeds but when I change the order of those around, my strategy gives different trades/ results

    This is quite ambiguous statement and figure this out without having the data is quite hard. But as a first guess assuming that the difference means that some trades are not taken - your sizing is connected to the risk and particular stock price. So it might be a cases when you don't have enough cash to buy on new signal. You may want to check if your size calculated by risk meets the rest of the cash.


  • administrators

    @ab_trader is probably right on spot.

    Let me complete the answer by asking a question:

    • How much logging do you have in your code to understand what's happening?

      Barely none. You only print the trades, but that can only inform you about things that happen and not about the things which aren't happening or about the order in which things are happening or why things aren't happening at all.

    Logging may seem tedious at first, but it will let you separate the grain from the chaff.



  • Thanks for the replies, I'll double check the code and will see what happens.


Log in to reply
 

});