Skip to content

Commit

Permalink
add listener to get notified about live events
Browse files Browse the repository at this point in the history
  • Loading branch information
verybadsoldier committed Jul 17, 2020
1 parent 18cf1a7 commit 794a7ec
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
1 change: 1 addition & 0 deletions backtrader/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
from .strategy import *

from .writer import *
from .listener import *

from .signal import *

Expand Down
24 changes: 24 additions & 0 deletions backtrader/cerebro.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ def __init__(self):
self.storecbs = list()
self.datacbs = list()
self.signals = list()
self.listeners = list()
self._signal_strat = (None, None, None)
self._signal_concurrent = False
self._signal_accumulate = False
Expand Down Expand Up @@ -623,6 +624,9 @@ def addwriter(self, wrtcls, *args, **kwargs):
'''
self.writers.append((wrtcls, args, kwargs))

def addlistener(self, lstcls, *args, **kwargs):
self.listeners.append((lstcls, args, kwargs))

def addsizer(self, sizercls, *args, **kwargs):
'''Adds a ``Sizer`` class (and args) which is the default sizer for any
strategy added to cerebro
Expand Down Expand Up @@ -1093,6 +1097,7 @@ def run(self, **kwargs):
self._dopreload = False

self.runwriters = list()
self.runlisteners = list()

# Add the system default writer if requested
if self.p.writer is True:
Expand All @@ -1104,6 +1109,10 @@ def run(self, **kwargs):
wr = wrcls(*wrargs, **wrkwargs)
self.runwriters.append(wr)

for lstcls, lstargs, lstkwargs in self.listeners:
wr = lstcls(*lstargs, **lstkwargs)
self.runlisteners.append(wr)

# Write down if any writer wants the full csv output
self.writers_csv = any(map(lambda x: x.p.csv, self.runwriters))

Expand Down Expand Up @@ -1293,6 +1302,9 @@ def runstrategies(self, iterstrat, predata=False):
for writer in self.runwriters:
writer.start()

for listener in self.runlisteners:
listener.start(self)

# Prepare timers
self._timers = []
self._timerscheat = []
Expand Down Expand Up @@ -1369,6 +1381,9 @@ def stop_writers(self, runstrats):
writer.writedict(dict(Cerebro=cerebroinfo))
writer.stop()

for listener in self.runlisteners:
listener.stop()

def _brokernotify(self):
'''
Internal method which kicks the broker and delivers any broker
Expand Down Expand Up @@ -1503,6 +1518,13 @@ def _next_writers(self, runstrats):

writer.next()

def _next_listeners(self):
if not self.runlisteners:
return

for listener in self.runlisteners:
listener.next()

def _disable_runonce(self):
'''API for lineiterators to disable runonce (see HeikinAshi)'''
self._dorunonce = False
Expand Down Expand Up @@ -1650,6 +1672,8 @@ def _runnext(self, runstrats):

self._next_writers(runstrats)

self._next_listeners()

# Last notification chance before stopping
self._datanotify()
if self._event_stop: # stop if requested
Expand Down
18 changes: 18 additions & 0 deletions backtrader/listener.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
from __future__ import (absolute_import, division, print_function,
unicode_literals)

import backtrader as bt
from backtrader.utils.py3 import ( with_metaclass)


class ListenerBase(with_metaclass(bt.MetaParams, object)):
def next():
pass

def start(self, cerebro):
pass

def stop(self):
pass

0 comments on commit 794a7ec

Please sign in to comment.