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/

    Problem with plotting buy sell arrows

    General Code/Help
    2
    4
    1517
    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.
    • Z
      zblp last edited by zblp

      Hi guys, I've just started using backtrader and I am struggling with plotting.
      Buy sell arrows don't seem in the correct place. There is some kind of scaling issue. I have a csv data with 5m frames. As you can see in my script I'm using

      timeframe=bt.TimeFrame.Minutes,
      compression=5
      

      Any help is appreciated.

      Plot:
      0_1547840632836_Figure_0.png

      You can see my config below:

      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      
      import backtrader as bt
      import backtrader.feeds as btfeeds
      import datetime
      import os.path  # To manage paths
      import sys  # To find out the script name (in argv[0])
      import numpy
      
      
      # Create a Stratey
      class TestStrategy(bt.Strategy):
      
          def log(self, txt, dt=None):
              ''' Logging function fot this strategy'''
              dt = dt or self.datas[0].datetime.date(0)
              print('%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
              self.datahigh = self.datas[0].high
      
              # To keep track of pending orders and buy price/commission
              self.order = None
              self.buyprice = None
              self.buycomm = None
      
              # Add a MovingAverageSimple indicator
              self.ma7 = bt.indicators.SimpleMovingAverage(self.datas[0], period=7)
              self.ma25 = bt.indicators.SimpleMovingAverage(self.datas[0], period=25)
      
          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
      
              # Check if an order has been completed
              # Attention: broker could reject order if not enough cash
              if order.status in [order.Completed]:
                  if order.isbuy():
                      self.log(
                          'BUY EXECUTED, Price: %.8f, Cost: %.8f, Comm %.8f' %
                          (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: %.8f, Cost: %.8f, Comm %.8f' %
                               (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 %.8f, NET %.8f' %
                       (trade.pnl, trade.pnlcomm))
      
          def next(self):
              # Simply log the closing price of the series from the reference
              self.log('Close, %.8f' % self.dataclose[0])
      
              # Check if an order is pending ... if yes, we cannot send a 2nd one
              if self.order:
                  return
      
              # Check if we are in the market
              if not self.position:
      
                  # Not yet ... we MIGHT BUY if ...
      
                  if self.ma7[0] > self.ma25[0]:
      
                      # BUY, BUY, BUY!!! (with all possible default parameters)
                      self.log('BUY CREATE, %.8f' % self.dataclose[0])
      
                      # Keep track of the created order to avoid a 2nd order
                      self.order = self.buy()
      
              else:
      
                  if self.ma7[0] < self.ma25[0]:
                      # SELL, SELL, SELL!!! (with all possible default parameters)
                      self.log('SELL CREATE, %.8f' % self.dataclose[0])
      
                      # Keep track of the created order to avoid a 2nd order
                      self.order = self.sell()
      
      
      if __name__ == '__main__':
          # Create a cerebro entity
          cerebro = bt.Cerebro()
      
          # Add a strategy
          cerebro.addstrategy(TestStrategy)
      
          # 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]))
          datapath = os.path.join(modpath, 'ohlcv1.csv')
      
          data = btfeeds.GenericCSVData(
              dataname=datapath,
              dtformat='%Y-%m-%d %H:%M:%S',
              datetime=0,
              open=1,
              high=2,
              low=3,
              close=4,
              volume=5,
              openinterest=-1,
              timeframe = bt.TimeFrame.Minutes,
              compression=5
          )
      
      
          # Add the Data Feed to Cerebro
          cerebro.adddata(data)
      
          # Set our desired cash start
          cerebro.broker.setcash(1000.0)
      
          # Add a FixedSize sizer according to the stake
          cerebro.addsizer(bt.sizers.FixedSize, stake=0.2)
      
          # Set the commission
          cerebro.broker.setcommission(commission=0.001)
      
          # Print out the starting conditions
          print('Starting Portfolio Value: %.8f' % cerebro.broker.getvalue())
      
          # Run over everything
          cerebro.run()
      
          # Print out the final result
          print('Final Portfolio Value: %.8f' % cerebro.broker.getvalue())
      
      
          # Plot the result
          cerebro.plot(style='candlestick', barup='green', bardown='red')
      
      
      B 1 Reply Last reply Reply Quote 0
      • B
        backtrader administrators @zblp last edited by

        @zblp said in Problem with plotting buy sell arrows:

        Buy sell arrows don't seem in the correct place

        They are

        @zblp said in Problem with plotting buy sell arrows:

        There is some kind of scaling issue

        No, there isn't. Your data doesn't have enough price difference from the highest high to the lowest low for the default configuration. See:

        • Docs - Observer Reference

        Disable the standard observers in cerebro using stdstats and add the observers you may wish with the configuration of your choice. See:

        • Docs - Cerebro
        • Docs - Observer and Statistics
        1 Reply Last reply Reply Quote 2
        • Z
          zblp last edited by

          Hi, thank you very much for help. I'm creating the cerebro entity with stdstats=False right now, but as you can see in the figure, arrows placed in the middle of the candles. Is there a way to add some kind of margin space between arrows and candles?

          0_1548020666236_Figure_0.png

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

            In the "Observers Reference* pasted above you have the parameters which can be given to the BuySell observer which do that (it is part of the standard configuration), namely barplot to activate the plotting away from the price and bardist to control the distance.

            1 Reply Last reply Reply Quote 1
            • 1 / 1
            • First post
              Last post
            Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
            $(document).ready(function () { app.coldLoad(); }); }