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!
-
The default configuration can be switched off when running
cerebro.run
with the parameterstdstats
.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
-
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) )