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/

    Buy and Sell markers plot distance

    General Code/Help
    2
    5
    632
    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.
    • A
      Aritz Lizaso last edited by

      Hi!, i am newat backtrader, i have read all documentation and fin any information related but i dont know how to change thebuy and sell markers distance to the data when i plot the results with .plot() . I am using 1 minute data and this markers are to far to the data and i cant see it easily. Can anyone help me with this? Many thanks!

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

        The default configuration can be switched off when running cerebro.run with the parameter stdstats.

        • https://www.backtrader.com/docu/cerebro/

        After that you can add your own plethora of observers, including the BuySell one and decide where you want the markers

        • https://www.backtrader.com/docu/observers-and-statistics/observers-and-statistics/
        • https://www.backtrader.com/docu/observers-reference/

        An example

        • https://www.backtrader.com/blog/posts/2016-12-10-buysellarrows/buysellarrows/
        1 Reply Last reply Reply Quote 1
        • A
          Aritz Lizaso last edited by

          Thank you for your answer,

          The first thing I apologize, I think I did not know how to put the code well.

          The second my code is not secret, its only a test. I put only the backtest running parts because there are too many lines.

          I read the documentation before post and had no problem hiding the imported data directly. My problem is that I don't know how to hide daily resampled data in the chart. Perhaps i lose something but I really can't find anything about it. Here I show everything:

          from __future__ import (absolute_import, division, print_function, unicode_literals)
          
          import backtrader as bt  # The backtrader platform
          import backtrader.feeds as btfeeds  # For load CSV data.
          from backtrader import Indicator, CmpEx # For indicators
          import backtrader.indicators as btind  # For indicators
          
          import datetime  # For datetime objects
          from datetime import time
          import matplotlib # For ploting
          
          # Symbols to load
          symbol_list = ['EURUSD','GBPUSD','USDJPY']
          
          # List for storage the loaded datas
          data_list = []
          
          # Load the data feeds
          for symbol in symbol_list:     
              
              # 1 minute data (Each tick for analyze the strategy)_______________________________________________________
              data0 = btfeeds.GenericCSVData(
              dataname='{}_GMT+0_2018-2019_M1.csv'.format(symbol),    
          
              fromdate=datetime.datetime(2018, 1, 1),
              todate=datetime.datetime(2018, 1, 31),  #(2018, 1, 31)
          
              nullvalue=0.0,
          
              dtformat=('%d.%m.%Y %H:%M:%S'),
          
              datetime=0,
              open=1,
              high=2,
              low=3,
              close=4,
              volume=-1,
              openinterest=-1,
          
              timeframe=bt.TimeFrame.Minutes,
              compression=1,
                  
              plot = True
              ) 
             
              data_list.append(data0)
              
              # 30 minute data (Pullback checking and plotting)__________________________________________________________
              data1 = btfeeds.GenericCSVData(
              dataname='{}_GMT+0_2018-2019_M30.csv'.format(symbol),    
          
              fromdate=datetime.datetime(2018, 1, 1),
              todate=datetime.datetime(2018, 1, 31),
          
              nullvalue=0.0,
          
              dtformat=('%d.%m.%Y %H:%M:%S'),
          
              datetime=0,
              open=1,
              high=2,
              low=3,
              close=4,
              volume=-1,
              openinterest=-1,
          
              timeframe=bt.TimeFrame.Minutes,
              compression=30,
                  
              plot = False
              ) 
             
              data_list.append(data1)
              
              # 1 Day data (For pivot points indicator)_______________________________________________________________
              data2 = btfeeds.GenericCSVData(
              dataname='{}_GMT+0_2018-2019_D1.csv'.format(symbol),    
          
              fromdate=datetime.datetime(2018, 1, 1),
              todate=datetime.datetime(2018, 1, 31),
          
              nullvalue=0.0,
          
              dtformat=('%d.%m.%Y %H:%M:%S'),
          
              datetime=0,
              open=1,
              high=2,
              low=3,
              close=4,
              volume=-1,
              openinterest=-1,
          
              timeframe=bt.TimeFrame.Days,
              compression=1,
                  
              plot = False
              ) 
             
              data_list.append(data2)
                 
          # Assign data feed variables
          data_eurusd_m1 = data_list[0]
          data_eurusd_m30 = data_list[1]
          data_eurusd_d1 = data_list[2]
          data_gbpusd_m1 = data_list[3]
          data_gbpusd_m30 = data_list[4]
          data_gbpusd_d1 = data_list[5]
          data_usdjpy_m1 = data_list[6]
          data_usdjpy_m30 = data_list[7]
          data_usdjpy_d1 = data_list[8]
          
          class PivotPoints_V8_Indicator(Indicator):
             
              lines = ('PP', 'R1', 'S1', 'R2', 'S2', 'R3', 'S3')
              #plotinfo = dict(subplot=False)
              plotinfo = dict(subplot=False)
              
              params = (('_autoplot', True),)  # attempt to plot on real target data
          
              def _plotinit(self):
                  
                  # Try to plot to the actual timeframe master
                  if self.p._autoplot:
                      if hasattr(self.data, 'data'):
                          self.plotinfo.plotmaster = self.data.data
                          #self.plotinfo.plotmaster = self.data.datas[1] # The second Data (M30) 
                          # The indicator plots on resampled data*
          
              def __init__(self):
                  
                  h = self.data.high  # current high
                  l = self.data.low  # current low
                  c = self.data.close  # current close
          
                
                  self.lines.PP = PP = (h + l + c) / 3.0
                  self.lines.R1 = R1 = 2.0 * PP - l
                  self.lines.S1 = S1 = 2.0 * PP - h
                  self.lines.R2 = R2 = (PP - S1) + R1
                  self.lines.S2 = S2 = PP - (R1 - S1)
                  self.lines.R3 = (PP - S2) + R2
                  self.lines.S3 = PP - (R2 - S2)
          
                  #super(PivotPoint, self).__init__()  # enable coopertive inheritance
          
                  if self.p._autoplot:
                      self.plotinfo.plot = False  # disable own plotting
                      self()  # Coupler to follow real object
          
          
          def time_in_range(start, end, x):
              
              """Return true if x is in the range [start, end]"""
              
              if start <= end:
                  return start <= x <= end
              else:
                  return start <= x or x <= end
          
          # The Strategy
          
          class PIVOTPOINTS_V8(bt.Strategy):
              
              
              # datas[0] = EURUSD
              #...
              # datas[3] = GBPUSD
              #...
              # datas[6] = USDJPY
              #...
              
              def log(self, txt, dt=None):
                  ''' Logging function for this strategy'''
                  dt = dt or self.datas[0].datetime.datetime(0)
                  print('%s, %s' % (dt.strftime('%d-%m-%Y %H:%M:%S'), txt))
          
              def __init__(self):
              
                  # Strategy symbol
                  self.symbol = 'EURUSD.r' #,'GBPUSD.r','USDJPY.r'
                  
                  # Indicator
                  self.pivotindicator = PivotPoints_V8_Indicator(self.datas[3])  # the resampled data
                  #self.pivotindicator.plotinfo.plotlinelabels = True
                  
                  # Data references
                  self.M1_datetime = self.datas[0].datetime
                  self.M1_close = self.datas[0].close
                  self.M30_close = self.datas[1].close
                  self.D1_close = self.datas[2].close
                  self.D1_high = self.datas[2].high
                  self.D1_low = self.datas[2].low
                  
                  # Strategy variables
                  self.pullback_size = 70
                  self.pullback_candles = 10 #(M30 Candles!)
                  self.op_counters = [0,0,0,0,0,0,0,0,0,0,0,0,0,0]
                  self.send_distance = 70  #(Points)
                  self.open_distance = 20  #(Points)
                  self.lot = 1.5  #(1 lot = 100.000 unitary units)
                  self.stoploss = 100
                  self.takeprofit = 100
                  
                  # Keep a reference to the orders   
                  #self.order = None
                  
              def notify_order(self, order):
                  #date = self.data.datetime.datetime().date()
                  date = self.data.datetime.datetime()
          
                  if order.status == order.Accepted:
                      print('-'*32,' NOTIFY ORDER ','-'*32)
                      print('Order Accepted')
                      print('{}, Status {}: Ref: {}, Size: {}, Price: {}'.format(
                                                                  date,
                                                                  order.status,
                                                                  order.ref,
                                                                  order.size,
                                                                  'NA' if not order.price else round(order.price,5)
                                                                  ))
          
          
                  if order.status == order.Completed:
                      print('-'*32,' NOTIFY ORDER ','-'*32)
                      print('Order Completed')
                      print('{}, Status {}: Ref: {}, Size: {}, Price: {}'.format(
                                                                  date,
                                                                  order.status,
                                                                  order.ref,
                                                                  order.size,
                                                                  'NA' if not order.price else round(order.price,5)
                                                                  ))
                      print('Created: {} Price: {} Size: {}'.format(bt.num2date(order.created.dt), order.created.price,order.created.size))
                      print('-'*80)
          
                  if order.status == order.Canceled:
                      print('-'*32,' NOTIFY ORDER ','-'*32)
                      print('Order Canceled')
                      print('{}, Status {}: Ref: {}, Size: {}, Price: {}'.format(
                                                                  date,
                                                                  order.status,
                                                                  order.ref,
                                                                  order.size,
                                                                  'NA' if not order.price else round(order.price,5)
                                                                  ))
          
                  if order.status == order.Rejected:
                      print('-'*32,' NOTIFY ORDER ','-'*32)
                      print('WARNING! Order Rejected')
                      print('{}, Status {}: Ref: {}, Size: {}, Price: {}'.format(
                                                                  date,
                                                                  order.status,
                                                                  order.ref,
                                                                  order.size,
                                                                  'NA' if not order.price else round(order.price,5)
                                                                  ))
                      print('-'*80)
          
          
              def notify_trade(self, trade):
                  date = self.data.datetime.datetime()
                  if trade.isclosed:
                      print('-'*32,' NOTIFY TRADE ','-'*32)
                      print('{}, Close Price: {}, Profit, Gross {}, Net {}'.format(
                                                          date,
                                                          trade.price,
                                                          round(trade.pnl,2),
                                                          round(trade.pnlcomm,2)))
                      print('-'*80)
          
              def next(self):
                  
                  #//////// Trading Time //////////////////////////////////////////////////////////////
                  
                  start = time(4,0,0) #4,0,0
                  end = time (20,50,0) #20,50,0
                  now = self.M1_datetime.time()
                  weekday = self.datas[0].datetime.datetime(0).weekday()
                  
                  if time_in_range(start, end, now) and weekday in [1,2,3,4]:  #(Monday=0, Tueasday=1...Sunday=6)
          
                      # --- Get Data ----------------------------------------------------------------------
          
                      # Pivot Points values
          
                      PP = self.pivotindicator.lines.PP[0]
                      R1 = self.pivotindicator.lines.R1[0]
                      S1 = self.pivotindicator.lines.S1[0]
                      R2 = self.pivotindicator.lines.R2[0]
                      S2 = self.pivotindicator.lines.S2[0]
                      R3 = self.pivotindicator.lines.R3[0]
                      S3 = self.pivotindicator.lines.S3[0]
          
                      # List of pivot point levels for send orders iteration (Buy and Sell each level)
                      pp_levels = [PP,PP,R1,R1,S1,S1,R2,R2,S2,S2,R3,R3,S3,S3]
          
                      # Price (M1 Close, Backtrader cant handle tick data for Bid and Ask prices)
                      price = self.M1_close[0]
          
                      # Point value
                      if 'JPY' in self.symbol:
                          point = 0.001
                      else:
                          point = 0.00001
          
                      # Pullbacks 
                      periods_back = self.pullback_candles  #(M30 Candles)
                      back_rates = self.M1_close.get(size=periods_back, ago=0)
          
                      highest = max(back_rates)
                      lowest = min(back_rates)
          
                      pullback_buy = (highest - price) / point > self.pullback_size 
                      pullback_sell = (price - lowest) / point > self.pullback_size
          
                      # --- Send Orders ---------------------------------------------------------------
          
                      # Check if any entry condition has been met
                      for i in range(len(self.op_counters)):
          
                          # BUY iterations on pivot levels
                          if i in [0,2,4,6,8,10,12]:
          
                              if price > pp_levels[i] and price < (pp_levels[i] + self.send_distance * point) and pullback_buy == True and self.op_counters[i] == 0 :  
          
                                  price = pp_levels[i]+(self.open_distance*point) # Price of the limit order
                                  sl = price - (self.stoploss*point)
                                  tp =price + (self.takeprofit*point)
          
                                  buy_order = self.buy_bracket(limitprice=tp, price=price, stopprice=sl, exectype=bt.Order.Limit, size= self.lot*100000)
          
                                  # Update ticket
          
                                  # Update counter
                                  self.op_counters[i] +=1
          
                          # SELL iterations on pivot levels
                          elif i in [1,3,5,7,9,11,13]:
          
                              if price < pp_levels[i] and price > (pp_levels[i] - self.send_distance * point) and pullback_sell == True and self.op_counters[i] == 0 :  
          
                                  price = pp_levels[i]-(self.open_distance*point) # Price of the limit order
                                  sl = price + (self.stoploss*point)
                                  tp =price - (self.takeprofit*point)
          
                                  sell_order = self.sell_bracket(limitprice=tp, price=price, stopprice=sl, exectype=bt.Order.Limit, size= self.lot*100000)
          
                                  # Update ticket
          
                                  # Update counter
                                  self.op_counters[i] +=1
          
                      # --- Orders Managment -----------------------------------------------------------
                      
                      
          
          
                  
                  else:
                      
                      #//////// Out of trading Time ////////////////////////////////////////////////////
                        
                      # --- Reset ----------------------------------------------------------------------
                      
                      self.op_counters = [0,0,0,0,0,0,0,0,0,0,0,0,0,0]
                      
                      # --- Close all ----------------------------------------------------------------------
                      
                      if self.position:
                          self.close()
                          #self.close(data= self.datas[0])
          
          
          if __name__ == '__main__':
              
              # Instantiate the Cerebro engine  
              cerebro = bt.Cerebro(stdstats=False)  # remove the standard observers
              
              # Add a strategy
              cerebro.addstrategy(PIVOTPOINTS_V8)
              
              # Add the Data Feeds to Cerebro
              cerebro.adddata(data_eurusd_m1)
              cerebro.adddata(data_eurusd_m30)
              cerebro.adddata(data_eurusd_d1)
              #cerebro.adddata(data_gbpusd_m1)
              #cerebro.adddata(data_gbpusd_m30)
              #cerebro.adddata(data_gbpusd_d1)
              #cerebro.adddata(data_usdjpy_m1)
              #cerebro.adddata(data_usdjpy_m30)
              #cerebro.adddata(data_usdjpy_d1)
              
              # Resampled data for the indicator
              cerebro.resampledata(data_eurusd_m1, timeframe=bt.TimeFrame.Days)
              
              # Set our desired cash start
              cerebro.broker.setcash(100000.0)
              
              cerebro.broker.set_checksubmit(False)
              
              # Set the commission - 25 monetary units per 1 lot (1 lot = 100.000 monetary units), per buy/sell = 0.0125%, total= 0.025% 
              cerebro.broker.setcommission(commission=0.000125)
              
              # Add Analyzers
              
              #cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='TradeAnalyzer')
              #cerebro.addanalyzer(bt.analyzers.Returns, _name='Returns')
              #cerebro.addanalyzer(bt.analyzers.TimeReturn, _name='TimeReturn')
              #cerebro.addanalyzer(bt.analyzers.Transactions, _name='Transactions')
              #cerebro.addanalyzer(bt.analyzers.PositionsValue, _name='PositionsValue')
              #cerebro.addanalyzer(bt.analyzers.DrawDown, _name='DrawDown')
              #cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name='AnnualReturn')
              
              # Print out the starting conditions
              print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) 
              
              # Run over everything (loop over the data)
              results = cerebro.run() 
              strat = results[0]
              
              # Print out the final result
              print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) 
          
          
              cerebro.plot(style='candle', numfigs=1, barup ='lime', bardown ='red', valuetags=False)
          1 Reply Last reply Reply Quote 0
          • A
            Aritz Lizaso last edited by

            Sorry, I have write in the wrong post!

            1 Reply Last reply Reply Quote 0
            • A
              Aritz Lizaso last edited by

              Many thanks for the answer. I cant find how can i change the buysell observer params. How can i do it? I tried this but the params didnt work.

              class MyBuySell(bt.observers.BuySell):
                  
                  params = (('barplot', True), ('bardist', 0.0))
                  
                  plotlines = dict(
                      buy=dict(marker='$\u21E7$', markersize=4.0),
                      sell=dict(marker='$\u21E9$', markersize=4.0)
                  )
              1 Reply Last reply Reply Quote 0
              • 1 / 1
              • First post
                Last post
              Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
              $(document).ready(function () { app.coldLoad(); }); }