back-trader-python 1.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. back_trader_python-1.4.0.dist-info/METADATA +1491 -0
  2. back_trader_python-1.4.0.dist-info/RECORD +465 -0
  3. back_trader_python-1.4.0.dist-info/WHEEL +5 -0
  4. back_trader_python-1.4.0.dist-info/licenses/LICENSE +674 -0
  5. back_trader_python-1.4.0.dist-info/top_level.txt +1 -0
  6. backtrader/__init__.py +148 -0
  7. backtrader/_cerebro/__init__.py +5 -0
  8. backtrader/_cerebro/channel.py +382 -0
  9. backtrader/_cerebro/execution.py +377 -0
  10. backtrader/_cerebro/lifecycle.py +143 -0
  11. backtrader/_cerebro/notifications.py +150 -0
  12. backtrader/_cerebro/presentation.py +230 -0
  13. backtrader/_cerebro/registry.py +593 -0
  14. backtrader/_cerebro/runnext.py +551 -0
  15. backtrader/_cerebro/runonce.py +142 -0
  16. backtrader/analyzer.py +594 -0
  17. backtrader/analyzers/__init__.py +50 -0
  18. backtrader/analyzers/annualreturn.py +226 -0
  19. backtrader/analyzers/calmar.py +165 -0
  20. backtrader/analyzers/drawdown.py +287 -0
  21. backtrader/analyzers/leverage.py +112 -0
  22. backtrader/analyzers/logreturnsrolling.py +190 -0
  23. backtrader/analyzers/periodstats.py +153 -0
  24. backtrader/analyzers/positions.py +119 -0
  25. backtrader/analyzers/pyfolio.py +470 -0
  26. backtrader/analyzers/returns.py +192 -0
  27. backtrader/analyzers/sharpe.py +307 -0
  28. backtrader/analyzers/sharpe_ratio_stats.py +534 -0
  29. backtrader/analyzers/sqn.py +112 -0
  30. backtrader/analyzers/timereturn.py +192 -0
  31. backtrader/analyzers/total_value.py +75 -0
  32. backtrader/analyzers/tradeanalyzer.py +278 -0
  33. backtrader/analyzers/transactions.py +141 -0
  34. backtrader/analyzers/vwr.py +245 -0
  35. backtrader/bokeh/__init__.py +155 -0
  36. backtrader/bokeh/analyzers/__init__.py +13 -0
  37. backtrader/bokeh/analyzers/plot.py +192 -0
  38. backtrader/bokeh/analyzers/recorder.py +181 -0
  39. backtrader/bokeh/app.py +1094 -0
  40. backtrader/bokeh/live/__init__.py +11 -0
  41. backtrader/bokeh/live/client.py +352 -0
  42. backtrader/bokeh/live/datahandler.py +346 -0
  43. backtrader/bokeh/plot_adapter.py +200 -0
  44. backtrader/bokeh/schemes/__init__.py +14 -0
  45. backtrader/bokeh/schemes/blackly.py +76 -0
  46. backtrader/bokeh/schemes/scheme.py +150 -0
  47. backtrader/bokeh/schemes/tradimo.py +82 -0
  48. backtrader/bokeh/tab.py +125 -0
  49. backtrader/bokeh/tabs/__init__.py +30 -0
  50. backtrader/bokeh/tabs/analyzer.py +120 -0
  51. backtrader/bokeh/tabs/config.py +154 -0
  52. backtrader/bokeh/tabs/live.py +109 -0
  53. backtrader/bokeh/tabs/log.py +185 -0
  54. backtrader/bokeh/tabs/metadata.py +182 -0
  55. backtrader/bokeh/tabs/performance.py +359 -0
  56. backtrader/bokeh/tabs/source.py +70 -0
  57. backtrader/bokeh/utils/__init__.py +8 -0
  58. backtrader/bokeh/utils/helpers.py +167 -0
  59. backtrader/bokeh/webapp.py +164 -0
  60. backtrader/broker.py +478 -0
  61. backtrader/brokers/__init__.py +36 -0
  62. backtrader/brokers/bbroker.py +2576 -0
  63. backtrader/brokers/btapibroker.py +8227 -0
  64. backtrader/brokers/hft/__init__.py +89 -0
  65. backtrader/brokers/hft/binance_bbo.py +625 -0
  66. backtrader/brokers/hft/binance_bbo_compare.py +1398 -0
  67. backtrader/brokers/hft/examples.py +1228 -0
  68. backtrader/brokers/hft/exchange.py +380 -0
  69. backtrader/brokers/hft/latency.py +309 -0
  70. backtrader/brokers/hft/matching_core.py +572 -0
  71. backtrader/brokers/hft/queue.py +238 -0
  72. backtrader/brokers/hft/recorder.py +88 -0
  73. backtrader/brokers/hft/state.py +138 -0
  74. backtrader/brokers/impact_models.py +118 -0
  75. backtrader/brokers/mixbroker.py +895 -0
  76. backtrader/brokers/tickbroker.py +1991 -0
  77. backtrader/btrun/__init__.py +12 -0
  78. backtrader/btrun/btrun.py +1218 -0
  79. backtrader/cerebro.py +828 -0
  80. backtrader/channel.py +682 -0
  81. backtrader/channels/__init__.py +23 -0
  82. backtrader/channels/bridge.py +186 -0
  83. backtrader/channels/funding.py +248 -0
  84. backtrader/channels/live_queue.py +216 -0
  85. backtrader/channels/live_validator.py +294 -0
  86. backtrader/channels/orderbook.py +257 -0
  87. backtrader/channels/tick.py +202 -0
  88. backtrader/comminfo.py +665 -0
  89. backtrader/commissions/__init__.py +106 -0
  90. backtrader/commissions/ctpoption.py +993 -0
  91. backtrader/configs/account_config_example.yaml +8 -0
  92. backtrader/dataseries.py +379 -0
  93. backtrader/errors.py +106 -0
  94. backtrader/events.py +980 -0
  95. backtrader/feed.py +1523 -0
  96. backtrader/feeds/__init__.py +75 -0
  97. backtrader/feeds/barrier.py +2006 -0
  98. backtrader/feeds/blaze.py +118 -0
  99. backtrader/feeds/btapifeed.py +1538 -0
  100. backtrader/feeds/btcsv.py +203 -0
  101. backtrader/feeds/chainer.py +114 -0
  102. backtrader/feeds/cryptohftdata.py +164 -0
  103. backtrader/feeds/csvgeneric.py +1205 -0
  104. backtrader/feeds/ctpcohort.py +1051 -0
  105. backtrader/feeds/influxfeed.py +158 -0
  106. backtrader/feeds/livefeed.py +71 -0
  107. backtrader/feeds/mixed_channel.py +108 -0
  108. backtrader/feeds/mt4csv.py +42 -0
  109. backtrader/feeds/pandafeed.py +381 -0
  110. backtrader/feeds/quandl.py +256 -0
  111. backtrader/feeds/rollover.py +229 -0
  112. backtrader/feeds/sierrachart.py +30 -0
  113. backtrader/feeds/vchart.py +162 -0
  114. backtrader/feeds/vchartcsv.py +84 -0
  115. backtrader/feeds/vchartfile.py +153 -0
  116. backtrader/feeds/yahoo.py +399 -0
  117. backtrader/fillers.py +148 -0
  118. backtrader/filters/__init__.py +34 -0
  119. backtrader/filters/bsplitter.py +127 -0
  120. backtrader/filters/calendardays.py +121 -0
  121. backtrader/filters/datafiller.py +192 -0
  122. backtrader/filters/datafilter.py +74 -0
  123. backtrader/filters/daysteps.py +96 -0
  124. backtrader/filters/heikinashi.py +63 -0
  125. backtrader/filters/renko.py +164 -0
  126. backtrader/filters/session.py +289 -0
  127. backtrader/flt.py +80 -0
  128. backtrader/functions.py +960 -0
  129. backtrader/indicator.py +449 -0
  130. backtrader/indicators/__init__.py +148 -0
  131. backtrader/indicators/accdecoscillator.py +110 -0
  132. backtrader/indicators/aroon.py +300 -0
  133. backtrader/indicators/atr.py +315 -0
  134. backtrader/indicators/awesomeoscillator.py +122 -0
  135. backtrader/indicators/basicops.py +834 -0
  136. backtrader/indicators/bollinger.py +223 -0
  137. backtrader/indicators/cci.py +89 -0
  138. backtrader/indicators/channels_ext.py +83 -0
  139. backtrader/indicators/contrib/__init__.py +228 -0
  140. backtrader/indicators/contrib/absolutely_no_lag_lwma.py +28 -0
  141. backtrader/indicators/contrib/absolutely_no_lag_lwma_color.py +44 -0
  142. backtrader/indicators/contrib/accumulation_distribution_line.py +92 -0
  143. backtrader/indicators/contrib/adx_cross_hull_style_indicator.py +249 -0
  144. backtrader/indicators/contrib/adxdmi.py +34 -0
  145. backtrader/indicators/contrib/ai_acceleration_deceleration_oscillator.py +34 -0
  146. backtrader/indicators/contrib/altr_trend_signal_v22.py +85 -0
  147. backtrader/indicators/contrib/anchored_momentum_line.py +115 -0
  148. backtrader/indicators/contrib/any_range_cld_tail_indicator.py +82 -0
  149. backtrader/indicators/contrib/aroon_horn_sign_indicator.py +96 -0
  150. backtrader/indicators/contrib/aroon_oscillator_sign_alert.py +50 -0
  151. backtrader/indicators/contrib/arrows_curves_indicator.py +112 -0
  152. backtrader/indicators/contrib/as_ctrend_indicator.py +143 -0
  153. backtrader/indicators/contrib/asimmetric_stoch_nr_indicator.py +187 -0
  154. backtrader/indicators/contrib/atr_normalize_histogram.py +118 -0
  155. backtrader/indicators/contrib/average_change_candle.py +165 -0
  156. backtrader/indicators/contrib/bb_squeeze_indicator.py +60 -0
  157. backtrader/indicators/contrib/bezier_st_dev_indicator.py +135 -0
  158. backtrader/indicators/contrib/binary_wave_indicator.py +233 -0
  159. backtrader/indicators/contrib/blau_c_momentum_indicator.py +123 -0
  160. backtrader/indicators/contrib/blau_cmi_indicator.py +141 -0
  161. backtrader/indicators/contrib/blau_csi.py +76 -0
  162. backtrader/indicators/contrib/blau_ergodic.py +53 -0
  163. backtrader/indicators/contrib/blau_t_stoch_i.py +72 -0
  164. backtrader/indicators/contrib/blau_ts_stochastic.py +85 -0
  165. backtrader/indicators/contrib/blau_tvi.py +55 -0
  166. backtrader/indicators/contrib/brain_trend2_indicator.py +128 -0
  167. backtrader/indicators/contrib/brain_trend_signal_proxy.py +47 -0
  168. backtrader/indicators/contrib/brake_parb_indicator.py +85 -0
  169. backtrader/indicators/contrib/breakout_bars_trend_v2.py +121 -0
  170. backtrader/indicators/contrib/bsi_indicator.py +87 -0
  171. backtrader/indicators/contrib/bulls_bears_eyes.py +67 -0
  172. backtrader/indicators/contrib/bulls_power.py +56 -0
  173. backtrader/indicators/contrib/bw_wise_man1_signal.py +102 -0
  174. backtrader/indicators/contrib/bykov_trend_indicator.py +85 -0
  175. backtrader/indicators/contrib/candle_stop_color.py +46 -0
  176. backtrader/indicators/contrib/candles_x_smoothed_indicator.py +69 -0
  177. backtrader/indicators/contrib/candlesticks_bw.py +45 -0
  178. backtrader/indicators/contrib/caudate_x_period_candle_color.py +56 -0
  179. backtrader/indicators/contrib/cci_histogram_indicator.py +53 -0
  180. backtrader/indicators/contrib/cci_woodies_indicator.py +80 -0
  181. backtrader/indicators/contrib/center_of_gravity_candle_indicator.py +83 -0
  182. backtrader/indicators/contrib/center_of_gravity_indicator.py +70 -0
  183. backtrader/indicators/contrib/cg_oscillator.py +40 -0
  184. backtrader/indicators/contrib/close_line_cci.py +38 -0
  185. backtrader/indicators/contrib/close_price_fractals.py +47 -0
  186. backtrader/indicators/contrib/color3rd_gen_xma_indicator.py +122 -0
  187. backtrader/indicators/contrib/color_bb_candles_indicator.py +108 -0
  188. backtrader/indicators/contrib/color_coppock_indicator.py +157 -0
  189. backtrader/indicators/contrib/color_hma.py +71 -0
  190. backtrader/indicators/contrib/color_j_variation_indicator.py +53 -0
  191. backtrader/indicators/contrib/color_metro_de_marker_indicator.py +78 -0
  192. backtrader/indicators/contrib/color_metro_stochastic_indicator.py +93 -0
  193. backtrader/indicators/contrib/color_metro_wpr_indicator.py +85 -0
  194. backtrader/indicators/contrib/color_schaff_de_marker_trend_cycle.py +92 -0
  195. backtrader/indicators/contrib/color_schaff_trend_cycle_indicator.py +203 -0
  196. backtrader/indicators/contrib/color_step_xccx_indicator.py +193 -0
  197. backtrader/indicators/contrib/color_x2_ma.py +49 -0
  198. backtrader/indicators/contrib/color_x_derivative.py +63 -0
  199. backtrader/indicators/contrib/color_zerolag_de_marker.py +84 -0
  200. backtrader/indicators/contrib/corrected_average_indicator.py +127 -0
  201. backtrader/indicators/contrib/darvas_boxes_system.py +73 -0
  202. backtrader/indicators/contrib/dema_range_channel_color.py +42 -0
  203. backtrader/indicators/contrib/derivative_indicator.py +95 -0
  204. backtrader/indicators/contrib/digital_ft01_indicator.py +112 -0
  205. backtrader/indicators/contrib/digital_macd.py +200 -0
  206. backtrader/indicators/contrib/donchian_channels_system.py +45 -0
  207. backtrader/indicators/contrib/dots_indicator.py +93 -0
  208. backtrader/indicators/contrib/ef_distance_indicator.py +82 -0
  209. backtrader/indicators/contrib/ema_rsi_va.py +80 -0
  210. backtrader/indicators/contrib/envelopes_jp_alonso.py +32 -0
  211. backtrader/indicators/contrib/f2a_ao_indicator.py +120 -0
  212. backtrader/indicators/contrib/fatl_filter.py +179 -0
  213. backtrader/indicators/contrib/fibo_candles_indicator.py +78 -0
  214. backtrader/indicators/contrib/fine_tuning_ma.py +100 -0
  215. backtrader/indicators/contrib/fisher_org_v1.py +102 -0
  216. backtrader/indicators/contrib/fisher_org_v1_sign.py +118 -0
  217. backtrader/indicators/contrib/force_index_ema.py +96 -0
  218. backtrader/indicators/contrib/force_index_ema_2.py +27 -0
  219. backtrader/indicators/contrib/forecast_oscilator.py +145 -0
  220. backtrader/indicators/contrib/fractal_amambk.py +81 -0
  221. backtrader/indicators/contrib/frama_series.py +84 -0
  222. backtrader/indicators/contrib/frasm_av2_indicator.py +104 -0
  223. backtrader/indicators/contrib/go_indicator.py +93 -0
  224. backtrader/indicators/contrib/hlr_indicator.py +95 -0
  225. backtrader/indicators/contrib/hma.py +50 -0
  226. backtrader/indicators/contrib/i4_drfv2.py +34 -0
  227. backtrader/indicators/contrib/i4_drfv3.py +38 -0
  228. backtrader/indicators/contrib/i_anch_mom_indicator.py +72 -0
  229. backtrader/indicators/contrib/i_de_marker_sign_indicator.py +64 -0
  230. backtrader/indicators/contrib/i_gap_indicator.py +45 -0
  231. backtrader/indicators/contrib/i_stoch_komposter_indicator.py +77 -0
  232. backtrader/indicators/contrib/i_trend_indicator.py +125 -0
  233. backtrader/indicators/contrib/iamma_indicator.py +39 -0
  234. backtrader/indicators/contrib/indexed_moving_average.py +33 -0
  235. backtrader/indicators/contrib/instantaneous_trend_filter_indicator.py +51 -0
  236. backtrader/indicators/contrib/inverse_reaction_indicator.py +41 -0
  237. backtrader/indicators/contrib/irsi_sign_indicator.py +95 -0
  238. backtrader/indicators/contrib/iwpr_sign_indicator.py +59 -0
  239. backtrader/indicators/contrib/j_brain_trend1_sig_indicator.py +233 -0
  240. backtrader/indicators/contrib/j_tpo_proxy.py +32 -0
  241. backtrader/indicators/contrib/jma_slope_indicator.py +73 -0
  242. backtrader/indicators/contrib/kalman_filter_indicator.py +119 -0
  243. backtrader/indicators/contrib/kalman_filter_line.py +127 -0
  244. backtrader/indicators/contrib/kama_indicator.py +150 -0
  245. backtrader/indicators/contrib/karacatica_indicator.py +99 -0
  246. backtrader/indicators/contrib/kdj_indicator.py +59 -0
  247. backtrader/indicators/contrib/kwan_ccc_indicator.py +195 -0
  248. backtrader/indicators/contrib/kwan_nrp_indicator.py +113 -0
  249. backtrader/indicators/contrib/kwan_rdp_indicator.py +192 -0
  250. backtrader/indicators/contrib/laguerre_adx_indicator.py +85 -0
  251. backtrader/indicators/contrib/laguerre_filter_indicator.py +66 -0
  252. backtrader/indicators/contrib/laguerre_plus_di_proxy.py +57 -0
  253. backtrader/indicators/contrib/laguerre_roc_indicator.py +81 -0
  254. backtrader/indicators/contrib/le_man_signal_indicator.py +63 -0
  255. backtrader/indicators/contrib/linear_reg_slope_v2_indicator.py +136 -0
  256. backtrader/indicators/contrib/loco_indicator.py +88 -0
  257. backtrader/indicators/contrib/lrma_indicator.py +185 -0
  258. backtrader/indicators/contrib/lsma_angle_indicator.py +106 -0
  259. backtrader/indicators/contrib/ma_rounding_channel_indicator.py +149 -0
  260. backtrader/indicators/contrib/macd2_indicator.py +61 -0
  261. backtrader/indicators/contrib/macd_candle_indicator.py +80 -0
  262. backtrader/indicators/contrib/malr_indicator.py +77 -0
  263. backtrader/indicators/contrib/momentum_candle_sign_indicator.py +51 -0
  264. backtrader/indicators/contrib/moving_average_fn_indicator.py +139 -0
  265. backtrader/indicators/contrib/mt5_stochastic_close_close.py +57 -0
  266. backtrader/indicators/contrib/muv_nor_diff_cloud_indicator.py +107 -0
  267. backtrader/indicators/contrib/non_lag_dot_indicator.py +124 -0
  268. backtrader/indicators/contrib/nrtr_extr_indicator.py +95 -0
  269. backtrader/indicators/contrib/nrtr_indicator.py +95 -0
  270. backtrader/indicators/contrib/p_channel_system.py +40 -0
  271. backtrader/indicators/contrib/percent_envelope.py +37 -0
  272. backtrader/indicators/contrib/percentage_crossover_channel.py +47 -0
  273. backtrader/indicators/contrib/pivot_zig_zag_proxy.py +47 -0
  274. backtrader/indicators/contrib/price_channel_stop_indicator.py +104 -0
  275. backtrader/indicators/contrib/price_extreme_channel.py +35 -0
  276. backtrader/indicators/contrib/qqe_cloud_indicator.py +129 -0
  277. backtrader/indicators/contrib/ravi_indicator.py +40 -0
  278. backtrader/indicators/contrib/raw_close_close_stochastic.py +74 -0
  279. backtrader/indicators/contrib/rd_trend_trigger_indicator.py +51 -0
  280. backtrader/indicators/contrib/renko_level.py +85 -0
  281. backtrader/indicators/contrib/renko_line_break.py +91 -0
  282. backtrader/indicators/contrib/rftl_indicator.py +41 -0
  283. backtrader/indicators/contrib/rkd_indicator.py +53 -0
  284. backtrader/indicators/contrib/roc2_vg_indicator.py +68 -0
  285. backtrader/indicators/contrib/rsi_histogram_indicator.py +43 -0
  286. backtrader/indicators/contrib/rsi_slowdown.py +57 -0
  287. backtrader/indicators/contrib/rsioma_v2.py +41 -0
  288. backtrader/indicators/contrib/rvi_histogram_indicator.py +107 -0
  289. backtrader/indicators/contrib/safe_adx.py +89 -0
  290. backtrader/indicators/contrib/shared_strategy_indicators.py +1651 -0
  291. backtrader/indicators/contrib/sidus_indicator.py +105 -0
  292. backtrader/indicators/contrib/silver_trend_indicator.py +79 -0
  293. backtrader/indicators/contrib/sliding_range_color.py +56 -0
  294. backtrader/indicators/contrib/slow_stoch.py +42 -0
  295. backtrader/indicators/contrib/smoothed_adx_indicator.py +86 -0
  296. backtrader/indicators/contrib/smoothed_rsi.py +31 -0
  297. backtrader/indicators/contrib/spearman_rank_correlation_histogram.py +60 -0
  298. backtrader/indicators/contrib/stalin_indicator.py +152 -0
  299. backtrader/indicators/contrib/starter_laguerre_filter.py +62 -0
  300. backtrader/indicators/contrib/step_manrtr_indicator.py +137 -0
  301. backtrader/indicators/contrib/stochastic_histogram_indicator.py +143 -0
  302. backtrader/indicators/contrib/t3_alarm_indicator.py +125 -0
  303. backtrader/indicators/contrib/t3_average.py +76 -0
  304. backtrader/indicators/contrib/t3_indicator.py +40 -0
  305. backtrader/indicators/contrib/the20s_v020_signal.py +93 -0
  306. backtrader/indicators/contrib/three_candles_indicator.py +70 -0
  307. backtrader/indicators/contrib/three_line_break_indicator.py +64 -0
  308. backtrader/indicators/contrib/time_line.py +57 -0
  309. backtrader/indicators/contrib/trading_channel_index_proxy.py +48 -0
  310. backtrader/indicators/contrib/trend_arrows_indicator.py +109 -0
  311. backtrader/indicators/contrib/trend_continuation_indicator.py +127 -0
  312. backtrader/indicators/contrib/trend_intensity_index_proxy.py +51 -0
  313. backtrader/indicators/contrib/trend_manager_indicator.py +39 -0
  314. backtrader/indicators/contrib/tri_x_candle_indicator.py +51 -0
  315. backtrader/indicators/contrib/trigger_line.py +66 -0
  316. backtrader/indicators/contrib/triple_ema_rate.py +34 -0
  317. backtrader/indicators/contrib/trvi_indicator.py +194 -0
  318. backtrader/indicators/contrib/two_pb_ideal_xosma_indicator.py +127 -0
  319. backtrader/indicators/contrib/ultra_absolutely_no_lag_lwma_color.py +92 -0
  320. backtrader/indicators/contrib/ultra_wpr_indicator.py +173 -0
  321. backtrader/indicators/contrib/up_down_candle_strength.py +68 -0
  322. backtrader/indicators/contrib/vinin_i_trend_indicator.py +139 -0
  323. backtrader/indicators/contrib/volume_weighted_ma_indicator.py +78 -0
  324. backtrader/indicators/contrib/volume_weighted_ma_st_dev_indicator.py +111 -0
  325. backtrader/indicators/contrib/vwap_close_indicator.py +65 -0
  326. backtrader/indicators/contrib/vwma_candle.py +57 -0
  327. backtrader/indicators/contrib/vwma_digit_system.py +70 -0
  328. backtrader/indicators/contrib/wami.py +43 -0
  329. backtrader/indicators/contrib/wprsi_signal_indicator.py +105 -0
  330. backtrader/indicators/contrib/x_de_marker_histogram_vol_direct_indicator.py +145 -0
  331. backtrader/indicators/contrib/x_fisher_indicator.py +64 -0
  332. backtrader/indicators/contrib/xcci_histogram_vol_direct_indicator.py +56 -0
  333. backtrader/indicators/contrib/xcci_histogram_vol_indicator.py +85 -0
  334. backtrader/indicators/contrib/xma_ichimoku.py +163 -0
  335. backtrader/indicators/contrib/xma_ishimoku_channel_indicator.py +65 -0
  336. backtrader/indicators/contrib/xma_ishimoku_line.py +68 -0
  337. backtrader/indicators/contrib/xma_range_bands_indicator.py +107 -0
  338. backtrader/indicators/contrib/xmacd_indicator.py +70 -0
  339. backtrader/indicators/contrib/xrsi_de_marker_histogram.py +67 -0
  340. backtrader/indicators/contrib/xrsi_histogram_vol_direct_indicator.py +52 -0
  341. backtrader/indicators/contrib/xrsi_histogram_vol_indicator.py +81 -0
  342. backtrader/indicators/contrib/xrvi_indicator.py +130 -0
  343. backtrader/indicators/contrib/zero_lag_macd.py +36 -0
  344. backtrader/indicators/contrib/zig_zag_recent_pivot_signal.py +90 -0
  345. backtrader/indicators/contrib/zpf_indicator.py +115 -0
  346. backtrader/indicators/crossover.py +337 -0
  347. backtrader/indicators/dema.py +175 -0
  348. backtrader/indicators/demarker.py +270 -0
  349. backtrader/indicators/deviation.py +284 -0
  350. backtrader/indicators/directionalmove.py +1071 -0
  351. backtrader/indicators/dma.py +112 -0
  352. backtrader/indicators/dpo.py +96 -0
  353. backtrader/indicators/dv2.py +56 -0
  354. backtrader/indicators/ema.py +145 -0
  355. backtrader/indicators/envelope.py +475 -0
  356. backtrader/indicators/hadelta.py +198 -0
  357. backtrader/indicators/heikinashi.py +153 -0
  358. backtrader/indicators/hma.py +153 -0
  359. backtrader/indicators/hurst.py +151 -0
  360. backtrader/indicators/ichimoku.py +267 -0
  361. backtrader/indicators/kama.py +181 -0
  362. backtrader/indicators/kst.py +159 -0
  363. backtrader/indicators/lrsi.py +125 -0
  364. backtrader/indicators/mabase.py +147 -0
  365. backtrader/indicators/macd.py +322 -0
  366. backtrader/indicators/momentum.py +267 -0
  367. backtrader/indicators/moneyflow.py +237 -0
  368. backtrader/indicators/mt5atr.py +124 -0
  369. backtrader/indicators/myind.py +179 -0
  370. backtrader/indicators/obv.py +94 -0
  371. backtrader/indicators/ols.py +265 -0
  372. backtrader/indicators/oscillator.py +161 -0
  373. backtrader/indicators/percentchange.py +83 -0
  374. backtrader/indicators/percentrank.py +46 -0
  375. backtrader/indicators/pivotpoint.py +469 -0
  376. backtrader/indicators/prettygoodoscillator.py +113 -0
  377. backtrader/indicators/priceops_ext.py +123 -0
  378. backtrader/indicators/priceoscillator.py +262 -0
  379. backtrader/indicators/psar.py +212 -0
  380. backtrader/indicators/rmi.py +69 -0
  381. backtrader/indicators/rsi.py +440 -0
  382. backtrader/indicators/sma.py +141 -0
  383. backtrader/indicators/smma.py +116 -0
  384. backtrader/indicators/spread.py +54 -0
  385. backtrader/indicators/stochastic.py +263 -0
  386. backtrader/indicators/supertrend.py +436 -0
  387. backtrader/indicators/trend_ext.py +105 -0
  388. backtrader/indicators/trix.py +202 -0
  389. backtrader/indicators/tsi.py +155 -0
  390. backtrader/indicators/ultimateoscillator.py +158 -0
  391. backtrader/indicators/vortex.py +62 -0
  392. backtrader/indicators/williams.py +194 -0
  393. backtrader/indicators/wma.py +103 -0
  394. backtrader/indicators/zlema.py +135 -0
  395. backtrader/indicators/zlind.py +104 -0
  396. backtrader/linebuffer.py +3155 -0
  397. backtrader/lineiterator.py +2911 -0
  398. backtrader/lineroot.py +1106 -0
  399. backtrader/lineseries.py +2559 -0
  400. backtrader/live_trading/__init__.py +31 -0
  401. backtrader/live_trading/interface.py +404 -0
  402. backtrader/mathsupport.py +94 -0
  403. backtrader/metabase.py +1804 -0
  404. backtrader/mixins/__init__.py +21 -0
  405. backtrader/mixins/singleton.py +118 -0
  406. backtrader/observer.py +106 -0
  407. backtrader/observers/__init__.py +45 -0
  408. backtrader/observers/benchmark.py +126 -0
  409. backtrader/observers/broker.py +184 -0
  410. backtrader/observers/buysell.py +144 -0
  411. backtrader/observers/drawdown.py +161 -0
  412. backtrader/observers/logreturns.py +113 -0
  413. backtrader/observers/timereturn.py +86 -0
  414. backtrader/observers/trade_logger.py +2972 -0
  415. backtrader/observers/tradelogger.py +6 -0
  416. backtrader/observers/trades.py +258 -0
  417. backtrader/order.py +1114 -0
  418. backtrader/parameters.py +2345 -0
  419. backtrader/plot/__init__.py +54 -0
  420. backtrader/plot/finance.py +1022 -0
  421. backtrader/plot/formatters.py +200 -0
  422. backtrader/plot/locator.py +353 -0
  423. backtrader/plot/multicursor.py +495 -0
  424. backtrader/plot/plot.py +2500 -0
  425. backtrader/plot/plot_plotly.py +1351 -0
  426. backtrader/plot/scheme.py +253 -0
  427. backtrader/plot/utils.py +104 -0
  428. backtrader/position.py +290 -0
  429. backtrader/position_modes.py +132 -0
  430. backtrader/profiles.py +254 -0
  431. backtrader/reports/__init__.py +39 -0
  432. backtrader/reports/charts.py +371 -0
  433. backtrader/reports/performance.py +620 -0
  434. backtrader/reports/reporter.py +660 -0
  435. backtrader/resamplerfilter.py +1001 -0
  436. backtrader/signal.py +118 -0
  437. backtrader/signals/__init__.py +17 -0
  438. backtrader/sizer.py +114 -0
  439. backtrader/sizers/__init__.py +26 -0
  440. backtrader/sizers/fixedsize.py +161 -0
  441. backtrader/sizers/percents_sizer.py +119 -0
  442. backtrader/store.py +221 -0
  443. backtrader/stores/__init__.py +33 -0
  444. backtrader/stores/btapistore.py +15506 -0
  445. backtrader/stores/livestore.py +137 -0
  446. backtrader/stores/vchartfile.py +96 -0
  447. backtrader/strategy.py +3655 -0
  448. backtrader/talib.py +280 -0
  449. backtrader/test_helpers.py +96 -0
  450. backtrader/timer.py +358 -0
  451. backtrader/trade.py +442 -0
  452. backtrader/tradingcal.py +361 -0
  453. backtrader/utils/__init__.py +68 -0
  454. backtrader/utils/autodict.py +251 -0
  455. backtrader/utils/date.py +71 -0
  456. backtrader/utils/dateintern.py +509 -0
  457. backtrader/utils/flushfile.py +94 -0
  458. backtrader/utils/fractal.py +101 -0
  459. backtrader/utils/get_metrics.py +101 -0
  460. backtrader/utils/load_data.py +209 -0
  461. backtrader/utils/log_message.py +998 -0
  462. backtrader/utils/ordereddefaultdict.py +75 -0
  463. backtrader/utils/py3.py +296 -0
  464. backtrader/version.py +21 -0
  465. backtrader/writer.py +372 -0
