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



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


  • administrators

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

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

    An example



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


  • Sorry, I have write in the wrong post!



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

Log in to reply
 

});