Backtrader Community

    • 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/

    Modifying Trade class to include entry and exit price

    General Code/Help
    4
    10
    3633
    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.
    • Richard O'Regan
      Richard O'Regan last edited by Richard O'Regan

      Hi guys,

      I'd like to keep track of trades. So I've been using notify_trade() in my strategy to record trades my system made. [I could also code an Analyzer to do the same].

      Ok, so I want to do several things with my list of trades made by system. E.g. plotting trades on my own chart so I can visually see entry and exits.
      I need to know; entry price and exit price.

      If I print a Trade object, the output string is this;

      ref:121
      data:<backtrader.feeds.csvgeneric.GenericCSVData object at 0x110f19320>
      tradeid:1
      size:0
      price:88.800003
      value:0.0
      commission:0.0
      pnl:-1.0
      pnlcomm:-1.0
      justopened:False
      isopen:False
      isclosed:True
      baropen:14
      dtopen:736338.0006944444
      barclose:14
      dtclose:736338.0006944444
      barlen:0
      historyon:False
      history:[]
      status:2

      I can see entry price via: 'price' but I problem is I can't easily see exit price (unless I calculate via add/subtract 'pnl' depending if long or short).

      I've added two lines of code in trade.py, in Trade's def update(..),
      which creates member variables 'entry_price' and 'exit_price'.

             self.value = comminfo.getvaluesize(self.size, self.price)
             
             # My added code..
             self.entry_price = self.price    # Rich O'Regan added..
             self.exit_price = price          # Rich O'Regan added..
      
             # Update the history if needed
             if self.historyon:
                 dt0 = self.data.datetime[0] .. blah   blah blah
      

      This simple code addition is helpful because I can now access these values from a Trade object, and do useful things like plot trades on my own charts.

      MY QUESTION:
      I was surprised Daniel didn't initially have this included. Entry and exit price are a key attribute to have, so maybe there was good reason not to.

      I'm working on some code that I'd like to make public. Are there any red flags to what I'm doing? Something I may be missing?

      Any comments greatly appreciated.

      Thanks

      You can take the man out of the army, but you can't take the army out of the man.

      1 Reply Last reply Reply Quote 0
      • P
        Paska Houso last edited by

        You may be oversimplifying the problem.

        • What is your definition of entry price?

        Some background:

        • A trade as it seems to be defined can accumulate, for example, 20 buy orders with 20 different entry prices before a reduction of the position is undertaken

        In this example it would seem straightforward to average the price using the sizes, but

        • Another trade can buy 20 times, sell 10 times, buy again 20 times and then sell 5 to close the position.

        It would seem difficult to define what's the entry price, because the position has been growing, diminishing, growing again and is then finally closed.

        You can apply the same examples to the exit price, which in the 2nd example is very difficult to define.

        If you obviously only have 1 opening order and 1 closing order, your entry and exit prices are clearly defined, but only because the match the 1st and last prices the trade see.

        1 Reply Last reply Reply Quote 0
        • Richard O'Regan
          Richard O'Regan last edited by Richard O'Regan

          Hi Paska, thanks very much for your quick response.

          Yeah I was afraid there might be some other issues.

          The way I personally backtest, I only buy or sell one future contract. I only test with a size of 1. It makes comparisons between systems easier.
          Yes for your example, my code would break!

          Personally if I want to add more to my position then I would consider that a separate trade. (It seems confusing to buy and sell different amounts at different times and consider this as one trade.)

          Just thinking the best way forward. I was going through trade.py code trying to figure out how it all works. Perhaps I could subclass a SimpleTrade object and enforce it to allow only one buy and sell etc and no multiple positions like in your example. And then place trades e.g. buy(mode='simple') e.t.c.

          Feel like it's gonna take far too long to implement.

          Maybe I should just keep my code private, since I am aware of the issue and will only be using it to trade 1 unit. Therefore don't have to worry about it not fitting correctly in more complex cases.

          Thoughts comments greatly appreciated, thanks guys.

          You can take the man out of the army, but you can't take the army out of the man.

          1 Reply Last reply Reply Quote 0
          • P
            Paska Houso last edited by

            The above examples model a "long trade" or "short trade" in which you can keep the trade going for a long time. Yours is an order based trade (entry/exit)

            Given how easy it is to monkey patch in Python, your best bet would be to override some methods in Trade before anything else happens in the system.

            It may be enough with saving the existing update method as old_update and then adding your own update which on the first heartbeat writes down the entry price and then calls old_update. And with the second heartbeat, the exit price is noted, piggybacking again on old_update

            Richard O'Regan 1 Reply Last reply Reply Quote 0
            • T
              ThatBlokeDave last edited by

              If you want to see by and sell points on the chart, how about tracking it via notify_order()?

              Each time an order is completed you can mark the executed order price and size on the chart (a little like how Tradingview does). That way you can see for example 10 contracts were bought here, 5 sold here, remaining 5 sold there etc.

              In your case, buying and selling one contract at a time, the markers would line up with the trade.

              Richard O'Regan 1 Reply Last reply Reply Quote 0
              • Richard O'Regan
                Richard O'Regan @Paska Houso last edited by

                @Paska-Houso Hey Paska, thanks again. Ok just to clarify what you are saying.

                Understood creating 'old_update(..)' and calling it from my overridden update(..).

                Couple of issues.

                1. If I'm using the first, second heartbeat, is it correct that I will also need to check for tradeid because I often have trades overlapping each other. i.e. I will need to eg put trade in a dict with tradeid as key and count first and 2nd heartbeat associated to that unique id.

                2. What advantage will this give me over what I'm doing now. i.e the simple 2 line code I first posted. Both are incompatible with more complex cases and both will work for simple cases.

                Many thanks

                You can take the man out of the army, but you can't take the army out of the man.

                1 Reply Last reply Reply Quote 0
                • Richard O'Regan
                  Richard O'Regan @ThatBlokeDave last edited by Richard O'Regan

                  @ThatBlokeDave Hey cheers Dave. Another interesting way to solve problem. Yeah I think your method is better actually, I hadn't considered this.

                  However since for myself I will likely only ever backtest the simple type of entry/exit, I think its easier to not worry about trying to implement the more complex open ended trade. Though if I wanted to make public I'd definitely reconsider.

                  Check this out what I've done so far. Using Plot.ly for convenience as nice interactivity (if anybody knows anything better pls let me know). This is a fictional test system and doesn't actually make money. You can see I can enter multiple trades and see entry, exit and profit. (Green lines = profitable trade, red = loss).

                  I also made profit use R-Multiples instead of raw price profit (another hack that probably will crash in complex cases!). I'll prob make a separate post of this plotting another time, I find it really helpful to check my logic is working correctly.

                  0_1510639453561_tradePlot2.png

                  You can take the man out of the army, but you can't take the army out of the man.

                  T 1 Reply Last reply Reply Quote 1
                  • T
                    ThatBlokeDave @Richard O'Regan last edited by ThatBlokeDave

                    @Richard-O'Regan

                    Looks great - Is this plotting after the backtest has ended? On my long list of "things to do but probably will never get around to", is to create an extension for live plotting. Like your example, visualizing what is happening really helps when working with people who are not coming from a technical background.

                    I looked at Bokeh a while ago when I was day dreaming about it.

                    https://bokeh.pydata.org/en/latest/

                    Not sure if it is better than plotly but worth a look for comparison.

                    1 Reply Last reply Reply Quote 1
                    • Richard O'Regan
                      Richard O'Regan last edited by Richard O'Regan

                      Yeah I was initially considering Bokeh. It seems the plotting wasn't quite as nice but I think is more flexible. It was 50:50 between them.. if anyone can say for sure pros / cons which is better, I may switch to Bokeh.

                      Yes correct, plots after backtest complete.

                      Right now my code is spread out in a Jupiter notebook, I can plot trades and also do heatmaps/3d charts of optimisations. I'm looking to make more of a solid environment to test my ideas. Once I set up I can release the code, you should be able to plug into your backtesting easy. It's not too long or complex.

                      Here are a couple of screenshots from backtesting another system. Surprisingly quick to do these plots.

                      2_1510647970671_heatmap1.png 1_1510647970671_heatmap2.png 0_1510647970670_3dchart.png

                      You can take the man out of the army, but you can't take the army out of the man.

                      A 1 Reply Last reply Reply Quote 1
                      • A
                        ab_trader @Richard O'Regan last edited by ab_trader

                        @Richard-O-Regan
                        Hi! Nice plots. I was looking into Bokeh sometime ago, but wasn't able to do any valuable staff. Not a lot of experience with python.

                        Can you share more details on the plotting with alternative package? Do you pass bt data directly into it or pass it to pandas (for example) first and then use in the plotting package?

                        • 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 0
                        • 1 / 1
                        • First post
                          Last post
                        Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors