Strategy Selection Pattern
-
with in the article Strategy Selection you speak of how to run multiple strategies separately. The pattern you seem to be using is called the singleton pattern
class StFetcher(object): _STRATS = [St0, St1] def __new__(cls, *args, **kwargs): idx = kwargs.pop('idx') obj = cls._STRATS[idx](*args, **kwargs) return obj
this pattern is great for a strategy selection type use case. However, I want to be able to change the
cerebro
fromoptstrategy()
toaddstrategy()
so that I can A: run the code live and B: be able to spin up multiple strategies at the same time on the same broker. Could you give me an example of how I could use the same pattern but instead of returning one strategy at a time, return as many as I need?Thanks,
-
@backtrader would the best pattern be something similar to attached code, the idea is this would allow the master to control sub strategies :
class NewSubStrategy(): def foo(self): ##Strategy code here class Master(bt.Strategy): def __init__(self): ##Lines here #Int new strategy (static version) self.st1 = NewSubStrategy self.st2 = NewSubStrategy def next(self): #Master strategy logic #call sub strategy on next() self.st1.foo(self) self.st2.foo(self)
-
after trying different things through out the day, I found the best pattern was to just make a strategy as a indicator and spawn a new instance of a indicator as needed.
-
I don't think the
StFetcher
class is a singleton. It is simply a factory, which can be easily expressed in Python as an opaque class thanks to the fact that__new__
method can return instances of actually anything.@blonc said in Strategy Selection Pattern:
I found the best pattern was to just make a strategy as a indicator and spawn a new instance of a indicator as needed
But in this case, the strategy is just calculating output values for the defined lines, or are you also executing orders from it?
-
@backtrader singleton, in the sense that I believe it can only return one instance at a time of anything.
The situation I am trying to achieve would also be executing orders. The concept I am trying to achieve is to have many strategies all being monitored by a master strategy. This way, the master strategy could be using a markov chain to monitor returns to turn on and off individual strategies based on the total returns of all strategies. It seems the best path is to , correct me if wrong, put the strategies logic into indicators and bring them into one master strategy.
-
That's a factory returning a single item, but not a singleton (
Store
subclasses, for exampleIBStore
for Interactive Brokers because only one connection to TWS is expected, are implemented as singletons, although someone could implement aStore
which isn't a singleton)Sub-strategies is not a pattern which does exist in backtrader. Using
Indicator
instances could do the trick.- Pass the
Strategy
(actuallyself
inside__init__
) to the indicator as a named (and declared) parameter - Use that reference to the strategy to execute operations
- Pass the
-
@backtrader i keep getting the error of
maximum recursion depth
im sure this has to do with how things are set up in the backend. could you give me some simple sudo code with what you were talking:@backtrader said in Strategy Selection Pattern:
Sub-strategies is not a pattern which does exist in backtrader. Using
Indicator
instances could do the trick.- Pass the
Strategy
(actuallyself
inside__init__
) to the indicator as a named (and declared) parameter - Use that reference to the strategy to execute operations
just add the required to bellow sudo to bellow, no need to include lines or anything:
class Sub(bt.Indicator): def __init__(self): def next(self): class Master(bt.Strategy): def __init__(self): def next(self):
- Pass the
-
class Sub(bt.Indicator): params = dict(mystrategy=None) def __init__(self): def next(self): class Master(bt.Strategy): def __init__(self): theindicator = Sub(mystrategy=self) def next(self):
-
Of course, the
maximum recursion depth
trace would/could help. -
@backtrader thats perfect, the two way communication works brilliantly while still retaining all of the passing of datas and so on.
-
@backtrader framework question. Since,
theindicator = Sub(mystrategy=self)
is defined with-in__init__
ofclass Master(bt.Strategy)
it seems to run through all of the lines provided forclass Sub(bt.Indicator):
before moving on to the next declared item in__init__
of Master. If receiving realtime data willclass Sub(bt.Indicator):
automatically update or will i need to call it with in the Master to let it know there is new info. -
@backtrader for two way communication to happen IE
one -> many
andmany->one
i found the following gives the desired results. the issue i ended up finding with the method of using indicators was that when youinitialize
thetheindicator = Sub(mystrategy=self)
for a class withbt.Indicator
. it would go up to that indicator and run through all lines with out stopping . ... creating a generic class and calling sub-strategynext()
with in the masternext()
. if u know a better way let me know.class SubStrategy(): def __init__(self,mystrategy,data_feed): #passes update to master self.master_comm = mystrategy def next(self): #example to send buy signal self.master_comm.buy() class Master(bt.Strategy): def __init__(self): #removed bt.indicator from class Sub() #the bellow seems to give desired results self.st1 = SubStrategy(mystrategy=self, data_feed=self.data0) def next(self): self.st1.next(self)
-
You have to disable
runonce
to avoid pre-calculation of the indicators, which in your case have to tick like in real-time at the pace of the strategy. -
@blonc said in Strategy Selection Pattern:
The concept I am trying to achieve is to have many strategies all being monitored by a master strategy. This way, the master strategy could be using a markov chain to monitor returns to turn on and off individual strategies based on the total returns of all strategies. It seems the best path is to , correct me if wrong, put the strategies logic into indicators and bring them into one master strategy.
@backtrader said in Strategy Selection Pattern:
Sub-strategies is not a pattern which does exist in backtrader. Using
Indicator
instances could do the trick.Was also thinking about utilizing the concept of having a "master" strategy turning on and off "micro strategies", so I'm glad I found this post :)
I can think of a lot of use cases for using a master strategy that based on a wide overview of a market/s can control what micro strategies are suited to be used.the idea of using indicators as sub-strategies seem brilliant (haven't tested it yet).
but from my understanding strategies can be better analyzed and give valuable insights. I hope we can wider the discussion just to explore more solutions (as @backtrader mentioned nested strategies are not supported)one idea I have that I don't think break backtrader structure is:
declaring a 'master' that run first and based on whatever user logic it creates a 'signal dictionary' that is then passed to all other micro strategies. allowing them to decide if to run or not in next().
this way all strategies are kept in the same level of operation (not nested)