Hi All,
Long overdue. In case it can be useful to her folks.
import datetime as dt
from backtrader import TimeFrame
from backtrader.feed import DataBase
from backtrader import date2num
from sqlalchemy import create_engine
class SQLiteData(DataBase):
params = (
('database', None),
('symbol', 'XBTUSD'),
('tick_value', 0.01),
('timeframe ', TimeFrame.Minutes),
('compression', 1),
('fromdate', dt.datetime(1900,1,1)),
('todate', dt.datetime.max),
)
def __init__(self):
try:
self.engine = create_engine('sqlite:///{0}'.format(self.p.database), echo=False)
self._timeframe = self.p.timeframe
self._compression = self.p.compression
self._dataname = '{0}'.format(self.p.symbol)
except Exception as ex:
print('Unable to open database {0} - {1}'.format(self.p.database, ex))
def start(self):
try:
self.conn = self.engine.connect()
sql_query = "SELECT `date`,`open`,`high`,`low`,`close`,`volume` FROM `historical_data` WHERE `symbol` = '" + self.p.symbol + "' AND `date` between '"+ self.p.fromdate.strftime("%Y-%m-%d %H:%M:%S") +"' and '" + self.p.todate.strftime("%Y-%m-%d %H:%M:%S") + "' ORDER BY `date` ASC"
#print(sql_query)
self.result = self.conn.execute(sql_query)
except Exception as ex:
print('Unable to read table historical_data from database {0} - {1}'.format(self.p.database, ex))
return
def stop(self):
self.engine.dispose()
def _load(self):
one_row = self.result.fetchone()
if one_row is None:
return False
self.lines.datetime[0] = date2num(dt.datetime.strptime(str(one_row[0]),'%Y-%m-%d %H:%M:%S')) # date parsing
self.lines.open[0] = float(one_row[1])
self.lines.high[0] = float(one_row[2])
self.lines.low[0] = float(one_row[3])
self.lines.close[0] = float(one_row[4])
self.lines.volume[0] = int(one_row[5])
self.lines.openinterest[0] = -1
return True