How to make All-in Market Price in tick-chart
-
What I want to do is that in tick chart,
price : buy at market price(maybe next tick price),
size : all avaliable size(volume) in that tick, all-in my account moneyFor example,
I have money 10000, and then tick-chart looks like below.
(tick-chart)
9:5:5 volume 12, price 60
9:5:5 volume 100, price 55
9:5:6 volume 80, price 60
9:5:7 volume 67, price 65then,
I expect to buy size 12(price 60) + size 100(price 55) + size 63(price 60). (because I dont have enough money at last)But it is so hard to make such code with backtrader.
Is there any easy way of doing it?
I am beginner of Backtrader. And I am reading all the document but it is too complicated for me.
I really appreciate for your help.Below is code sample:
(I got order margin here.)def __init__(self): self.order = None self.buytime = None self.dataclose = self.datas[0].close self.dataopen = self.datas[0].open self.minvolume = self.datas[1].volume self.market_volume = self.datas[0].volume self.time = self.datas[0].datetime self.mintime = self.datas[1].datetime self.buy_continue = False self.volume_sma = bt.indicators.SimpleMovingAverage(self.datas[1].volume, period=10) def log(self, txt, dt=None): print('%s, %s' % (self.time.datetime(), txt)) 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, {} {}'.format(order.executed.price, order.executed.size)) elif order.issell(): self.log('SELL EXECUTED, {} {}'.format(order.executed.price, order.executed.size)) elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('{} {} Order Canceled/Margin/Rejected'.format(order.created.price, order.created.size)) if not order.alive: self.order = None def next(self): # Check if we are in the market if not self.order: if self.buy_continue: if self.broker.get_cash() > 0: self.order = self.buy(size=self.market_volume[0]) else: if not self.position: if self.time.time() > datetime.time(9, 5, 0) and self.time.time() < datetime.time(14, 00, 00): if self.volume_sma[0] * 0.5 <= self.minvolume[0]: self.buy_continue = True if self.broker.get_cash() > 0: size = int(self.broker.get_cash() / self.dataclose[0]) self.order = self.buy(size=size)
if name == 'main':
cerebro = bt.Cerebro() modpath = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))) datapath = os.path.join(modpath, 'database/000250.csv') dataframe = pd.read_csv(datapath, parse_dates=True, index_col=0, dtype={"Close":'float', "Volume":'int', "Open":'float', 'High':'float', 'Low':'float'}) dataframe["Datetime"] = pd.to_datetime(dataframe["Datetime"]) cerebro.addstrategy(FatherStrategy) data = bt.feeds.PandasData(dataname=dataframe) cerebro.adddata(data) data = cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes) cerebro.broker.setcash(10000000.0) cerebro.broker.setcommission(commission=0.0175) print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.run() print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.plot(style='bar')
-
@김도언 said in How to make All-in Market Price in tick-chart:
if self.buy_continue: if self.broker.get_cash() > 0: self.order = self.buy(size=self.market_volume[0])
market volume will be more than your available cash during your last fill.
a much easier alternative would be something like this inside the notify_order method
if order.status in [order.Margin, order.Rejected]: self.order = self.buy(size=int(self.data.close[0] / self.broker.get_cash())
possibly lower size by 1 until you get your fill.
-
@hghhgghdf-dfdf
That's genius idea. I wonder why there is no such method provided by backtrader. Just wonder. Anyway, thank you so much.