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

Setting multiple TP for the same buy position



  • Hi,

    I am trying to manage multiple take profits for the same buy order (I didn't see any example about it).
    I use a sizer in percent:

    from backtrader.sizers import PercentSizerInt
    
    
    class FullMoney(PercentSizer):
        params = (
            ('percents', 100),
        )
    
    cerebro = bt.Cerebro()
    cerebro.addsizer(FullMoney)
    
    broker = cerebro.getbroker()
    broker.setcash(100000)
    
    # ...
    

    and orders like these:

    # ...
    self.buy()
    self.sell(exectype=bt.Order.Limit, price=self.data.close * 1.03, size=50)
    self.sell(exectype=bt.Order.Limit, price=self.data.close * 1.06, size=50)
    

    At the end of the trade (blue dot), cash should match value but it's not happening (maybe something is wrong in my sizer):

    Screenshot 2020-08-10 at 22.14.56.png

    Any thoughts ?
    Thanks for your help !



  • @balibou said in Setting multiple TP for the same buy position:

    Any thoughts ?

    Based on what is shown (and it is actually not a lot) you sell more shares when you had in the long position, therefore you opened short position. And your cash is not equal, but larger than the broker value.

    If the sizer is used in the system, than the sizer defines size. Looks like somewhere in bt 100% size defined by the sizer interferes with size=50 in your orders returning that large short positions.

    I would recommend you to add more logging (signals, order statuses and prices, order sizes, trade opening/closing, cash, values, prices etc) while you are developing your scripts in order to have full understanding of what is going on. Believe me it will save a lot of time for you and will bring deeper understanding of bt.



  • Thanks for your feedback @ab_trader !

    Actually I had a deeper understanding of sizers with this article: https://www.backtrader.com/blog/posts/2019-08-29-fractional-sizes/fractional-sizes/

    I thought that the size parameter was in percents ... but it has been much clearer with this piece of code:

    def notify_order(self, order):
            if order.alive():
                return
    
            otypetxt = 'Buy ' if order.isbuy() else 'Sell'
            if order.status == order.Completed:
                self.loginfo(
                    ('{} Order Completed - '
                     'Size: {} @Price: {} '
                     'Value: {:.2f} Comm: {:.2f}'),
                    otypetxt, order.executed.size, order.executed.price,
                    order.executed.value, order.executed.comm
                )
            else:
                self.loginfo('{} Order rejected', otypetxt)
    

    As you said, logs saved me on this topic !

    I came with this solution, and it's working like a charm:

    o1 = self.buy()
    self.sell(exectype=bt.Order.Limit, price=self.data.close * 1.03, size= o1.size * 0.25)
    self.sell(exectype=bt.Order.Limit, price=self.data.close * 1.06, size=o1.size * 0.25)
    self.sell(exectype=bt.Order.Limit, price=self.data.close * 1.12, size=o1.size * 0.25)
    self.sell(exectype=bt.Order.Limit, price=self.data.close * 1.20, size=o1.size * 0.25)
    

    On each TP, I sell a fragment (25%) of my position (+3%, +6%, +12% and +20%)


Log in to reply
 

});