Green candlesticks not appearing
-
Using default matplotlib or bokeh neither of them is showing candlestick chart properly.
Here is the code below, found on quickstart guide
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # For datetime objects import os.path # To manage paths import sys # To find out the script name (in argv[0]) from backtrader_plotting import Bokeh from backtrader_plotting.schemes import Tradimo # Import the backtrader platform import backtrader as bt # Create a Stratey class TestStrategy(bt.Strategy): params = ( ('maperiod', 15), ) 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 # To keep track of pending orders and buy price/commission self.order = None self.buyprice = None self.buycomm = None # Add a MovingAverageSimple indicator self.sma = bt.indicators.SimpleMovingAverage( self.datas[0], period=self.params.maperiod) # Indicators for the plotting show bt.indicators.ExponentialMovingAverage(self.datas[0], period=25) bt.indicators.WeightedMovingAverage(self.datas[0], period=25, subplot=True) bt.indicators.StochasticSlow(self.datas[0]) bt.indicators.MACDHisto(self.datas[0]) rsi = bt.indicators.RSI(self.datas[0]) bt.indicators.SmoothedMovingAverage(rsi, period=10) bt.indicators.ATR(self.datas[0], plot=False) 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: %.2f, Cost: %.2f, Comm %.2f' % (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: %.2f, Cost: %.2f, Comm %.2f' % (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 %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm)) def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % 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.dataclose[0] > self.sma[0]: # BUY, BUY, BUY!!! (with all possible default parameters) self.log('BUY CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.buy() else: if self.dataclose[0] < self.sma[0]: # SELL, SELL, SELL!!! (with all possible default parameters) self.log('SELL CREATE, %.2f' % 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, 'ZEEL.NS.csv') # Create a Data Feed data = bt.feeds.YahooFinanceCSVData( dataname=datapath, # Do not pass values before this date fromdate=datetime.datetime(2002, 1, 1), # Do not pass values before this date todate=datetime.datetime(2003, 12, 31), # Do not pass values after this date reverse=False) # 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=10) # Set the commission cerebro.broker.setcommission(commission=0.0) # Print out the starting conditions print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Run over everything cerebro.run() # Print out the final result print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Plot the result cerebro.plot(style='candlestick') #b = Bokeh(filename='chart.html',style='bar', plot_mode="single", scheme=Tradimo()) #cerebro.plot(b)
-
Which obviously suggests that the only thing you don't share is wrong: the data.
-
@backtrader the dataset seems ok
Date,High,Low,Open,Close,Volume,Adj Close 2002-07-01,39.138099670410156,38.48149871826172,38.847999572753906,38.878501892089844,4031529.0,30.347339630126953 2002-07-02,40.11539840698242,38.54249954223633,38.72579956054688,39.214500427246094,14152322.0,30.60960960388184 2002-07-03,39.764198303222656,38.86320114135742,39.03120040893555,39.56570053100586,8456845.0,30.883745193481445 2002-07-04,40.833099365234375,39.30609893798828,39.87110137939453,39.535099029541016,12745157.0,30.859865188598636 2002-07-05,40.00849914550781,39.01589965820313,40.00849914550781,39.351898193359375,6445895.0,30.71685791015625 2002-07-08,40.039100646972656,38.40510177612305,39.73360061645508,38.618900299072266,8225227.0,30.144695281982425 2002-07-09,39.15340042114258,37.88589859008789,38.2677001953125,37.977500915527344,10865999.0,29.64403915405273 2002-07-10,38.5884017944336,37.412498474121094,38.14550018310547,37.58050155639648,8238269.0,29.33416175842285 2002-07-11,38.14550018310547,36.86280059814453,37.412498474121094,37.85540008544922,12711851.0,29.548738479614254 2002-07-12,38.55780029296875,37.45840072631836,38.328800201416016,37.74850082397461,7378410.0,29.465293884277344 2002-07-15,37.8400993347168,35.290000915527344,37.824798583984375,35.7327995300293,12436803.0,27.89190673828125 2002-07-16,37.71789932250977,35.03030014038086,35.48849868774414,37.18349838256836,20568293.0,29.024272918701172 2002-07-17,37.1682014465332,36.08399963378906,36.8932991027832,36.6338005065918,9150981.0,28.595195770263672 2002-07-18,37.38199996948242,35.64120101928711,37.25979995727539,36.114601135253906,18480280.0,28.189922332763672 2002-07-19,37.45840072631836,36.23669815063477,36.23669815063477,36.51160049438477,14291424.0,28.49980354309082 2002-07-22,35.97710037231445,32.770301818847656,35.80910110473633,33.45750045776367,13678966.0,26.11587142944336 2002-07-23,34.75550079345703,32.23590087890625,33.54909896850586,34.46540069580078,15143604.0,26.902606964111328 2002-07-24,33.900299072265625,32.2510986328125,33.900299072265625,33.106300354003906,10235892.0,25.841739654541016 2002-07-25,35.09140014648437,33.060501098632805,34.297401428222656,33.518600463867195,7693444.0,26.1635684967041 2002-07-26,32.800899505615234,31.18219947814941,32.678699493408196,31.65559959411621,10417471.0,24.70936584472656 2002-07-29,32.35800170898437,30.23539924621582,30.54080009460449,30.663000106811523,12310549.0,23.93457794189453
-
The SimpleMovingAverage on the chart has an ending value of:
9178920.20
and your data has values in the30-40
range.Everything Ok!
-
@backtrader yes, the ohlc prices seem to be read wrong, everything instead of 30-40 range is read as eg. 883637.92 can this be tweaked to work as expected in YahooFinanceCSVData()?
-
The prices are not being read wrongly .... data which is not compatible with
YahooFinanceCSVData
is being fed (the Yahoo order is.: O H L C AC V and the order of your data is O H L C V AC)Option 1
- Extend
GenericCSVData
to keep your adjustedclose in place. - Create a filter which uses the adjusted close to adjust the prices - Docs - Filters
Option 2
- Extend
GenericCSVData
to keep your adjustedclose in place. - Override the
_loadline
method, call the original and when done ... adjust the prices with the already available adjusted close.
Option 3
- Read the data with
pandas
- Adjust the prices in the dataframe
- Use
PandasData
as your data feed
- Extend