For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
Extending Datafeeds
-
Greetings all, I am a newbie in Backtrader.
I would like to insert the highs and lows of the previous day in the 1H chart.
I've read the documentation and posts, but I haven't been able to get it to work.Thanks in advance to those who will teach me where I'm wrong!
########################################################################### # # I would like to plot the previous day's High and Low in the hourly chart. # ########################################################################### import pandas as pd import numpy as np import yfinance as yf import backtrader as bt import backtrader.feeds as btfeeds import datetime as dt import pytz df_1h = yf.download("EURUSD=X", period='3mo', interval='1h') # df_1h.head(3) # Remove the time zone offset df_1h.index = df_1h.index.tz_convert(None) ### Resemple Daily # Resample to daily data daily_data = df_1h.resample('1D').agg({ 'Open': 'first', 'High': 'max', 'Low': 'min', 'Close': 'last', # 'Volume': 'sum' }) # daily_data ## Calculate High Low Shift points on daily daily_data["High_Dy"] = daily_data["High"].shift(1) daily_data["Low_Dy"] = daily_data["Low"].shift(1) # Just keep the two shifted columns and delete NaN daily_data.dropna(inplace=True) daily_data = daily_data[["High_Dy", "Low_Dy"]] # Merging df_1h e hourly_data = df_1h.copy() plot_data = pd.merge_asof(hourly_data, daily_data, left_index=True, right_index=True) plot_data.dropna(inplace=True) # Insert 100 in the volume column, I saw that the absence of volume causes problems, sometime, plot_data['Volume'] = 1000 # plot_data.head(3) # Extending a Datafeed <<<< ===================================================== MY BIG PROBLEM !!!! class PandasDataOptix(btfeeds.PandasData): thenewlines = ['High_Dy', 'Low_Dy'] mydict = dict( lines=tuple(thenewlines), datafieds=bt.feeds.PandasData.datafields + thenewlines, ) MyPandasClass = type('mypandasname', (bt.feeds.PandasData,), mydict) class StrategyOptix(bt.Strategy): def __init__(self): pass # Creo le due emas self.ema1 = bt.ind.EMA(self.data.close, period = 200) self.sma1 = bt.ind.SMA(self.data.High_Dy, period = 1) # <<<< ====== ??? Tested it does not plot anything and gives an error self.hi_dy = bt.ind.SMA(self.data.lines.High_Dy, period = 1) # <<<< ====== ???Tested it does not plot anything and gives an error print(data) def next(self): # Print the current data print("Datetime:", self.data.datetime.datetime()) print("Open:", self.data.open[0]) print("High:", self.data.high[0]) print("Low:", self.data.low[0]) print("Close:", self.data.close[0]) print("Volume:", self.data.volume[0]) print("Open Interest:", self.data.openinterest[0]) print("High_Dy:", self.data.High_Dy[0]) ## <<<< ====== ??? print("Low_Dy:", self.data.Low_Dy[0]) ## <<<< ====== ??? print("====================================") # From the data printout I don't see the two columns ['High_Dy', 'Low_Dy'] # Create a cerebro entity # cerebro = bt.Cerebro(stdstats=False) cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(StrategyOptix) # Pass it to the backtrader datafeed and add it to the cerebro PandasDataOptix data = PandasDataOptix(dataname=plot_data) cerebro.adddata(data) # Run over everything cerebro.run() # cerebro.plot() cerebro.plot(style='candle', iplot=False, # False volume = False, barupfill = False, bardownfill = False, barup='green', bardown='red')
-
I found a solution....!
Being a novice, it will certainly be improved.
########################################################################### # # I would like to plot the previous day's High and Low in the hourly chart. # ########################################################################### import pandas as pd import numpy as np import yfinance as yf import backtrader as bt import backtrader.feeds as btfeeds import datetime as dt # import pytz df_1h = yf.download("EURUSD=X", period='3mo', interval='1h') # df_1h.head(3) # Remove the time zone offset df_1h.index = df_1h.index.tz_convert(None) ### Resemple Daily # Resample to daily data daily_data = df_1h.resample('1D').agg({ 'Open': 'first', 'High': 'max', 'Low': 'min', 'Close': 'last', }) # daily_data ## Calculate High Low Shift points on daily daily_data["High_Dy"] = daily_data["High"].shift(1) daily_data["Low_Dy"] = daily_data["Low"].shift(1) # Just keep the two shifted columns and delete NaN daily_data.dropna(inplace=True) daily_data = daily_data[["High_Dy", "Low_Dy"]] # Merging df_1h e hourly_data = df_1h.copy() plot_data = pd.merge_asof(hourly_data, daily_data, left_index=True, right_index=True) plot_data.dropna(inplace=True) # Insert 0 in the volume column, insert OpenInterest = 0, plot_data['Volume'] = 0 plot_data.insert(5, "OpenInterest", 0) plot_data.drop('Adj Close', axis=1, inplace=True) ######## Dynamic class creation ########## lines = ('High_Dy', 'Low_Dy') params = (('High_Dy', -1), ('Low_Dy', -1), ) datafields = btfeeds.PandasData.datafields + ( ['High_Dy', 'Low_Dy']) mydict = dict( lines=tuple(lines), params=params, datafields=bt.feeds.PandasData.datafields + list(lines), ) PandasDataOptix = type('PandasDataOptix', (btfeeds.PandasData,), mydict) class StrategyOptix(bt.Strategy): def __init__(self): # Plot High & Low Daily self.hi_dy = bt.ind.SMA(self.data.lines.High_Dy, period = 1) self.lo_dy = bt.ind.SMA(self.data.lines.Low_Dy, period = 1) def next(self): pass # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(StrategyOptix) # Pass it to the backtrader datafeed and add it to the cerebro PandasDataOptix data = PandasDataOptix(dataname=plot_data) cerebro.adddata(data) # Run over everything cerebro.run() cerebro.plot(style='candle', iplot=False, volume = False, barupfill = False, bardownfill = False, barup='green', bardown='red')