For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

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 money

    For 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 65

    then,
    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.


Log in to reply
 

});