For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
Help with limit orders- (getting executed at market prices)
-
Hi,My limit orders keep getting executed at market prices. Will be a great help if someone can help me find what i am doing wrong here
class TestStrategy(bt.Strategy): params = ( ('maperiod', 2), ) def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.datetime(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 # Add a MovingAverageSimple indicator self.sma = bt.indicators.SimpleMovingAverage(self.datas[0], period=self.params.maperiod) 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 self.position.size ==0: if self.dataclose[0] > self.sma[0]: self.order = self.buy(price=6000.00,exec=bt.Order.Limit) if __name__ == '__main__': cerebro = bt.Cerebro() cerebro.addstrategy(TestStrategy) data = bt.feeds.PandasData(dataname=dataframe) cerebro.adddata(data) cerebro.broker.setcash(100000) cerebro.broker.setcommission(commission=0.00025) print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.run() print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
-
Please provide some logs and a glimpse on the relevant data from your dataframe (could it be that the market prices are well below 6000.00 ? )
-
Hi @vladisld ,
Starting Portfolio Value: 100000.00 2020-04-07T06:12:00, BUY EXECUTED, Price: 7277.00, Cost: 7277.00, Comm 1.82 Final Portfolio Value: 99901.68
-
Code to try this in Google colab / jupyter note book
!pip install backtrader[plotting] import requests import pandas as pd import backtrader as bt import backtrader.feeds as btfeeds import datetime response=requests.get('https://www.bitmex.com/api/v1/trade/bucketed?binSize=1m&partial=false&symbol=XBTUSD&count=1000&reverse=false&startTime=2020-04-07T06:09:48') a=response.text dataframe=pd.read_json(a) dataframe['datetime']=pd.to_datetime(dataframe['timestamp'],unit='ms') dataframe.set_index('datetime',inplace=True) class TestStrategy(bt.Strategy): params = ( ('maperiod', 2), ) def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.datetime(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 # Add a MovingAverageSimple indicator self.sma = bt.indicators.SimpleMovingAverage(self.datas[0], period=self.params.maperiod) 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 self.position.size ==0: if self.dataclose[0] > self.sma[0]: self.order = self.buy(price=6000.00,exec=bt.Order.Limit) if __name__ == '__main__': cerebro = bt.Cerebro() cerebro.addstrategy(TestStrategy) data = bt.feeds.PandasData(dataname=dataframe) cerebro.adddata(data) cerebro.broker.setcash(100000) cerebro.broker.setcommission(commission=0.00025) print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.run() print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
-
@Akshay said in Help with limit orders- (getting executed at market prices):
self.order = self.buy(price=6000.00,exec=bt.Order.Limit)
Please try to use the
exectype
argument forbuy
method instead ofexec
(it was probably a typo)self.order = self.buy(price=6000.00,exectype=bt.Order.Limit)
-
@vladisld Thanks a lot, that worked!