Skip to content
Permalink
Browse files

Add support for packages and frompackages

  • Loading branch information
mementum committed Feb 14, 2017
1 parent 2a11ee2 commit 1146c83d9f9832630e97daab3ec7359705dc2c77
Showing with 64 additions and 1 deletion.
  1. +15 −0 backtrader/errors.py
  2. +49 −1 backtrader/metabase.py
@@ -34,3 +34,18 @@ class StrategySkipError(BacktraderError):
'''Requests the platform to skip this strategy for backtesting. To be
raised during the initialization (``__init__``) phase of the instance'''
pass


class ModuleImportError(BacktraderError):
'''Raised if a class requests a module to be present to work and it cannot
be imported'''
def __init__(self, message, *args):
super(ModuleImportError, self).__init__(message)
self.args = args


class FromModuleImportError(ModuleImportError):
'''Raised if a class requests a module to be present to work and it cannot
be imported'''
def __init__(self, message, *args):
super(FromModuleImportError, self).__init__(message, *args)
@@ -25,7 +25,8 @@
import itertools
import sys

from .utils.py3 import zip
import backtrader as bt
from .utils.py3 import zip, string_types


def findbases(kls, topclass):
@@ -205,21 +206,68 @@ def __new__(meta, name, bases, dct):
# (and hence "repetition")
newparams = dct.pop('params', ())

packs = 'packages'
newpackages = tuple(dct.pop(packs, ())) # remove before creation

fpacks = 'frompackages'
fnewpackages = tuple(dct.pop(fpacks, ())) # remove before creation

# Create the new class - this pulls predefined "params"
cls = super(MetaParams, meta).__new__(meta, name, bases, dct)

# Pulls the param class out of it - default is the empty class
params = getattr(cls, 'params', AutoInfoClass)

# Pulls the packages class out of it - default is the empty class
packages = tuple(getattr(cls, packs, ()))
fpackages = tuple(getattr(cls, fpacks, ()))

# get extra (to the right) base classes which have a param attribute
morebasesparams = [x.params for x in bases[1:] if hasattr(x, 'params')]

# Get extra packages, add them to the packages and put all in the class
for y in [x.packages for x in bases[1:] if hasattr(x, packs)]:
packages += tuple(y)

for y in [x.frompackages for x in bases[1:] if hasattr(x, fpacks)]:
fpackages += tuple(y)

cls.packages = packages + newpackages
cls.frompackages = fpackages + fnewpackages

# Subclass and store the newly derived params class
cls.params = params._derive(name, newparams, morebasesparams)

return cls

def donew(cls, *args, **kwargs):
clsmod = sys.modules[cls.__module__]
# import specified packages
for p in cls.packages:
if isinstance(p, (tuple, list)):
p, palias = p
else:
palias = p

pmod = __import__(p)
setattr(clsmod, palias, pmod)

# import from specified packages - the 2nd part is a string or iterable
for p, frompackage in cls.frompackages:
if isinstance(frompackage, string_types):
frompackage = (frompackage,) # make it a tuple

for fp in frompackage:
if isinstance(fp, (tuple, list)):
fp, falias = fp
else:
fp, falias = fp, fp # assumed is string

# complain "not string" without fp (unicode vs bytes)
pmod = __import__(p, fromlist=[str(fp)])
pattr = getattr(pmod, fp)
setattr(clsmod, falias, pattr)

# Create params and set the values from the kwargs
params = cls.params()
for pname, pdef in cls.params._getitems():

0 comments on commit 1146c83

Please sign in to comment.
You can’t perform that action at this time.