Hello there
I am very new with backtrader and I am trying to experiment a little. As of now I am trying to backtest a strategy based on a machine learning prediction model that forecast based on a categorized pattern of data which refer to the current tick and the -1 and -2 tick datas.
This is the code
import backtrader as bt
import datetime as dt
import backtrader.analyzer as bta
import matplotlib
def forecast1(Lista1):
import xgboost as xgb
import numpy as np
model1 = xgb.Booster()
model1.load_model('20210406-btcusdt-CC1.model')
X = np.reshape(Lista1, (1, 7))
XX = xgb.DMatrix(X)
Risultato1 = model1.predict(XX)
return Risultato1
def binningitX(ListaX):
bins = [-99999.0, -1.000001, -0.2000001, -0.1000001, -0.04000001, -0.01500001, -0.005000001
+ 0.005000001, +0.015000001, +0.040000001, +0.10000001, +0.2000001, +1.0000001, +99999.0]
label = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
xCat = []
for item in range(0, len(listaX)):
for i in range(0, len(bins)):
if listaX[item] > bins[i] and listaX[item] < bins[i + 1]:
xcat[item] = label[i]
return xCat
class MyBooster(bt.Strategy):
# param1 = [0.5, 1, 1.5, 2, 2.5]
# param2 = [0.5, 1, 1.5, 2, 2.5]
def log(self,txt,dt=None):
dt = df or self.datas[0].datetime.date(0)
print('%s, %s' % (dt.isoformat(), txt))
def __init__(self):
# self.dataclose = self.datas[0].close
# self.dataclose2 = self.datas[-2].close
Close_change1 = self.datas[0].close - self.datas[-1].close / self.datas[-1].close
Close_change2 = self.datas[-1].close - self.datas[-2].close / self.datas[-2].close
High_change = self.datas[0].high - self.datas[-1].high / self.datas[-1].high
Low_change = self.datas[0].low - self.datas[-1].low / self.datas[-1].low
Volume_change1 = self.datas[0].volume - self.datas[-1].volume / self.datas[-1].volume
Volume_change2 = self.datas[-1].volume - self.datas[-2].volume / self.datas[-2].volume
Vola_change = (self.datas[0].high - self.datas[0].low) - (self.datas[-1].high - self.datas[-1].low) / \
(self.data[-1].high - self.datas[-1].low)
def next(self):
X = [Close_change1, Close_change2, High_change, Low_change, Volume_change1, Volume_change2, Vola_change]
XX = binningitX(X)
Prev_close = forecast1(XX)
if Prev_close > self.datas[0].close: # VAI LONG
trade = 'LO'
takeprofit = self.datas[0].close * (1 + param1 * ((Prev_Close - self.datas[0].close) / 100)) # VAI LONG CON TP > diff
stoploss = self.datas[0].close * (1 + param2 * (-(Prev_Close - self.datas[0].close) / 100)) # E ST < diff
self.log('BUY CREATE, %.2f' % self.dataclose[0])
self.buy()
if Prev_close < self.datas[0].close: # VAI SHORT
trade = 'SH'
takeprofit = self.datas[0].close * (1 + param1 * ((Prev_Close - self.datas[0].close) / 100)) # VAI SHORT CON TP < diff
stoploss = self.datas[0].close * (1 + param2 * (-(Prev_Close - self.datas[0].close) / 100)) # E ST > diff
self.log('SELL CREATE, %.2f' % self.dataclose[0])
self.sell()
Create a cerebro entity
cerebro = bt.Cerebro()
Add a strategy
cerebro.addstrategy(MyBooster)
Set our desired cash start
cerebro.broker.setcash(1000.0)
Create a Data Feed
data = bt.feeds.GenericCSVData(
dataname="btcusd-hourly.csv",
timeframe=bt.TimeFrame.Minutes,
compression='60',
fromdate=dt.datetime(2015, 1, 1),
todate=dt.datetime(2021, 4, 8),
nullvalue=0.0,
dtformat=('%Y-%m-%d'),
tmformat=('%H:%M:%S'),
datetime=0,
time=1,
open=2,
high=3,
low=4,
close=5,
volume=6,
openinterest=-1)
Add the Data Feed to Cerebro
cerebro.adddata(data)
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())
I am. sure I did something very wrong, but I am not able to understand how to get rid of the index out of range error I receive when I run the whole thing.
Is someone able to help ?