Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Hedging support

    General Discussion
    5
    10
    2287
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B
      btalgo last edited by

      Hi guys,

      I'm wondering does backtrader have any support for hedging?

      For example being in a long and short position at the same time?

      There are many reasons/use cases for this; such as:

      • a market neutral strategy (trading on the same market), or
      • building into a net long/short position over time, etc.

      I cant seem to find any examples or any search results when searching hedging.

      Breaking it down- I'm essentially looking for the ability to have buy market and sell market orders open at the same time.

      Thanks again, fantastic community here and great product.

      1 Reply Last reply Reply Quote 1
      • A
        ab_trader last edited by

        If you try to get in the long and short position at the same time in the same instrument in the same account, you will have no position? Or these are positions in different instruments or different accounts? In latter case it does't matter is it hedging or not, bt will open positions according to signals.

        • If my answer helped, hit reputation up arrow at lower right corner of the post.
        • Python Debugging With Pdb
        • New to python and bt - check this out
        1 Reply Last reply Reply Quote 1
        • B
          backtrader administrators last edited by

          Cannot say more than what @ab_trader already said

          1 Reply Last reply Reply Quote 0
          • B
            btalgo last edited by btalgo

            Hi guys thanks for the replies.

            As @ab_trader said, this is what I have found when using Backtrader-
            you can be either in a LONG or SHORT position or FLAT (no position).

            My question was in relation to going LONG and SHORT (both at market), on the same instrument, on the same account. <-- in essence that is the most basic form of hedging.. (as opposed to multiple instruments/different accounts)

            I've attached an example of this:
            Build Example: (https://imgur.com/WI83gWk)

            However- the root of the question lies in the ability to have each order being independant of each other. i.e

            With the ability to have orders independent (and consequently allow hedging), some more use cases would include (i.e questions- can these be done?):

            1. Allowing each order have its own stop loss/profit target

            2. Having the ability to select a specific order from an order book (where multiple orders exist on the same instrument)

            3. Have multiple strategies trading on the same instrument
            i.e Strategy 1 - BUY
            i.e Strategy 2 - BUY
            i.e Strategy 3 - BUY
            i.e Strategy 4 - BUY

            I hope this makes sense, happy to explain in more detail if necessary.

            Thanks guys, appreciate the fast response.

            B 1 Reply Last reply Reply Quote 0
            • B
              backtrader administrators @btalgo last edited by

              @btalgo said in Hedging support:

              As @ab_trader said, this is what I have found when using Backtrader-
              you can be either in a LONG or SHORT position or FLAT (no position).

              That's not because you are using Backtrader. That's the reality of life.

              @btalgo said in Hedging support:

              However- the root of the question lies in the ability to have each order being independant of each other. i.e

              Order are always independent. The problem is that you want to issue orders which undo the actions of other orders

              @btalgo said in Hedging support:

              1. Allowing each order have its own stop loss/profit target

              Orders do not have stop loss/profit target. You can have orders which allow you reach a profit or loss target when you already have an open position. You can use bracket orders and have stop loss/profit target orders be activated if a position is entered.

              • Docs - Bracket Orders

              @btalgo said in Hedging support:

              1. Having the ability to select a specific order from an order book (where multiple orders exist on the same instrument)

              Call your broker and ask it if you have can multiple conflicting orders on the same asset and only select and execute those which are of your interest.

              @btalgo said in Hedging support:

              1. Have multiple strategies trading on the same instrument
                i.e Strategy 1 - BUY
                i.e Strategy 2 - BUY
                i.e Strategy 3 - BUY
                i.e Strategy 4 - BUY

              That's already built-in from day 1 in backtrader

              @btalgo said in Hedging support:

              I hope this makes sense, happy to explain in more detail if necessary.

              Most of it doesn't make any sense at all.

              B 1 Reply Last reply Reply Quote 1
              • B
                btalgo @backtrader last edited by

                hi @backtrader thanks for the response.
                I'll try and expand and be clearer on some points:

                @btalgo said in Hedging support:

                As @ab_trader said, this is what I have found when using Backtrader-
                you can be either in a LONG or SHORT position or FLAT (no position).

                That's not because you are using Backtrader. That's the reality of life.

                @btalgo said in Hedging support:

                However- the root of the question lies in the ability to have each order being independant of each other. i.e

                Order are always independent. The problem is that you want to issue orders which undo the actions of other orders

                I understand what you are saying here (a SELL order closes a LONG order and vice versa).
                However in other platforms a SELL order is a market order independent of a LONG order. This is where hedging comes in- you can have a LONG and SHORT order open at the same time.

                Q: Is there any future scope, or any way to modify the current cerebro engine to allow this?

                @btalgo said in Hedging support:

                1. Allowing each order have its own stop loss/profit target

                Orders do not have stop loss/profit target. You can have orders which allow you reach a profit or loss target when you already have an open position. You can use bracket orders and have stop loss/profit target orders be activated if a position is entered.

                • Docs - Bracket Orders

                I am aware the orders do not have stops/profit targets- they are set with respective (separate) stop and limit orders. bracket orders solves this, sorry missed this in documentation, thanks!

                @btalgo said in Hedging support:

                1. Having the ability to select a specific order from an order book (where multiple orders exist on the same instrument)

                Call your broker and ask it if you have can multiple conflicting orders on the same asset and only select and execute those which are of your interest.

                many brokers do allow this but more specifically in the spot FX and CFD space. Futures/stockbrokers rare to find due to FIFO rules (in the same account)

                But this feature (only for backtesting) is very handy for various types of strategies where the goal would be to deploy across multiple accounts.

                @btalgo said in Hedging support:

                1. Have multiple strategies trading on the same instrument
                  i.e Strategy 1 - BUY
                  i.e Strategy 2 - BUY
                  i.e Strategy 3 - BUY
                  i.e Strategy 4 - BUY

                That's already built-in from day 1 in backtrader

                @btalgo said in Hedging support:

                I hope this makes sense, happy to explain in more detail if necessary.

                Most of it doesn't make any sense at all.

                Thanks again, look forward to your reply.

                B 1 Reply Last reply Reply Quote 0
                • B
                  backtrader administrators @btalgo last edited by

                  @btalgo said in Hedging support:

                  a SELL order closes a LONG order and vice versa

                  That's wrong. When you issue a Sell order, the broker looks at the current position held for the target asset. If the position is positive (Long), the sell order (which has a negative size) will sell as many contracts as possible. If the negative size is greater than the positive existing size, the broker will keep on selling (you will go Short)

                  @btalgo said in Hedging support:

                  Futures/stockbrokers rare to find due to FIFO rules (in the same account)

                  Exactly. Keep your own book as you would have to do in almost all of the brokers (I guess anyone reading this would be glad to a pointer to the broker who lets you have simultaneous conflicting Market orders parked on the same asset and on the same account)

                  @btalgo said in Hedging support:

                  However in other platforms a SELL order is a market order independent of a LONG order.

                  Sell orders are executed with the execution type you choose and not with simply with Market. What other platforms may or may not do is not relevant here. If you send conflicting Market orders to the same asset you will have a conflicting behavior.

                  @btalgo said in Hedging support:

                  Q: Is there any future scope, or any way to modify the current cerebro engine to allow this?

                  Cerebro has nothing to do with it. The key here is that you send order on the same account targeted at the same assets and the orders contradict each other.

                  You can put effort in developing a multi-account broker and you may execute conflicting orders against as many accounts as you wish.

                  1 Reply Last reply Reply Quote 0
                  • L
                    Laurent Michelizza last edited by

                    This hedging support offered by FX Brokers and CFD is really a bad idea and I am glad that backtrader is handling orders the way it is doing it at the moment. Which is the way to do it.

                    I am not sure what benefits do you get from hedging. If you have a loss, you can always exit it and re-enter, do need to supposedly hedge it by entering the opposite direction. The result is the same.

                    1 Reply Last reply Reply Quote 0
                    • J
                      jeff lee last edited by

                      Hi, I know your concern, like China futrue market, we have both the sell-open and buy-open contract at the same time.
                      in fact, you can reference the pair-trade mode to create your strategy.
                      the pair trade have both sell-open and buy-open of different instrument contracts at the same time.
                      you can upgrade it, one strategy sell the A contract and the other strategy buy the A contract at the same time.
                      that will fulfill your requirement.

                      1 Reply Last reply Reply Quote 2
                      • J
                        jeff lee last edited by

                        
                        # -*- coding: utf-8 -*-
                        ###############################################################################
                        #
                        # Copyright (C) 2019 http://www.backtrader.cn  3952700@qq.com
                        #
                        ###############################################################################
                        
                        from __future__ import (absolute_import, division, print_function,
                                                unicode_literals)
                        
                        import datetime  # For datetime objects
                        
                        import backtrader as bt
                        from backtrader import (date2num, num2date, time2num, TimeFrame, dataseries,
                                                metabase)
                        from LoadData import get_stock_code_daily,get_future_code_daily,get_future_code_min,get_future_data
                        
                        # Create a Stratey
                        class HedgeSameInstrumentStrategy1(bt.Strategy):
                            params = (
                                # ('exitbars', 5),
                                ('maperiod', 25),
                                ('printlog', True),
                            )
                        
                            def log(self, txt, dt=None, doprint=False):
                                ''' Logging function fot this strategy'''
                                if self.params.printlog or doprint:
                                    dt = dt or self.datas[0].datetime.date(0)
                                    print(len(self), ' HedgeSameInstrumentStrategy1 %s, %s' % (dt.isoformat(), txt))
                        
                            def __init__(self):
                                # Keep a reference to the "close" line in the data[0] dataseries
                                self.dataclose = self.datas[0].close
                                # To keep track of pending orders and buy price/commission
                                self.order = None
                                self.buyprice = None
                                self.buycomm = None
                        
                            def notify_order(self, order):
                                if order.status in [order.Submitted, order.Accepted]:
                                    # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                                    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')
                        
                                # Write down: no pending order
                                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):
                                # Simply log the closing price of the series from the reference
                                # self.log('Close, %.2f, %.2f' % (self.dataclose[0] , 0))
                        
                                # Check if an order is pending ... if yes, we cannot send a 2nd one
                                if self.order:
                                    return
                                if len(self) == 10:
                                    self.order = self.buy(data=self.data0, exectype=bt.Order.Market)
                        
                                if len(self) == 101:
                                    self.order = self.close(data=self.data0, exectype=bt.Order.Market)
                        
                        
                            def stop(self):
                                # cash is amount of money on the broker's account, value is cash available plus cost of all open positions
                                # Return is equal to value minus starting capital.
                                # If all positions are closed than, yes, value and cash should be the same.
                                # if short position still open, cash = value + abs(position value)
                                self.log('(MA Period %2d) Ending Value %.2f' %
                                         (self.params.maperiod, self.broker.getvalue()), doprint=True)
                        
                        
                        
                        
                        class HedgeSameInstrumentStrategy2(bt.Strategy):
                            params = (
                                # ('exitbars', 5),
                                ('maperiod', 25),
                                ('printlog', True),
                            )
                        
                            def log(self, txt, dt=None, doprint=False):
                                ''' Logging function fot this strategy'''
                                if self.params.printlog or doprint:
                                    dt = dt or self.datas[0].datetime.date(0)
                                    print(len(self), ' HedgeSameInstrumentStrategy2 %s, %s' % (dt.isoformat(), txt))
                        
                            def __init__(self):
                                # Keep a reference to the "close" line in the data[0] dataseries
                                self.dataclose = self.datas[0].close
                                # To keep track of pending orders and buy price/commission
                                self.order = None
                                self.buyprice = None
                                self.buycomm = None
                        
                            def notify_order(self, order):
                                if order.status in [order.Submitted, order.Accepted]:
                                    # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                                    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')
                        
                                # Write down: no pending order
                                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):
                                # Simply log the closing price of the series from the reference
                                # self.log('Close, %.2f, %.2f' % (self.dataclose[0] , 0))
                        
                                # Check if an order is pending ... if yes, we cannot send a 2nd one
                                if self.order:
                                    return
                        
                                if len(self) == 55:
                                    self.order = self.sell(data=self.data1, exectype=bt.Order.Market)
                        
                                if len(self) == 205:
                                    self.order = self.close(data=self.data1, exectype=bt.Order.Market)
                        
                            def stop(self):
                                # cash is amount of money on the broker's account, value is cash available plus cost of all open positions
                                # Return is equal to value minus starting capital.
                                # If all positions are closed than, yes, value and cash should be the same.
                                # if short position still open, cash = value + abs(position value)
                                self.log('(MA Period %2d) Ending Value %.2f' %
                                         (self.params.maperiod, self.broker.getvalue()), doprint=True)
                        
                        if __name__ == '__main__':
                            cerebro = bt.Cerebro(maxcpus = 1 )
                            cerebro.broker.setcash(100000.0)
                        
                            # Add a strategy
                            cerebro.addstrategy(HedgeSameInstrumentStrategy1)
                            cerebro.addstrategy(HedgeSameInstrumentStrategy2)
                        
                            # Datas are in a subfolder of the samples. Need to find where the script is
                            # because it could have been called from anywhere
                            # modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
                            filePath1 = r"D:\BackTraderCN\Class1\stock_data\600827.csv"
                            data_1 = get_stock_code_daily(filePath1)
                            start_dt1 = data_1.index[0]
                            end_dt1 = data_1.index[-1]
                        
                        
                            filePath2 = r"D:\BackTraderCN\Class1\stock_data\600827.csv"
                            data_2 = get_stock_code_daily(filePath2)
                            start_dt2 = data_2.index[0]
                            end_dt2 = data_2.index[-1]
                        
                            if start_dt1 < start_dt2:
                                start_dt1 = start_dt2
                        
                            if end_dt1 > end_dt2:
                                end_dt1 = end_dt2
                        
                        
                            # end_dt = datetime.datetime(year=2019, month=7, day=8)
                            data1 = bt.feeds.PandasData(dataname=data_1,
                                                       fromdate=start_dt1,
                                                       todate=end_dt1,
                                                       timeframe=TimeFrame.Days,
                                                       )
                            data2 = bt.feeds.PandasData(dataname=data_2,
                                                        fromdate=start_dt1,
                                                        todate=end_dt1,
                                                        timeframe=TimeFrame.Days,
                                                        )
                        
                        
                            # Add the 1st data to cerebro
                            cerebro.adddata(data1)
                        
                            # Add the 2nd data to cerebro
                            cerebro.adddata(data2)
                        
                            # Add a FixedSize sizer according to the stake
                            cerebro.addsizer(bt.sizers.FixedSize, stake=10)
                        
                            print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
                            # Set the commission
                            cerebro.broker.setcommission(commission=0.0)
                        
                            cerebro.run()
                        
                            print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
                            # cerebro.plot(style='candlestick')
                            cerebro.plot()
                        
                        
                        
                        1 Reply Last reply Reply Quote 1
                        • 1 / 1
                        • First post
                          Last post
                        Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors