Updating the thread for people facing the same problem. This is directly related to future contracts. IBPy looks for m_includedExpired to be true to dish out expire futures minutes data.
A possible solution to circumvent this is provided by backtrader here https://community.backtrader.com/topic/1533/extract-historical-expired-futures-contract-data-from-ib/2
Floating point arithmetic.
I have written a system which uses high precision Decimals. Backtrader uses Floats.
I run a backtest through my system to verify the output of BT.
To do this, I must convert the source prices used in BT from Floats into Decimals.
After some iterations, with spreads involving subtraction and division, my indicators begin to diverge, presumably due to the increased rounding accuracy.
I would prefer to convert BT to use Decimals and this is why I asked the question.
Without searching the entire codebase for occurences of all numbers, I would like to ask the creator of this library for his view on how best to do this.
found my issue:
A StopLimit order requires the plimit parameter, to specify at which price to activate the limit order, somehow I managed to get through backtesting without setting it, but interactive broker didn't like it.
apologies for the noise.
Great thanks, exactly what I needed.
I just changed the buy / sell signals as per the below:
if self.rsi <= (np.percentile([self.rsiLLV, self.rsiHHV], self.p.threshold_Buy)):
self.order = self.buy()
if self.rsi >= (np.percentile([self.rsiLLV, self.rsiHHV], self.p.threshold_Sell)):
self.order = self.sell()
Many thanks again
I had a similar problem and resolved following way.
First, there is a base strategy class that can verify if date is within interval:
params = (
date = self.data.datetime.datetime(0)
if date >= self.p.start_date and date <= self.p.end_date:
The methold within_range() is called in self() of derived class:
if not self.within_range():
Then I have a function to adjust the dates that will be loaded from the feed:
def adjust_start_date(date, *params):
maximum = 0
for p in params:
if isinstance(p, int):
if p > maximum:
maximum = p
# For every week there are only 5 trading days (stocks)
days = math.ceil(maximum * 7/5)
adjusted = date - datetime.timedelta(days = days)
This function is used to adjust the date of the feed. So there are two start dates: one for the feed, other for the strategy:
feed_start_date = adjust_start_date(start_date, param1, param2, param3)
cerebro.adddata(bt.feeds.GenericCSVData(fromdate = feed_start_date, todate=end_date))
param1 = param1,
param2 = param2,
param3 = param3,
start_date = feed_start_date,
end_date = end_date
import backtrader as bt
from datetime import datetime
params = (('pfast', 10), ('pslow', 30),)
sma1, sma2 = bt.ind.SMA(period=self.p.pfast), bt.ind.SMA(period=self.p.pslow)
self.signal_add(bt.SIGNAL_LONG, bt.ind.CrossOver(sma1, sma2))
cerebro = bt.Cerebro(maxcpus=1, writer=True)
data = bt.feeds.YahooFinanceData(dataname='MSFT',
fromdate=datetime(2011, 1, 1),
todate=datetime(2012, 12, 31))
pfast=range(6, 16, 2),
pslow=range(15, 40, 5),
cerebro.addwriter(bt.WriterFile, csv=True, out="test")
I was able to save the data after enable maxcpus=1 and set the writer opt as a True.