Problem with plotting buy sell arrows
-
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 usingtimeframe=bt.TimeFrame.Minutes, compression=5
Any help is appreciated.
Plot:
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')
-
@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:
Disable the standard observers in
cerebro
usingstdstats
and add the observers you may wish with the configuration of your choice. See: -
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? -
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), namelybarplot
to activate the plotting away from the price andbardist
to control the distance.