11#!/usr/bin/env python
2- # -*- coding: utf-8; py-indent-offset:4 -*-
32"""
43Live plotting analyzer.
54
1312
1413try :
1514 import tornado .ioloop
15+
1616 TORNADO_AVAILABLE = True
1717except ImportError :
1818 TORNADO_AVAILABLE = False
1919
2020import backtrader as bt
2121
2222from ..app import BacktraderBokeh
23- from ..webapp import Webapp
24- from ..schemes import Tradimo , Blackly
2523from ..live .client import LiveClient
24+ from ..schemes import Tradimo
25+ from ..webapp import Webapp
2626
2727_logger = logging .getLogger (__name__ )
2828
@@ -51,15 +51,15 @@ class LivePlotAnalyzer(bt.Analyzer):
5151 lookback=100,
5252 port=8999)
5353 """
54-
54+
5555 params = (
56- (' scheme' , None ), # Theme
57- (' style' , ' bar' ), # Chart style
58- (' lookback' , 100 ), # Historical data retention
59- (' address' , ' localhost' ), # Server address
60- (' port' , 8999 ), # Server port
61- (' title' , None ), # Title
62- (' autostart' , True ), # Auto-start
56+ (" scheme" , None ), # Theme
57+ (" style" , " bar" ), # Chart style
58+ (" lookback" , 100 ), # Historical data retention
59+ (" address" , " localhost" ), # Server address
60+ (" port" , 8999 ), # Server port
61+ (" title" , None ), # Title
62+ (" autostart" , True ), # Auto-start
6363 )
6464
6565 def __init__ (self , ** kwargs ):
@@ -76,48 +76,46 @@ def __init__(self, **kwargs):
7676 - autostart: Whether to auto-start server (default: True)
7777 """
7878 super ().__init__ ()
79-
79+
8080 # Set title
8181 title = self .p .title
8282 if title is None :
83- title = f' Live { type (self .strategy ).__name__ } '
84-
83+ title = f" Live { type (self .strategy ).__name__ } "
84+
8585 # Set auto-start
86- autostart = kwargs .get (' autostart' , self .p .autostart )
87-
86+ autostart = kwargs .get (" autostart" , self .p .autostart )
87+
8888 # Get theme
8989 scheme = self .p .scheme
9090 if scheme is None :
9191 scheme = Tradimo ()
92-
92+
9393 # Create Webapp
9494 self ._webapp = Webapp (
9595 title = title ,
96- template = ' basic.html.j2' ,
96+ template = " basic.html.j2" ,
9797 scheme = scheme ,
9898 on_root_model = self ._app_cb_build_root_model ,
9999 on_session_destroyed = self ._on_session_destroyed ,
100100 autostart = autostart ,
101101 address = self .p .address ,
102- port = self .p .port
102+ port = self .p .port ,
103103 )
104-
104+
105105 self ._lock = Lock ()
106106 self ._clients = {}
107107 self ._app_kwargs = kwargs
108-
108+
109109 def _create_app (self ):
110110 """Create BacktraderBokeh application instance.
111111
112112 Returns:
113113 BacktraderBokeh instance
114114 """
115115 return BacktraderBokeh (
116- style = self .p .style ,
117- scheme = self .p .scheme or Tradimo (),
118- ** self ._app_kwargs
116+ style = self .p .style , scheme = self .p .scheme or Tradimo (), ** self ._app_kwargs
119117 )
120-
118+
121119 def _on_session_destroyed (self , session_context ):
122120 """Session destroyed callback.
123121
@@ -129,17 +127,17 @@ def _on_session_destroyed(self, session_context):
129127 if session_id in self ._clients :
130128 self ._clients [session_id ].stop ()
131129 del self ._clients [session_id ]
132-
130+
133131 def _t_server (self ):
134132 """Server thread method."""
135133 if not TORNADO_AVAILABLE :
136- _logger .error (' Tornado is not available. Cannot start Bokeh server.' )
134+ _logger .error (" Tornado is not available. Cannot start Bokeh server." )
137135 return
138-
136+
139137 asyncio .set_event_loop (asyncio .new_event_loop ())
140138 loop = tornado .ioloop .IOLoop .current ()
141139 self ._webapp .start (loop )
142-
140+
143141 def _app_cb_build_root_model (self , doc ):
144142 """Build root model callback.
145143
@@ -149,37 +147,32 @@ def _app_cb_build_root_model(self, doc):
149147 Returns:
150148 Root model
151149 """
152- client = LiveClient (
153- doc ,
154- self ._create_app (),
155- self .strategy ,
156- self .p .lookback
157- )
158-
150+ client = LiveClient (doc , self ._create_app (), self .strategy , self .p .lookback )
151+
159152 with self ._lock :
160153 self ._clients [doc .session_context .id ] = client
161-
154+
162155 return client .model
163-
156+
164157 def start (self ):
165158 """Start from backtrader.
166159
167160 Starts the Bokeh Server.
168161 """
169- _logger .debug (' Starting LivePlotAnalyzer...' )
170-
162+ _logger .debug (" Starting LivePlotAnalyzer..." )
163+
171164 t = threading .Thread (target = self ._t_server )
172165 t .daemon = True
173166 t .start ()
174-
167+
175168 def stop (self ):
176169 """Stop from backtrader."""
177- _logger .debug (' Stopping LivePlotAnalyzer...' )
178-
170+ _logger .debug (" Stopping LivePlotAnalyzer..." )
171+
179172 with self ._lock :
180173 for client in self ._clients .values ():
181174 client .stop ()
182-
175+
183176 def next (self ):
184177 """Receive new data from backtrader.
185178
@@ -188,7 +181,7 @@ def next(self):
188181 with self ._lock :
189182 for client in self ._clients .values ():
190183 client .next ()
191-
184+
192185 def get_analysis (self ):
193186 """Return analysis results.
194187
0 commit comments