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

Problem with multiple stocks.



  • Hi, I am new at Backtrader.
    I have two stocks and use a simple algorithm in the long position
    If I buy and sell in that order
    self.buy(first_stock)
    self.sell(first_stock)
    self.buy(second_stock)
    self.sell(second_stock)

    The code works correctly and after each sell operation notify_trade(self, trade) function is called and print profit etc.
    I have problem,when this situation happens
    self.buy(first_stock)
    self.buy(second_stock)
    self.sell(first_stock)
    self.sell(second_stock)
    In this situation notify_trade(self, trade) function is not called

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    
    import datetime  # For datetime objects
    import os 
    
    
    # Import the backtrader platform
    import backtrader as bt
    import numpy as np
    
    # Create a Stratey
    class TestStrategy(bt.Strategy):
        params = (
            ('maperiod', 10),
            ('oneplot', True),
            #('order_pct', round(0.95/len(self.datas),2)),
        )
    
        def log(self, txt, dt=None):
            ''' Logging function fot this strategy'''
            dt = dt or self.datas[0].datetime.date(0)
            print('%s, %s' % (dt.isoformat(), txt))
    
        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
            
            self.buy_price = [1,1]
            self.entry = None
            self.sum = 0
            self.pos = [None, None]
            self.trading = False
            self.lose = 0
            
            self.order_pct = round(0.95/len(self.datas),2)
            
            # self.number_stake = 100
            # Add a MovingAverageSimple indicator
            self.sma = []
            
            for i, d in enumerate(self.datas):
                self.sma.append(bt.indicators.SimpleMovingAverage(
                    self.datas[i], period=self.params.maperiod))    
                    
        def next(self):
            for i, d in enumerate(self.datas):
                #self.log('{}, {}'.format(d._name, self.buy_price[i]))
                dt, dn = self.datetime.date(), d._name
                pos = self.getposition(d).size
                 
                day_close = d.close[0]
                date = d.datetime.date
                symbol = d._name
                
                if self.order:
                    return
    
                if not pos:
                    if (day_close > self.sma[i][0]) :
    
                        # BUY, BUY, BUY!!! (with all possible default parameters)
                        diff = ((day_close/self.sma[i][0])-1)*100
                        
                        self.log("BUY CREATE {} in long , {}, SMA: {}".format(
                                  d._name,
                                  day_close, 
                                  self.sma[i][0]))
                        
                        # Keep track of the created order to avoid a 2nd order
                        amount_to_invest = (self.order_pct * self.broker.cash)
                        self.size = amount_to_invest // day_close
    
                        self.order = self.buy(data=d, exectype=bt.Order.Close, size=self.size)
    
                        self.buy_price[i] = day_close
    
                        self.log(('Number of stocks: {}').format(self.size))
    
                else:
                    if ((day_close > self.buy_price[i] * 1.06) or
                        (day_close < self.buy_price[i] * 0.97)) :
                        # SELL, SELL, SELL!!! (with all possible default parameters)
                        
                        self.log('SELL CREATE %s in long, %.2f, SMA: %.2f, DIFF: %.2f' % 
                                 (d._name,
                                  day_close, 
                                  self.sma[i][0], 
                                  ( (day_close/self.buy_price[i])-1)*100 ))
    
                        # Keep track of the created order to avoid a 2nd order
                        self.order = self.sell(data=d, exectype=bt.Order.Close, size=self.size)
                        self.buy_price[i] = 1
                            
                        
        def notify_order(self, order):
            if order.status in [order.Submitted, order.Accepted]:
                # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                return
    
            # Check if an order has been completed
            # Attention: broker could reject order if not enough cash
            if order.status in [order.Completed]:
                # order.executed.value = order.executed.price * self.p.stake
                if order.isbuy():
                    self.log(
                        'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                        (order.executed.price,
                         order.executed.price * self.size,
                         order.executed.comm))
    
                    self.buyprice = order.executed.price
                    self.buycomm = order.executed.comm
                else:  # Sell
                    self.log('SELL EXECUTED, Price: %.2f, Profit %.2f, Comm %.2f' %
                             (order.executed.price,
                              #order.executed.value,
                              order.executed.price * self.size,
                              order.executed.comm))
    
                self.bar_executed = len(self)
            elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                self.log('Order Canceled/Margin/Rejected')
    
            # Write down: no pending order
            self.order = None
    
        def notify_trade(self, trade):
            if not trade.isclosed:
                return
            
            self.sum+=trade.pnlcomm
            
            
            self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f, SUM %.2f' %
                     (trade.pnl, trade.pnlcomm, self.sum))
            
        def notify_cashvalue(self,cash, value):
            for i in self.buy_price:
                if i != 1 or self.trading:
                    self.log('Cash %.2f, Value %.2f' % (cash, value))
    
    
    if __name__ == '__main__':
        
        def read_data(file_name):    
            datapath = os.path.abspath(os.getcwd() + '/datas/' + file_name)
            return bt.feeds.YahooFinanceCSVData(
                    dataname=datapath,
                    # Do not pass values before this date
                    fromdate=datetime.datetime(2016, 2, 1),
                    # Do not pass values before this date
                    todate=datetime.datetime(2016, 3, 1),
                    # Do not pass values after this date
                    reverse=False)
        
            
        # Create a cerebro entity
        cerebro = bt.Cerebro()
    
            
        # Add a strategy
        strategy = TestStrategy
        cerebro.addstrategy(strategy)
    
        # Datas are in a subfolder of the samples. Need to find where the script is
        # because it could have been called from anywhere
    
        data0 = read_data('labu.csv')
        data1 = read_data('TQQQ.csv')
        data2 = read_data('SOXL.csv')
        
        # Add the Data Feed to Cerebro
        cerebro.adddata(data0, name='LABU')
        
        data1.plotinfo.plotmaster = data0
        cerebro.adddata(data1, name='TQQQ')
    
    #     data2.plotinfo.plotmaster = data0
    #     cerebro.adddata(data2, name='data2')
    
        #cerebro.addobserver(bt.observers.DrawDown)
        #cerebro.adddata(get_data(datapath0))
        # Set our desired cash start
        cerebro.broker.setcash(100000.0)
    
        # Add a FixedSize sizer according to the stake
        cerebro.addsizer(bt.sizers.FixedSize)
    
        # Set the commission
        cerebro.broker.setcommission(commission=0.00)
    
        start_value = cerebro.broker.getvalue()
        # Run over everything
        results = cerebro.run()
        strat = results[0]
    
        # Print out the starting conditions
        print('Start capital: %.2f' % start_value)
        # Print out the final result
        print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
        
    
    

    Output:

    2016-02-17, SELL CREATE labu in long, 28.60, SMA: 24.13, DIFF: 12.60
    2016-02-18, SELL EXECUTED, Price: 25.68, Profit 47508.00, Comm 0.00
    2016-02-18, OPERATION PROFIT, GROSS -5402.00, NET -5402.00, SUM -5402.00
    2016-02-18, BUY CREATE 0 in long , 25.68, SMA: 24.016
    2016-02-18, Number of stocks: 1731.0
    2016-02-19, BUY EXECUTED, Price: 26.96, Cost: 46667.76, Comm 0.00
    2016-02-19, Cash 47930.24, Value 94598.00
    2016-02-19, BUY CREATE 1 in long , 13.8, SMA: 12.718
    2016-02-19, Number of stocks: 1632.0
    2016-02-22, BUY EXECUTED, Price: 14.45, Cost: 23582.40, Comm 0.00
    2016-02-22, Cash 24347.84, Value 96052.04
    2016-02-22, Cash 24347.84, Value 96052.04
    2016-02-22, SELL CREATE labu in long, 27.80, SMA: 24.14, DIFF: 8.26
    2016-02-23, SELL EXECUTED, Price: 24.20, Profit 39494.40, Comm 0.00
    2016-02-23, Cash 63842.24, Value 88645.40
    2016-02-23, SELL CREATE labu in long, 24.20, SMA: 24.47, DIFF: 2320.00
    2016-02-24, SELL EXECUTED, Price: 24.76, Profit 40408.32, Comm 0.00
    2016-02-24, OPERATION PROFIT, GROSS -4722.12, NET -4722.12, SUM -10124.12
    2016-02-24, Cash 104250.56, Value 89369.96
    2016-02-24, SELL CREATE labu in long, 24.76, SMA: 24.83, DIFF: 2376.00
    2016-02-25, SELL EXECUTED, Price: 24.24, Profit 39559.68, Comm 0.00
    2016-02-25, Cash 143810.24, Value 90787.28
    2016-02-25, SELL CREATE labu in long, 24.24, SMA: 25.12, DIFF: 2324.00
    2016-02-26, SELL EXECUTED, Price: 25.52, Profit 41648.64, Comm 0.00
    2016-02-26, Cash 185458.88, Value 86687.12
    2016-02-26, SELL CREATE labu in long, 25.52, SMA: 25.59, DIFF: 2452.00
    2016-02-29, SELL EXECUTED, Price: 23.52, Profit 38384.64, Comm 0.00
    2016-02-29, Cash 223843.52, Value 95660.96
    2016-02-29, SELL CREATE labu in long, 23.52, SMA: 25.67, DIFF: 2252.00
    

  • administrators

    After the trade in your log is closed

    @sasha said in Problem with multiple stocks.:

    2016-02-24, OPERATION PROFIT, GROSS -4722.12, NET -4722.12, SUM -10124.12
    

    you only have SELL orders. How do you expect a trade to be closed if you don't buy what you have sold?



  • @backtrader said in Problem with multiple stocks.:

    you only have SELL orders. How do you expect a trade to be closed if you don't buy what you have sold?
    Sorry, output was not correct.
    Correct output:

    2016-02-16, BUY CREATE LABU in long , 25.4, SMA: 23.916
    2016-02-16, Number of stocks: 1850.0
    2016-02-17, BUY EXECUTED, Price: 28.60, Cost: 52910.00, Comm 0.00
    2016-02-17, Cash 47090.00, Value 100000.00
    2016-02-17, SELL CREATE LABU in long, 28.60, SMA: 24.13, DIFF: 12.60
    2016-02-18, SELL EXECUTED, Price: 25.68, Profit 47508.00, Comm 0.00
    2016-02-18, OPERATION PROFIT, GROSS -5402.00, NET -5402.00, SUM -5402.00
    2016-02-18, BUY CREATE LABU in long , 25.68, SMA: 24.016
    2016-02-18, Number of stocks: 1731.0
    2016-02-19, BUY EXECUTED, Price: 26.96, Cost: 46667.76, Comm 0.00
    2016-02-19, Cash 47930.24, Value 94598.00
    2016-02-19, BUY CREATE TQQQ in long , 13.8, SMA: 12.718
    2016-02-19, Number of stocks: 1632.0
    2016-02-22, BUY EXECUTED, Price: 14.45, Cost: 23582.40, Comm 0.00
    2016-02-22, Cash 24347.84, Value 96052.04
    2016-02-22, Cash 24347.84, Value 96052.04
    2016-02-22, SELL CREATE LABU in long, 27.80, SMA: 24.14, DIFF: 8.26
    2016-02-23, SELL EXECUTED, Price: 24.20, Profit 39494.40, Comm 0.00
    2016-02-23, Cash 63842.24, Value 88645.40
    2016-02-23, SELL CREATE LABU in long, 24.20, SMA: 24.47, DIFF: 2320.00
    2016-02-24, SELL EXECUTED, Price: 24.76, Profit 40408.32, Comm 0.00
    2016-02-24, OPERATION PROFIT, GROSS -4722.12, NET -4722.12, SUM -10124.12
    2016-02-24, Cash 104250.56, Value 89369.96
    2016-02-24, SELL CREATE LABU in long, 24.76, SMA: 24.83, DIFF: 2376.00
    2016-02-25, SELL EXECUTED, Price: 24.24, Profit 39559.68, Comm 0.00
    2016-02-25, Cash 143810.24, Value 90787.28
    2016-02-25, SELL CREATE LABU in long, 24.24, SMA: 25.12, DIFF: 2324.00
    2016-02-26, SELL EXECUTED, Price: 25.52, Profit 41648.64, Comm 0.00
    2016-02-26, Cash 185458.88, Value 86687.12
    2016-02-26, SELL CREATE LABU in long, 25.52, SMA: 25.59, DIFF: 2452.00
    2016-02-29, SELL EXECUTED, Price: 23.52, Profit 38384.64, Comm 0.00
    2016-02-29, Cash 223843.52, Value 95660.96
    2016-02-29, SELL CREATE LABU in long, 23.52, SMA: 25.67, DIFF: 2252.00
    Start capital: 100000.00
    Final Portfolio Value: 95660.96
    
    

    I have both buy and sell orders.
    This code will work correctly if I use only one stock. If I use for several stocks, there is a problem with sell orders. Above it can be seen that until the stock TQQQ occurs, the LABU is trading successfully. When two stocks are combined, an error occurs.
    I realized that after the SELL the trade does not close, I can not understand why it is re-executed. What do I need to fix in the code?


  • administrators

    Small tip: you print the size of what you buy.

    Why don't you print the size of what you sell?

    You SELL and SELL and SELL and given that your expectation is that the trade will be closed, you are (obviously) apparently not selling the same size that you are buying.



  • @backtrader Thanks. You helped me a lot

    ----------------------------------------
    2016-02-16, BUY CREATE LABU in long , 25.4, SMA: 23.916
    2016-02-16, Number of stocks: 1850.0
    2016-02-17, BUY EXECUTED, Price: 28.60, Cost: 52910.00, Comm 0.00
    2016-02-17, Cash 47090.00, Value 100000.00
    ----------------------------------------
    2016-02-17, SELL CREATE LABU in long, 28.60, SMA: 24.13, DIFF: 12.60
    2016-02-17, Number of stocks 1850.00
    2016-02-18, SELL EXECUTED, Price: 25.68, Profit 47508.00, Comm 0.00
    2016-02-18, OPERATION PROFIT, GROSS -5402.00, NET -5402.00, SUM -5402.00
    ----------------------------------------
    2016-02-18, BUY CREATE LABU in long , 25.68, SMA: 24.016
    2016-02-18, Number of stocks: 1731.0
    2016-02-19, BUY EXECUTED, Price: 26.96, Cost: 46667.76, Comm 0.00
    2016-02-19, Cash 47930.24, Value 94598.00
    ----------------------------------------
    2016-02-19, BUY CREATE TQQQ in long , 13.8, SMA: 12.718
    2016-02-19, Number of stocks: 1632.0
    2016-02-22, BUY EXECUTED, Price: 14.45, Cost: 23582.40, Comm 0.00
    2016-02-22, Cash 24347.84, Value 96052.04
    2016-02-22, Cash 24347.84, Value 96052.04
    ----------------------------------------
    2016-02-22, SELL CREATE LABU in long, 27.80, SMA: 24.14, DIFF: 8.26
    2016-02-22, Number of stocks 1632.00
    2016-02-23, SELL EXECUTED, Price: 24.20, Profit 39494.40, Comm 0.00
    2016-02-23, Cash 63842.24, Value 88645.40
    ----------------------------------------
    2016-02-23, SELL CREATE LABU in long, 24.20, SMA: 24.47, DIFF: 2320.00
    2016-02-23, Number of stocks 1632.00
    2016-02-24, SELL EXECUTED, Price: 24.76, Profit 40408.32, Comm 0.00
    2016-02-24, OPERATION PROFIT, GROSS -4722.12, NET -4722.12, SUM -10124.12
    2016-02-24, Cash 104250.56, Value 89369.96
    

    The problem was with the size of stocks.


Log in to reply
 

});