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 calledfrom __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
-
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? -
Small tip: you print the size of what you buy.
Why don't you print the size of what you sell?
You
SELL
andSELL
andSELL
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.