Module backtrader.feeds.vchart
Expand source code
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import datetime
import struct
import os.path
from .. import feed
from .. import TimeFrame
from ..utils import date2num
class VChartData(feed.DataBase):
'''
Support for `Visual Chart <www.visualchart.com>`_ binary on-disk files for
both daily and intradaily formats.
Note:
- ``dataname``: to file or open file-like object
If a file-like object is passed, the ``timeframe`` parameter will be
used to determine which is the actual timeframe.
Else the file extension (``.fd`` for daily and ``.min`` for intraday)
will be used.
'''
def start(self):
super(VChartData, self).start()
# Not yet known if a extension is needed
self.ext = ''
if not hasattr(self.p.dataname, 'read'):
# assume is a string because it has no write method
if self.p.dataname.endswith('.fd'):
self.p.timeframe = TimeFrame.Days
elif self.p.dataname.endswith('.min'):
self.p.timeframe = TimeFrame.Minutes
else:
# Neither fd nor min ... just the code, assign extension
if self.p.timeframe == TimeFrame.Days:
self.ext = '.fd'
else:
self.ext = '.min'
if self.p.timeframe >= TimeFrame.Days:
self.barsize = 28
self.dtsize = 1
self.barfmt = 'IffffII'
else:
self.dtsize = 2
self.barsize = 32
self.barfmt = 'IIffffII'
self.f = None
if hasattr(self.p.dataname, 'read'):
# A file has been passed in (ex: from a GUI)
self.f = self.p.dataname
else:
dataname = self.p.dataname + self.ext
# Let an exception propagate
self.f = open(dataname, 'rb')
def stop(self):
if self.f is not None:
self.f.close()
self.f = None
def _load(self):
if self.f is None:
return False
# Let an exception propagate to let the caller know
bardata = self.f.read(self.barsize)
if not bardata:
return False
bdata = struct.unpack(self.barfmt, bardata)
# Years are stored as if they had 500 days
y, md = divmod(bdata[0], 500)
# Months are stored as if they had 32 days
m, d = divmod(md, 32)
dt = datetime.datetime(y, m, d)
if self.dtsize > 1: # Minute Bars
# Daily Time is stored in seconds
hhmm, ss = divmod(bdata[1], 60)
hh, mm = divmod(hhmm, 60)
dt = dt.replace(hour=hh, minute=mm, second=ss)
self.lines.datetime[0] = date2num(dt)
o, h, l, c, v, oi = bdata[self.dtsize:]
self.lines.open[0] = o
self.lines.high[0] = h
self.lines.low[0] = l
self.lines.close[0] = c
self.lines.volume[0] = v
self.lines.openinterest[0] = oi
return True
class VChartFeed(feed.FeedBase):
DataCls = VChartData
params = (('basepath', ''),) + DataCls.params._gettuple()
def _getdata(self, dataname, **kwargs):
maincode = dataname[0:2]
subcode = dataname[2:6]
datapath = os.path.join(self.p.basepath,
'RealServer', 'Data',
maincode, subcode, # 01 00XX
dataname)
newkwargs = self.p._getkwargs()
newkwargs.update(kwargs)
kwargs['dataname'] = datapath
return self.DataCls(**kwargs)
Classes
class VChartData (*args, **kwargs)
-
Support for
Visual Chart <www.visualchart.com>
_ binary on-disk files for both daily and intradaily formats.Note
dataname
: to file or open file-like object
If a file-like object is passed, the
timeframe
parameter will be used to determine which is the actual timeframe.Else the file extension (
.fd
for daily and.min
for intraday) will be used.Expand source code
class VChartData(feed.DataBase): ''' Support for `Visual Chart <www.visualchart.com>`_ binary on-disk files for both daily and intradaily formats. Note: - ``dataname``: to file or open file-like object If a file-like object is passed, the ``timeframe`` parameter will be used to determine which is the actual timeframe. Else the file extension (``.fd`` for daily and ``.min`` for intraday) will be used. ''' def start(self): super(VChartData, self).start() # Not yet known if a extension is needed self.ext = '' if not hasattr(self.p.dataname, 'read'): # assume is a string because it has no write method if self.p.dataname.endswith('.fd'): self.p.timeframe = TimeFrame.Days elif self.p.dataname.endswith('.min'): self.p.timeframe = TimeFrame.Minutes else: # Neither fd nor min ... just the code, assign extension if self.p.timeframe == TimeFrame.Days: self.ext = '.fd' else: self.ext = '.min' if self.p.timeframe >= TimeFrame.Days: self.barsize = 28 self.dtsize = 1 self.barfmt = 'IffffII' else: self.dtsize = 2 self.barsize = 32 self.barfmt = 'IIffffII' self.f = None if hasattr(self.p.dataname, 'read'): # A file has been passed in (ex: from a GUI) self.f = self.p.dataname else: dataname = self.p.dataname + self.ext # Let an exception propagate self.f = open(dataname, 'rb') def stop(self): if self.f is not None: self.f.close() self.f = None def _load(self): if self.f is None: return False # Let an exception propagate to let the caller know bardata = self.f.read(self.barsize) if not bardata: return False bdata = struct.unpack(self.barfmt, bardata) # Years are stored as if they had 500 days y, md = divmod(bdata[0], 500) # Months are stored as if they had 32 days m, d = divmod(md, 32) dt = datetime.datetime(y, m, d) if self.dtsize > 1: # Minute Bars # Daily Time is stored in seconds hhmm, ss = divmod(bdata[1], 60) hh, mm = divmod(hhmm, 60) dt = dt.replace(hour=hh, minute=mm, second=ss) self.lines.datetime[0] = date2num(dt) o, h, l, c, v, oi = bdata[self.dtsize:] self.lines.open[0] = o self.lines.high[0] = h self.lines.low[0] = l self.lines.close[0] = c self.lines.volume[0] = v self.lines.openinterest[0] = oi return True
Ancestors
Class variables
var alias
var aliased
var frompackages
var linealias
var packages
var params
var plotinfo
var plotlines
Methods
def start(self)
-
Expand source code
def start(self): super(VChartData, self).start() # Not yet known if a extension is needed self.ext = '' if not hasattr(self.p.dataname, 'read'): # assume is a string because it has no write method if self.p.dataname.endswith('.fd'): self.p.timeframe = TimeFrame.Days elif self.p.dataname.endswith('.min'): self.p.timeframe = TimeFrame.Minutes else: # Neither fd nor min ... just the code, assign extension if self.p.timeframe == TimeFrame.Days: self.ext = '.fd' else: self.ext = '.min' if self.p.timeframe >= TimeFrame.Days: self.barsize = 28 self.dtsize = 1 self.barfmt = 'IffffII' else: self.dtsize = 2 self.barsize = 32 self.barfmt = 'IIffffII' self.f = None if hasattr(self.p.dataname, 'read'): # A file has been passed in (ex: from a GUI) self.f = self.p.dataname else: dataname = self.p.dataname + self.ext # Let an exception propagate self.f = open(dataname, 'rb')
def stop(self)
-
Expand source code
def stop(self): if self.f is not None: self.f.close() self.f = None
Inherited members
class VChartFeed
-
Expand source code
class VChartFeed(feed.FeedBase): DataCls = VChartData params = (('basepath', ''),) + DataCls.params._gettuple() def _getdata(self, dataname, **kwargs): maincode = dataname[0:2] subcode = dataname[2:6] datapath = os.path.join(self.p.basepath, 'RealServer', 'Data', maincode, subcode, # 01 00XX dataname) newkwargs = self.p._getkwargs() newkwargs.update(kwargs) kwargs['dataname'] = datapath return self.DataCls(**kwargs)
Ancestors
Class variables
var DataCls
-
Support for
Visual Chart <www.visualchart.com>
_ binary on-disk files for both daily and intradaily formats.Note
dataname
: to file or open file-like object
If a file-like object is passed, the
timeframe
parameter will be used to determine which is the actual timeframe.Else the file extension (
.fd
for daily and.min
for intraday) will be used. var frompackages
var packages
var params