For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
Multi-stock backtesting, the FIFO of buy and sell orders will be invalid
-
My strategy is simple, sell all stocks for the day and buy the next group of stocks.
This works fine when the strategy has only one stock, the log is as follows
![]]CK67SD]IJ4]0M(3I2J(9T.png](/assets/uploads/files/1643073913032-ck67sd-ij4-0m-3i2j-9t.png)However, when using multiple stocks for backtesting, the sell order executed first did not refresh the cash balance, resulting in insufficient funds when buying other stocks. It looks like the order doesn't follow the first in first out rule. the log is as follows:
How can I implement this strategy?
- Use the closing price to sell all stocks
- Use the closing price to buy the next group of stocks
-
Single stock
log
code
def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: return if order.status in [order.Completed]: if order.isbuy(): self.log('buy {} price:{}, size:{}, price*size:{}'.format(order.data._name, order.executed.price, order.executed.size, order.executed.price*order.executed.size)) elif order.issell(): self.log('sell {} price:{}, size:{}, price*size:{}'.format(order.data._name, order.executed.price, order.executed.size, order.executed.price*order.executed.size)) else: self.log('margin %s, %s, isbuy=%i' % (order.data._name, order.getstatusname(), order.isbuy())) def next(self): #print(self.datas[0].datetime[0]) print("") self.log('cash: {}'.format(self.broker.getcash())) self.log('value: {}'.format(self.broker.getvalue())) self.log('position: {}'.format(self.broker.getposition(self.data).size)) self.close() self.buy()
Multi-stock(two stock)
log
code
def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: return if order.status in [order.Completed]: if order.isbuy(): self.log('buy {} price:{}, size:{}, price*size:{}'.format(order.data._name, order.executed.price, order.executed.size, order.executed.price*order.executed.size)) elif order.issell(): self.log('sell {} price:{}, size:{}, price*size:{}'.format(order.data._name, order.executed.price, order.executed.size, order.executed.price*order.executed.size)) else: self.log('margin %s, %s, isbuy=%i' % (order.data._name, order.getstatusname(), order.isbuy())) def next(self): #print(self.datas[0].datetime[0]) print("") self.log('cash: {}'.format(self.broker.getcash())) self.log('value: {}'.format(self.broker.getvalue())) self.log('position: {}'.format(self.broker.getposition(self.data).size)) for index, d in enumerate(self.datas): self.close(data=d) for index, d in enumerate(self.datas): if self.last_buy != d: self.buy(data=d) self.last_buy = d break