Do you know what the format for dataname in visual chart for a stock such as 'YHOO' is?
Is
data = vcstore.getdata(dataname='YHOO', fromdate=datetime(2016, 5, 15))
Correct?
Do you know what the format for dataname in visual chart for a stock such as 'YHOO' is?
Is
data = vcstore.getdata(dataname='YHOO', fromdate=datetime(2016, 5, 15))
Correct?
@backtrader Thanks, for your informative comments. What company would you recommend as a minute-bar data provider that is compatible with backtrader? I'd still like to use IB as the broker since my business partner likes them due to their cost structure.
@backtrader Thanks backorder!
@backtrader I updated to the last version of backtrader and I cannot get that dispatcher error however I'm getting a different issue. The code is very simple:
from __future__ import (absolute_import, division, print_function, unicode_literals)
import backtrader as bt
import time
class BuyOnGapStrategy(bt.Strategy):
def log(self, txt, doprint=False):
if doprint:
print('%s' % (txt))
def __init__(self):
self.log('******************* Strategy Created *********************', doprint = True)
def notify_data(self, data, status, *args, **kwargs):
# CONNECTED, DISCONNECTED, CONNBROKEN, NOTSUBSCRIBED, DELAYED, LIVE
self.log('DATA NOTIF: %s, %s' %( data._getstatusname(status), data._dataname), doprint = True)
def notify_store(self, msg, *args, **kwargs):
self.log('-> STORE NOTIF: %s' %(msg), doprint= True)
def notify_order(self, order):
pass
def notify_trade(self, trade):
pass
def next(self):
for indx in range(0, len(self.datas), 2):
datax = self.datas[indx]
datax2 = self.datas[indx+1]
if datax is not None and len(datax.datetime) > 0:
self.log("Sym %s, Time %s, 1-min Close %.2f" %(datax._dataname, datax.datetime.time(), datax.close[0]), doprint = True)
if datax2 is not None and len(datax2.datetime) > 0:
self.log("Sym %s, Time %s, 3-min Close %.2f" %(datax2._dataname, datax2.datetime.time(), datax2.close[0]), doprint = True)
if __name__ == '__main__':
all_syms = ['YHOO-STK-SMART-USD', 'CTXS-STK-SMART-USD', 'ADSK-STK-SMART-USD', 'ETFC-STK-SMART-USD', 'DISCA-STK-SMART-USD',
'QCOM-STK-SMART-USD', 'ADS-STK-SMART-USD', 'PVH-STK-SMART-USD', 'AMG-STK-SMART-USD', 'CMA-STK-SMART-USD']
storekwargs = dict(
host = "127.0.0.1", port = 4001,
clientId = 35, timeoffset = True,
reconnect = True, timeout = 10,
notifyall = False, _debug = False
)
ibstore = bt.stores.IBStore(**storekwargs)
cerebro = bt.Cerebro(exactbars = 1)
cerebro.setbroker(ibstore.getbroker())
datakwargs = dict(
timeframe = bt.TimeFrame.Minutes,
compression = 1,
qcheck = 0.5,
historical = False,
backfill_start = True,
backfill= True,
latethrough = True
)
for symbol in all_syms:
datax = ibstore.getdata(dataname=symbol, **datakwargs)
cerebro.resampledata(dataname=datax, timeframe = bt.TimeFrame.Minutes, compression = 1)
cerebro.resampledata(dataname=datax, timeframe = bt.TimeFrame.Minutes, compression = 3)
# Add the strategy
cerebro.addstrategy(BuyOnGapStrategy)
cerebro.run()
Here is message I get:
Server Version: 76
TWS Time at connection:20170317 11:58:19 CST
******************* Strategy Created *********************
-> STORE NOTIF: <error id=-1, errorCode=2104, errorMsg=Market data farm connecti
on is OK:usfarm>
-> STORE NOTIF: <error id=-1, errorCode=2106, errorMsg=HMDS data farm connection
is OK:ushmds>
DATA NOTIF: DELAYED, YHOO-STK-SMART-USD
DATA NOTIF: DELAYED, CTXS-STK-SMART-USD
DATA NOTIF: DELAYED, ADSK-STK-SMART-USD
DATA NOTIF: DELAYED, ETFC-STK-SMART-USD
DATA NOTIF: DELAYED, DISCA-STK-SMART-USD
DATA NOTIF: DELAYED, QCOM-STK-SMART-USD
DATA NOTIF: DELAYED, ADS-STK-SMART-USD
DATA NOTIF: DELAYED, PVH-STK-SMART-USD
DATA NOTIF: DELAYED, AMG-STK-SMART-USD
DATA NOTIF: DELAYED, CMA-STK-SMART-USD
Traceback (most recent call last):
File "ib_test.py", line 84, in <module>
cerebro.run()
File "C:\Users\Reza\trading\libs\backtrader\backtrader\cerebro.py", line 794,
in run
runstrat = self.runstrategies(iterstrat)
File "C:\Users\Reza\trading\libs\backtrader\backtrader\cerebro.py", line 924,
in runstrategies
self._runnext(runstrats)
File "C:\Users\Reza\trading\libs\backtrader\backtrader\cerebro.py", line 1240,
in _runnext
strat._next()
File "C:\Users\Reza\trading\libs\backtrader\backtrader\strategy.py", line 296,
in _next
super(Strategy, self)._next()
File "C:\Users\Reza\trading\libs\backtrader\backtrader\lineiterator.py", line
240, in _next
clock_len = self._clk_update()
File "C:\Users\Reza\trading\libs\backtrader\backtrader\strategy.py", line 285,
in _clk_update
newdlens = [len(d) for d in self.datas]
File "C:\Users\Reza\trading\libs\backtrader\backtrader\strategy.py", line 285,
in <listcomp>
newdlens = [len(d) for d in self.datas]
File "C:\Users\Reza\trading\libs\backtrader\backtrader\lineseries.py", line 43
2, in __len__
return len(self.lines)
File "C:\Users\Reza\trading\libs\backtrader\backtrader\lineseries.py", line 19
9, in __len__
return len(self.lines[0])
ValueError: __len__() should return >= 0
Hello,
I connect to IB and add two symbols (for each symbol, 1-min and 3-min bars) to the store; total 4 data feed. However, I get this error very often (not always):
13-Mar-17 15:25:03 ERROR Exception in message dispatch. Handler 'historical
Data' for 'historicalData' Traceback (most recent call last):
File "C:\Users\Reza\Anaconda3\lib\site-packages\ib\opt\dispatcher.py", line 44, in __call__results.append(listener(message))
File "C:\Users\Reza\trading\libs\backtrader\backtrader\stores\ibstore.py", line 920, in historicalData q = self.qs[tickerId] KeyError: 16777221
13-Mar-17 15:25:03 ERROR Exception in message dispatch. Handler 'historicalData' for 'historicalData' Traceback (most recent call last):
File "C:\Users\Reza\Anaconda3\lib\site-packages\ib\opt\dispatcher.py", line 44, in __call__ results.append(listener(message))
@backtrader Thanks for your reply. Yes, it works with some data files, but not with others. Is there anyway I can attach two files here as examples?
Sorry I cannot format the code correctly here.
When I have more than one symbols with two different time frames(min and day), the next function is not called: basically, start and stop are called but not the next.
Here is shortened code:
class TestInstrument():
def __init__(self):
self.symbol = None
self.order = None
self.live = False
self.i_macd = None
self.i_sma = None
self.tradable_today = False
self.no_longs = 0
self.no_shorts = 0
self.no_profitable_longs = 0
self.no_profitable_shorts = 0
self.current_position_is_long = None
self.profit = 0
class MACDStrategy(bt.Strategy):
params = dict(
initial_cash = None,
macd1 = 12, #12
macd2 = 26, #26
macdsig = 9,
smaperiod = 28, #28
exectype=bt.Order.Market,
max_investment_per_trade = 500000,
max_loss_perc_trade = 3000,
max_profit_perc_trade = 4000,
printlog = False,
savelog = False,
start_time = datetime.time(9, 35),
end_time = datetime.time(15, 30), #originally 35 not zero
enter_short_bound = 0.4, #0.3
exit_short_bound = 0,
enter_long_bound = -0.4,
output_dir = "d:\\glt\\output\\all\\",
)
def __init__(self):
self.current_date = None
self.market_hours = None
self.log_file = None
self.instruments = dict((self.datas[indx]._dataname, TestInstrument()) for indx in range(0, len(self.datas), 2))
if self.p.savelog:
self.log_file = open(self.p.output_dir + "@enter_short" + str(self.p.enter_short_bound) + "@enter_long" + str(self.p.enter_long_bound) + "@max_loss" + str(self.p.max_loss_perc_trade * self.p.max_investment_per_trade) + "@max_profit" + str(self.p.max_profit_perc_trade * self.p.max_investment_per_trade) + ".txt", "w")
self.optim_file = open(self.p.output_dir + 'optimization.csv', 'a')
for indx in range(0, len(self.datas), 2):
datax = self.datas[indx]
datax_day = self.datas[indx+1]
instrument_name = datax._dataname
self.instruments[instrument_name].i_macd = bt.indicators.MACD(datax, period_me1=self.p.macd1, period_me2=self.p.macd2, period_signal=self.p.macdsig)
self.instruments[instrument_name].i_sma = bt.indicators.SMA(datax_day, period=self.p.smaperiod)
self.log('Signals are created for: %s' %(instrument_name))
print('******************* Strategy Created *********************')
def nextstart(self):
self.log('--------------------------------------------------')
self.log('nextstart called with len %d' %len(self))
self.log('--------------------------------------------------')
super(MACDStrategy, self).nextstart()
def next(self, frompre=False):
self.log("Next is called", doprint = True)
#some logic here
def start(self):
self.log('Start', doprint = True)
pass
def stop(self):
self.log('Stop', doprint = True)
if __name__ == '__main__':
mydir='d:\\glt\\sp500energy1516_market' # minute based data
all_syms = os.listdir(mydir)
mycash = 500000 * len(all_syms) / 4 # leverage 4
cerebro = bt.Cerebro(exactbars = False)
cerebro.broker.setcash(mycash)
for file in all_syms:
# Create a Data Feed
data = bt.feeds.GenericCSVData(
dataname=mydir + "\\" + file,
#(2015, 12, 20, 7, 30)-(2016, 2, 22, 16, 0) -> 2 22 Jan
#(2016, 2, 24, 7, 30)-(2016, 4, 25, 16, 0) -> 5 25 April
fromdate=datetime.datetime(2015, 1, 1, 7, 30),
todate=datetime.datetime(2016, 12, 30, 16, 0),
nullvalue=0.0,
dtformat=('%Y%m%d'),
tmformat = ('%H%M'),
datetime=0,
time=1,
open=2,
high=3,
low=4,
close=5,
volume=6,
openinterest=7)
cerebro.adddata(data, name = file[:-4])
cerebro.resampledata(data, timeframe=bt.TimeFrame.Days, compression = 1, name = file[:-4] + "_d")
#Set the commission
#cerebro.broker.setcommission(commission=0)
cerebro.broker.setcommission(commission=0.00003, margin= None, mult=1.0, commtype=None, percabs=True, stocklike=True, leverage=4.0)
#Set the slippage
cerebro.broker.set_slippage_perc(0.001, slip_open=True, slip_limit=True, slip_match=True, slip_out=False)
cerebro.addanalyzer(bt.analyzers.Returns)
# Add a strategy
cerebro.optstrategy(MACDStrategy,
enter_short_bound = [0.5, 0.45],
enter_long_bound = [-0.5, -0.45],
max_loss_perc_trade = [0.018, 0.016, 0.014, 0.012],
max_profit_perc_trade = [0.018, 0.016, 0.014, 0.012],
initial_cash = mycash, max_investment_per_trade = 500000, savelog = True)
#Run over everything
cerebro.run()
@rastegarr The version that I'm using is 1.9.27.105.
I have an strategy that has multiple symbols and each symbols has two simultaneous data feeds (minute and day frequency). So if I have N symbols, I have 2N datafeeds that are added to Cerebro.
I could run the strategy with no problem previously, but after updating backtrader to the last two versions it doesn't work anymore. The same strategy works fine if I only have one symbol (still with two data feeds -- minute and day frequency). Any idea what that can be? I can send you the code if it helps.