@@ -0,0 +1,245 @@
1
+ #!/usr/bin/env python
2
+ """VWR Analyzer Module - Variability-Weighted Return calculation.
3
+
4
+ This module provides the VWR (Variability-Weighted Return) analyzer,
5
+ an alternative to the Sharpe ratio using log returns.
6
+
7
+ Classes:
8
+ VWR: Analyzer that calculates VWR metric.
9
+
10
+ Example:
11
+ >>> cerebro = bt.Cerebro()
12
+ >>> cerebro.addanalyzer(bt.analyzers.VWR, _name='vwr')
13
+ >>> results = cerebro.run()
14
+ >>> print(results[0].analyzers.vwr.get_analysis())
15
+ """
16
+
17
+ import math
18
+
19
+ from ..analyzer import TimeFrameAnalyzerBase
20
+ from ..dataseries import TimeFrame
21
+ from ..mathsupport import standarddev
22
+ from ..metabase import OwnerContext
23
+ from .returns import Returns
24
+
25
+
26
+ # Get VWR indicator
27
+ class VWR(TimeFrameAnalyzerBase):
28
+ """Variability-Weighted Return: Better SharpeRatio with Log Returns
29
+
30
+ Alias:
31
+
32
+ - VariabilityWeightedReturn
33
+
34
+ See:
35
+
36
+ - https://www.crystalbull.com/sharpe-ratio-better-with-log-returns/
37
+
38
+ Params:
39
+
40
+ - ``timeframe`` (default: ``None``)
41
+ If ``None`` then the complete return over the entire backtested period
42
+ will be reported
43
+
44
+ Pass ``TimeFrame.NoTimeFrame`` to consider the entire dataset with no
45
+ time constraints
46
+
47
+ - ``compression`` (default: ``None``)
48
+
49
+ Only used for sub-day timeframes to, for example, work on an hourly
50
+ timeframe by specifying "TimeFrame.Minutes" and 60 as compression
51
+
52
+ If `None`, then the compression of the first data in the system will be
53
+ used
54
+
55
+ - ``tann`` (default: ``None``)
56
+
57
+ Number of periods to use for the annualization (normalization) of the
58
+ average returns. If ``None``, then standard ``t`` values will be used,
59
+ namely:
60
+
61
+ - ``days: 252``
62
+ - ``weeks: 52``
63
+ - ``months: 12``
64
+ - ``years: 1``
65
+
66
+ - ``tau`` (default: ``2.0``)
67
+
68
+ Factor for the calculation (see the literature)
69
+
70
+ - ``sdev_max`` (default: ``0.20``)
71
+
72
+ Max standard deviation (see the literature)
73
+
74
+ - ``fund`` (default: ``None``)
75
+
76
+ If `None`, the actual mode of the broker (fundmode - True/False) will
77
+ be autodetected to decide if the returns are based on the total net
78
+ asset value or on the fund value. See ``set_fundmode`` in the broker
79
+ documentation
80
+
81
+ Set it to ``True`` or ``False`` for a specific behavior
82
+
83
+ Methods:
84
+
85
+ - Get_analysis
86
+
87
+ Returns a dictionary with returns as values and the datetime points for
88
+ each return as keys
89
+
90
+ The returned dict contains the following keys:
91
+
92
+ - ``vwr``: Variability-Weighted Return
93
+ """
94
+
95
+ # Parameters
96
+ params = (
97
+ ("tann", None),
98
+ ("tau", 0.20),
99
+ ("sdev_max", 2.0),
100
+ ("fund", None),
101
+ )
102
+
103
+ # Trading periods per year
104
+ _TANN = {
105
+ TimeFrame.Days: 252.0,
106
+ TimeFrame.Weeks: 52.0,
107
+ TimeFrame.Months: 12.0,
108
+ TimeFrame.Years: 1.0,
109
+ }
110
+
111
+ # Initialize, get returns
112
+ def __init__(self, *args, **kwargs):
113
+ """Initialize the VWR analyzer.
114
+
115
+ Args:
116
+ *args: Positional arguments.
117
+ **kwargs: Keyword arguments for analyzer parameters.
118
+ """
119
+ # Call parent class __init__ method to support timeframe and compression parameters
120
+ super().__init__(*args, **kwargs)
121
+
122
+ # Children log return analyzer
123
+ self._pns = None
124
+ self._pis = None
125
+ self._fundmode = None
126
+ # Use OwnerContext so child analyzer can find this as its parent
127
+ with OwnerContext.set_owner(self):
128
+ self._returns = Returns(
129
+ timeframe=self.p.timeframe, compression=self.p.compression, tann=self.p.tann
130
+ )
131
+
132
+ # Start
133
+ def start(self):
134
+ """Initialize the analyzer at the start of the backtest.
135
+
136
+ Sets the fund mode and initializes lists to track period
137
+ start and end values.
138
+ """
139
+ super().start()
140
+ # Add an initial placeholder for [-1] operation
141
+ # Get fundmode
142
+ if self.p.fund is None:
143
+ self._fundmode = self.strategy.broker.fundmode
144
+ else:
145
+ self._fundmode = self.p.fund
146
+ # Get initial value based on fundmode
147
+ if not self._fundmode:
148
+ self._pis = [self.strategy.broker.getvalue()] # keep initial value
149
+ else:
150
+ self._pis = [self.strategy.broker.fundvalue] # keep initial value
151
+ # Initialize final value to None
152
+ self._pns = [None] # keep final prices (value)
153
+
154
+ # Stop
155
+ def stop(self):
156
+ """Calculate the VWR metric when backtest ends.
157
+
158
+ VWR = rnorm100 * (1 - (sdev_p / sdev_max)^tau)
159
+ where sdev_p is the standard deviation of period returns.
160
+ """
161
+ super().stop()
162
+ # Check if no value has been seen after the last 'dt_over'
163
+ # If so, there is one 'pi' out of place and a None 'pn'. Purge
164
+ # If the last value is None, remove the last element
165
+ if self._pns[-1] is None:
166
+ self._pis.pop()
167
+ self._pns.pop()
168
+
169
+ # Get results from children
170
+ # Get returns
171
+ rs = self._returns.get_analysis()
172
+ ravg = rs["ravg"]
173
+ rnorm100 = rs["rnorm100"]
174
+
175
+ # make n 1 based in enumerate (number of periods and not index)
176
+ # skip initial placeholders for synchronization
177
+ # Calculate return for each period (usually yearly, then save to dts)
178
+ dts = []
179
+ invalid_input = False
180
+ for n, pipn in enumerate(zip(self._pis, self._pns), 1):
181
+ pi, pn = pipn
182
+ try:
183
+ dt = pn / (pi * math.exp(ravg * n)) - 1.0
184
+ if isinstance(dt, complex) or not math.isfinite(dt):
185
+ invalid_input = True
186
+ dt = 0.0
187
+ except (ZeroDivisionError, TypeError, ValueError, OverflowError):
188
+ invalid_input = True
189
+ dt = 0.0
190
+ if not math.isfinite(dt):
191
+ invalid_input = True
192
+ dt = 0.0
193
+ dts.append(dt)
194
+ # Calculate standard deviation of annual returns
195
+ sdev_p = standarddev(dts, bessel=True)
196
+ # Calculate VWR value
197
+ try:
198
+ invalid_output = (
199
+ invalid_input
200
+ or isinstance(sdev_p, complex)
201
+ or not math.isfinite(sdev_p)
202
+ or isinstance(rnorm100, complex)
203
+ or not math.isfinite(rnorm100)
204
+ )
205
+ except TypeError:
206
+ invalid_output = True
207
+ if invalid_output:
208
+ vwr = 0.0
209
+ elif self.p.sdev_max:
210
+ try:
211
+ vwr = rnorm100 * (1.0 - pow(sdev_p / self.p.sdev_max, self.p.tau))
212
+ if isinstance(vwr, complex) or not math.isfinite(vwr):
213
+ vwr = 0.0
214
+ except (ZeroDivisionError, TypeError, ValueError, OverflowError):
215
+ vwr = 0.0
216
+ else:
217
+ vwr = 0.0
218
+ self.rets["vwr"] = vwr
219
+
220
+ # Fund notification
221
+ def notify_fund(self, cash, value, fundvalue, shares):
222
+ """Update the current period end value from fund notification.
223
+
224
+ Args:
225
+ cash: Current cash amount.
226
+ value: Current portfolio value.
227
+ fundvalue: Current fund value.
228
+ shares: Number of fund shares.
229
+ """
230
+ if not self._fundmode:
231
+ self._pns[-1] = value # annotate last seen pn for the current period
232
+ else:
233
+ self._pns[-1] = fundvalue # annotate last pn for current period
234
+
235
+ def on_dt_over(self):
236
+ """Handle timeframe boundary crossing.
237
+
238
+ Moves the current period end value to be the next period's
239
+ start value and creates a new placeholder.
240
+ """
241
+ self._pis.append(self._pns[-1]) # the last pn is pi in the next period
242
+ self._pns.append(None) # placeholder for [-1] operation
243
+
244
+
245
+ VariabilityWeightedReturn = VWR
@@ -0,0 +1,155 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ Backtrader Bokeh Module
4
+
5
+ Provides Bokeh-based live plotting functionality, including:
6
+ - Real-time data push and chart updates
7
+ - Extensible tab system
8
+ - Navigation controls (pause/play/forward/backward)
9
+ - Theme system (black/white themes)
10
+ - Memory optimization (lookback control)
11
+
12
+ Example:
13
+ import backtrader as bt
14
+ from backtrader.bokeh import LivePlotAnalyzer, Blackly
15
+
16
+ cerebro = bt.Cerebro()
17
+ cerebro.adddata(data)
18
+ cerebro.addstrategy(MyStrategy)
19
+
20
+ # Add live plot analyzer
21
+ cerebro.addanalyzer(LivePlotAnalyzer,
22
+ scheme=Blackly(),
23
+ lookback=100)
24
+
25
+ cerebro.run()
26
+ """
27
+
28
+ import importlib
29
+ import os
30
+ import sys
31
+
32
+ _BOKEH_PACKAGE_ROOT = os.path.realpath(os.path.dirname(__file__))
33
+ _BOKEH_PACKAGE_PARENT = os.path.dirname(_BOKEH_PACKAGE_ROOT)
34
+
35
+
36
+ def _is_local_bokeh_module(module):
37
+ """Return whether a top-level ``bokeh`` module resolves to this package."""
38
+ module_file = getattr(module, "__file__", None)
39
+ if module_file and os.path.realpath(module_file).startswith(_BOKEH_PACKAGE_ROOT + os.sep):
40
+ return True
41
+
42
+ return any(
43
+ os.path.realpath(module_path) == _BOKEH_PACKAGE_ROOT
44
+ for module_path in getattr(module, "__path__", ())
45
+ )
46
+
47
+
48
+ def _ensure_external_bokeh():
49
+ """Load the third-party Bokeh package when this package directory shadows it.
50
+
51
+ Some test and embedded environments add ``backtrader/`` directly to
52
+ ``sys.path``. In that layout, a bare ``import bokeh`` resolves to this
53
+ package rather than the third-party dependency. Resolve the optional
54
+ dependency while temporarily excluding that shadowing path.
55
+ """
56
+ loaded = sys.modules.get("bokeh")
57
+ if loaded is not None and not _is_local_bokeh_module(loaded):
58
+ return loaded
59
+
60
+ original_path = sys.path[:]
61
+ try:
62
+ sys.path[:] = [
63
+ entry
64
+ for entry in sys.path
65
+ if os.path.realpath(entry or os.getcwd()) != _BOKEH_PACKAGE_PARENT
66
+ ]
67
+ for name in list(sys.modules):
68
+ module = sys.modules.get(name)
69
+ if name == "bokeh" or name.startswith("bokeh."):
70
+ if module is not None and _is_local_bokeh_module(module):
71
+ sys.modules.pop(name, None)
72
+ return importlib.import_module("bokeh")
73
+ except ImportError:
74
+ return None
75
+ finally:
76
+ sys.path[:] = original_path
77
+
78
+
79
+ _ensure_external_bokeh()
80
+
81
+ if __name__ != "bokeh":
82
+ from . import tabs
83
+ from .schemes import Blackly, Scheme, Tradimo
84
+ from .tab import BokehTab
85
+ from .utils import get_datanames, get_strategy_label, sanitize_source_name
86
+
87
+ # Custom tab registry
88
+ _custom_tabs = []
89
+
90
+
91
+ def register_tab(tab_class):
92
+ """Register a custom tab.
93
+
94
+ Args:
95
+ tab_class: Tab class that inherits from BokehTab
96
+ """
97
+ if not issubclass(tab_class, BokehTab):
98
+ raise ValueError("tab_class must be a subclass of BokehTab")
99
+ _custom_tabs.append(tab_class)
100
+
101
+
102
+ def get_registered_tabs():
103
+ """Get all registered custom tabs."""
104
+ return _custom_tabs.copy()
105
+
106
+
107
+ # Lazy import to avoid circular dependencies
108
+ def __getattr__(name):
109
+ """Lazy load module attributes."""
110
+ if name == "BacktraderBokeh":
111
+ from .app import BacktraderBokeh
112
+
113
+ return BacktraderBokeh
114
+ if name == "LivePlotAnalyzer":
115
+ from .analyzers import LivePlotAnalyzer
116
+
117
+ return LivePlotAnalyzer
118
+ if name == "RecorderAnalyzer":
119
+ from .analyzers import RecorderAnalyzer
120
+
121
+ return RecorderAnalyzer
122
+ if name == "LiveClient":
123
+ from .live import LiveClient
124
+
125
+ return LiveClient
126
+ if name == "LiveDataHandler":
127
+ from .live import LiveDataHandler
128
+
129
+ return LiveDataHandler
130
+ if name == "BokehPlot":
131
+ from .plot_adapter import BokehPlot
132
+
133
+ return BokehPlot
134
+
135
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
136
+
137
+
138
+ __all__ = [
139
+ "BacktraderBokeh",
140
+ "Scheme",
141
+ "Blackly",
142
+ "Tradimo",
143
+ "BokehTab",
144
+ "LivePlotAnalyzer",
145
+ "RecorderAnalyzer",
146
+ "LiveClient",
147
+ "LiveDataHandler",
148
+ "BokehPlot",
149
+ "tabs",
150
+ "register_tab",
151
+ "get_registered_tabs",
152
+ "get_datanames",
153
+ "get_strategy_label",
154
+ "sanitize_source_name",
155
+ ]
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ Bokeh analyzers module.
4
+
5
+ Provides the following analyzers:
6
+ - LivePlotAnalyzer: Live plotting analyzer
7
+ - RecorderAnalyzer: Data recording analyzer
8
+ """
9
+
10
+ from .plot import LivePlotAnalyzer
11
+ from .recorder import RecorderAnalyzer
12
+
13
+ __all__ = ["LivePlotAnalyzer", "RecorderAnalyzer"]
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ Live plotting analyzer.
4
+
5
+ Provides real-time plotting functionality based on Bokeh Server.
6
+ """
7
+
8
+ import asyncio
9
+ import threading
10
+ from threading import Lock
11
+
12
+ from backtrader.utils.log_message import get_logger
13
+
14
+ try:
15
+ import tornado.ioloop
16
+
17
+ TORNADO_AVAILABLE = True
18
+ except ImportError:
19
+ TORNADO_AVAILABLE = False
20
+
21
+ import backtrader as bt
22
+
23
+ from ..app import BacktraderBokeh
24
+ from ..live.client import LiveClient
25
+ from ..schemes import Tradimo
26
+ from ..webapp import Webapp
27
+
28
+ _logger = get_logger(__name__)
29
+
30
+
31
+ class LivePlotAnalyzer(bt.Analyzer):
32
+ """Live plotting analyzer.
33
+
34
+ Provides real-time plotting functionality based on Bokeh Server, including:
35
+ - WebSocket real-time data push
36
+ - Pause/resume functionality
37
+ - Forward/backward navigation
38
+ - Data lookback control
39
+
40
+ Args:
41
+ scheme: Theme instance, defaults to Tradimo
42
+ style: Chart style, 'bar' or 'candle'
43
+ lookback: Amount of historical data to retain
44
+ address: Server address
45
+ port: Server port
46
+ title: Title
47
+ autostart: Whether to auto-start the server
48
+
49
+ Example:
50
+ cerebro.addanalyzer(LivePlotAnalyzer,
51
+ scheme=Blackly(),
52
+ lookback=100,
53
+ port=8999)
54
+ """
55
+
56
+ params = (
57
+ ("scheme", None), # Theme
58
+ ("style", "bar"), # Chart style
59
+ ("lookback", 100), # Historical data retention
60
+ ("address", "localhost"), # Server address
61
+ ("port", 8999), # Server port
62
+ ("title", None), # Title
63
+ ("autostart", True), # Auto-start
64
+ )
65
+
66
+ def __init__(self, **kwargs):
67
+ """Initialize live plot analyzer.
68
+
69
+ Args:
70
+ **kwargs: Keyword arguments overriding default parameters:
71
+ - scheme: Theme instance (defaults to Tradimo)
72
+ - style: Chart style ('bar' or 'candle')
73
+ - lookback: Number of bars to retain in display
74
+ - address: Server address (default: 'localhost')
75
+ - port: Server port (default: 8999)
76
+ - title: Chart title (default: 'Live {StrategyName}')
77
+ - autostart: Whether to auto-start server (default: True)
78
+ """
79
+ super().__init__()
80
+
81
+ # Set title
82
+ title = self.p.title
83
+ if title is None:
84
+ title = f"Live {type(self.strategy).__name__}"
85
+
86
+ # Set auto-start
87
+ autostart = kwargs.get("autostart", self.p.autostart)
88
+
89
+ # Get theme
90
+ scheme = self.p.scheme
91
+ if scheme is None:
92
+ scheme = Tradimo()
93
+
94
+ # Create Webapp
95
+ self._webapp = Webapp(
96
+ title=title,
97
+ template="basic.html.j2",
98
+ scheme=scheme,
99
+ on_root_model=self._app_cb_build_root_model,
100
+ on_session_destroyed=self._on_session_destroyed,
101
+ autostart=autostart,
102
+ address=self.p.address,
103
+ port=self.p.port,
104
+ )
105
+
106
+ self._lock = Lock()
107
+ self._clients = {}
108
+ self._app_kwargs = kwargs
109
+
110
+ def _create_app(self):
111
+ """Create BacktraderBokeh application instance.
112
+
113
+ Returns:
114
+ BacktraderBokeh instance
115
+ """
116
+ return BacktraderBokeh(
117
+ style=self.p.style, scheme=self.p.scheme or Tradimo(), **self._app_kwargs
118
+ )
119
+
120
+ def _on_session_destroyed(self, session_context):
121
+ """Session destroyed callback.
122
+
123
+ Args:
124
+ session_context: Bokeh session context
125
+ """
126
+ with self._lock:
127
+ session_id = session_context.id
128
+ if session_id in self._clients:
129
+ self._clients[session_id].stop()
130
+ del self._clients[session_id]
131
+
132
+ def _t_server(self):
133
+ """Server thread method."""
134
+ if not TORNADO_AVAILABLE:
135
+ _logger.error("Tornado is not available. Cannot start Bokeh server.")
136
+ return
137
+
138
+ asyncio.set_event_loop(asyncio.new_event_loop())
139
+ loop = tornado.ioloop.IOLoop.current()
140
+ self._webapp.start(loop)
141
+
142
+ def _app_cb_build_root_model(self, doc):
143
+ """Build root model callback.
144
+
145
+ Args:
146
+ doc: Bokeh document
147
+
148
+ Returns:
149
+ Root model
150
+ """
151
+ client = LiveClient(doc, self._create_app(), self.strategy, self.p.lookback)
152
+
153
+ with self._lock:
154
+ self._clients[doc.session_context.id] = client
155
+
156
+ return client.model
157
+
158
+ def start(self):
159
+ """Start from backtrader.
160
+
161
+ Starts the Bokeh Server.
162
+ """
163
+ _logger.debug("Starting LivePlotAnalyzer...")
164
+
165
+ t = threading.Thread(target=self._t_server)
166
+ t.daemon = True
167
+ t.start()
168
+
169
+ def stop(self):
170
+ """Stop from backtrader."""
171
+ _logger.debug("Stopping LivePlotAnalyzer...")
172
+
173
+ with self._lock:
174
+ for client in self._clients.values():
175
+ client.stop()
176
+
177
+ def next(self):
178
+ """Receive new data from backtrader.
179
+
180
+ Updates all connected clients.
181
+ """
182
+ with self._lock:
183
+ for client in self._clients.values():
184
+ client.next()
185
+
186
+ def get_analysis(self):
187
+ """Return analysis results.
188
+
189
+ Returns:
190
+ dict: Empty dict (this analyzer is for plotting, does not produce analysis data)
191
+ """
192
+ return {}