Issue with PercentSizer 2020-11-11, Order Canceled/Margin/Rejected
-
On running the quick start strategy after changing the Sizer to a PercentSizer, the output I am getting is as follows :
Starting Portfolio Value: 100000.00 2020-11-10, BUY CREATE, 63.75 2020-11-11, Order Canceled/Margin/Rejected 2020-11-11, BUY CREATE, 63.40 2020-11-12, Order Canceled/Margin/Rejected Final Portfolio Value: 100000.00
What I wish to achieve is utilize all available cash for a buy or sell. In other words, buy as many shares as possible with my cash that is available.
Kindly advise if this is possible and the correct way to do it.
My code is as follows.
import datetime import backtrader as bt class TestStrategy(bt.Strategy): params = ( ('exitbars', 5), ) def log(self, txt, dt=None): dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): self.dataclose = self.datas[0].close self.order = None self.buyprice = None self.buycomm = None 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 EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.buyprice = order.executed.price self.buycomm = order.executed.comm else: # Sell self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.bar_executed = len(self) elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Canceled/Margin/Rejected') self.order = None def notify_trade(self, trade): if not trade.isclosed: return self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm)) def next(self): if self.order: return if not self.position: if self.dataclose[0] < self.dataclose[-1]: if self.dataclose[-1] < self.dataclose[-2]: self.log('BUY CREATE, %.2f' % self.dataclose[0]) self.order = self.buy() else: if len(self) >= (self.bar_executed + self.params.exitbars): self.log('SELL CREATE, %.2f' % self.dataclose[0]) self.order = self.sell() if __name__ == '__main__': cerebro = bt.Cerebro() cerebro.addstrategy(TestStrategy) data = bt.feeds.YahooFinanceData( dataname='BOMDYEING.NS', fromdate=datetime.datetime(2020, 11, 1), todate=datetime.datetime(2020, 12, 31), reverse=False) cerebro.adddata(data) cerebro.broker.setcash(100000.0) cerebro.addsizer(bt.sizers.PercentSizer, percents=100) cerebro.broker.setcommission(commission=0.001) value_start = cerebro.broker.getvalue() print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.run() print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
-
@backtrader can you kindly help me. The following also produces the same output.
cerebro.addsizer(bt.sizers.AllInSizer)
-
@rajanprabu can you kindly take a look at this ?
-
Hi @Sourav-Basu-Roy ,
I havent used Percent Sizer. But BT buys at next candle open, sizer is determined by the signal create price. You can either use
cheat-on-open
to force BT to buy at close or use less percentage. -
@rajanprabu i just checked
percents=99
works but nopercents=100
-
Yes I have just explained why that happens.. Use cheat-on-close..