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
backtrader/__init__.py ADDED
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env python
2
+ """Backtrader - Python Trading Framework.
3
+
4
+ A feature-rich Python framework for backtesting and trading with support for
5
+ multiple data feeds, brokers, and analysis tools.
6
+
7
+ This module serves as the main entry point for the backtrader package,
8
+ exposing all public APIs through a unified namespace.
9
+
10
+ Example:
11
+ Basic usage::
12
+
13
+ import backtrader as bt
14
+
15
+ cerebro = bt.Cerebro()
16
+ data = bt.feeds.GenericCSVData(dataname='data.csv')
17
+ cerebro.adddata(data)
18
+ cerebro.addstrategy(MyStrategy)
19
+ results = cerebro.run()
20
+ cerebro.plot()
21
+
22
+ Core Components:
23
+ - **Cerebro**: Main engine that orchestrates backtesting
24
+ - **Strategy**: Base class for trading strategies
25
+ - **Indicator**: Base class for technical indicators
26
+ - **Analyzer**: Base class for performance analyzers
27
+ - **Broker**: Simulated broker for order execution
28
+ - **Feed**: Data feed classes for market data input
29
+
30
+ Subpackages:
31
+ - analyzers: Performance analysis tools (Sharpe, Drawdown, etc.)
32
+ - brokers: Broker implementations (backtesting + unified bt_api_py live broker)
33
+ - feeds: Data feed implementations (CSV, Pandas, Yahoo, bt_api_py live feed)
34
+ - indicators: Technical indicators (SMA, RSI, MACD, etc.)
35
+ - observers: Chart observers for visualization
36
+ - sizers: Position sizing algorithms
37
+ - stores: Data store implementations
38
+ - filters: Data filtering utilities
39
+
40
+ Attributes:
41
+ __version__ (str): Package version string
42
+ __btversion__ (tuple): Package version as tuple
43
+
44
+ See Also:
45
+ - Documentation: https://www.backtrader.com/docu/
46
+ - GitHub: https://github.com/mementum/backtrader
47
+ """
48
+
49
+ import os as _os
50
+
51
+ _LIGHT_IMPORT = _os.environ.get("BACKTRADER_LIGHT_IMPORT", "").strip().lower() in {
52
+ "1",
53
+ "true",
54
+ "yes",
55
+ "on",
56
+ }
57
+
58
+ if _LIGHT_IMPORT:
59
+ from . import broker as broker
60
+ from . import brokers as brokers
61
+ from . import errors as errors
62
+ from . import feeds as feeds
63
+ from . import indicators as ind
64
+ from . import indicators as indicators
65
+ from . import observers as obs
66
+ from . import observers as observers
67
+ from . import stores as stores
68
+ from .broker import *
69
+ from .cerebro import *
70
+ from .comminfo import *
71
+ from .dataseries import *
72
+ from .errors import *
73
+ from .feed import *
74
+ from .functions import *
75
+ from .indicator import *
76
+ from .linebuffer import *
77
+ from .lineiterator import *
78
+ from .lineseries import *
79
+ from .observer import *
80
+ from .order import *
81
+ from .position import *
82
+ from .signal import *
83
+ from .strategy import *
84
+ from .timer import *
85
+ from .trade import *
86
+ from .utils import date2num, num2date, num2dt, num2time, time2num
87
+ from .utils import configure_logging, get_logger, reset_logging, set_level
88
+ from .version import __btversion__, __version__
89
+ else:
90
+ # Load contributed indicators and studies (lazy import to avoid circular dependency)
91
+ # from .indicators import contrib as _indicators_contrib
92
+
93
+ from . import analyzers as analyzers
94
+ from . import broker as broker
95
+ from . import brokers as brokers
96
+ from . import channels as channels
97
+ from . import commissions as commissions
98
+ from . import commissions as comms
99
+ from . import errors as errors
100
+ from . import feeds as feeds
101
+ from . import filters as filters
102
+ from . import indicators as ind
103
+ from . import indicators as indicators
104
+ from . import observers as obs
105
+ from . import observers as observers
106
+ from . import signals as signals
107
+ from . import sizers as sizers
108
+ from . import stores as stores
109
+ from . import talib as talib
110
+ from . import timer as timer
111
+ from . import utils as utils
112
+ from .analyzer import *
113
+ from .broker import *
114
+ from .cerebro import *
115
+ from .comminfo import *
116
+ from .dataseries import *
117
+ from .errors import *
118
+ from .feed import *
119
+ from .flt import *
120
+ from .functions import *
121
+ from .indicator import *
122
+ from .linebuffer import *
123
+ from .lineiterator import *
124
+ from .lineseries import *
125
+ from .observer import *
126
+ from .order import *
127
+ from .position import *
128
+ from .resamplerfilter import *
129
+ from .signal import *
130
+ from .sizer import *
131
+ from .sizers import SizerFix # old sizer for compatibility
132
+ from .store import Store
133
+ from .strategy import *
134
+ from .timer import *
135
+ from .trade import *
136
+ from .utils import date2num, num2date, num2dt, num2time, time2num
137
+ from .utils import configure_logging, get_logger, reset_logging, set_level
138
+ from .version import __btversion__, __version__
139
+ from .writer import *
140
+ from .profiles import LiveProfile, build_cerebro
141
+
142
+ # Iteration 138: Tick-level backtesting and live trading
143
+ from .events import TickEvent, OrderBookSnapshot, FundingEvent, BarEvent
144
+ from .channel import Event, EventPriority, StreamingEventQueue
145
+
146
+ # import backtrader.studies.contrib
147
+
148
+ # from backtrader import vectors
@@ -0,0 +1,5 @@
1
+ """Private Cerebro implementation mixins (iteration 28 split).
2
+
3
+ Not part of the public API. Import order and contents are internal;
4
+ the public class remains ``backtrader.cerebro.Cerebro``.
5
+ """
@@ -0,0 +1,382 @@
1
+ """Cerebro channel event mode mixin (iteration 28 split).
2
+
3
+ Moved verbatim from ``backtrader/cerebro.py``: channel event dispatch,
4
+ channel strategy wiring and the channel run loop.
5
+ """
6
+
7
+ import datetime
8
+ import itertools
9
+ import logging
10
+ from datetime import timezone
11
+ from typing import Dict
12
+
13
+ from .. import errors
14
+ from ..channel import ChannelDataRef
15
+ from ..lineseries import LineSeries
16
+ from ..metabase import OwnerContext
17
+ from ..utils import date2num
18
+ from ..utils.log_message import _is_output_enabled_for, get_logger, throttled_warning
19
+
20
+ UTC = timezone.utc
21
+
22
+ # Keep the historical logger name (D28-04.6): routing/filters must not change.
23
+ logger = get_logger("backtrader.cerebro")
24
+
25
+
26
+ class ChannelMixin:
27
+ """Channel event mode half of Cerebro (see module docstring)."""
28
+
29
+ def dispatch_channel_event(self, event):
30
+ """Dispatch a channel event to all running strategies.
31
+
32
+ Routes tick, orderbook, funding, and bar events from the channel
33
+ system (StreamingEventQueue / LiveEventQueue) to the appropriate
34
+ ``notify_*`` callbacks on each strategy.
35
+
36
+ Args:
37
+ event: Event wrapper with ``.data`` and ``.channel_type`` attrs.
38
+ """
39
+ data = event.data
40
+ channel_type = event.channel_type
41
+ data_ref = getattr(event, "_source_feed", None)
42
+ if data_ref is not None:
43
+ # Feed events use the actual data object for native broker routing.
44
+ # Channel-only events are matched separately by _run_channel().
45
+ processor = getattr(self._broker, "process_" + channel_type, None)
46
+ if processor is not None and channel_type in {"tick", "orderbook"}:
47
+ processor(data, data=data_ref)
48
+ else:
49
+ data_ref = self._get_channel_data_ref(event)
50
+
51
+ for strat in self.runningstrats:
52
+ strat._event_count += 1
53
+ if data_ref is not None and hasattr(strat, "_register_hft_data"):
54
+ strat._register_hft_data(data_ref)
55
+
56
+ if channel_type == "tick":
57
+ strat._tick_count += 1
58
+ strat._last_tick[getattr(data, "symbol", "")] = data
59
+ strat.notify_tick(data)
60
+ strat._notify_tick_to_observers(data)
61
+ elif channel_type == "orderbook":
62
+ strat._last_ob[getattr(data, "symbol", "")] = data
63
+ strat.notify_orderbook(data)
64
+ elif channel_type == "funding":
65
+ strat._last_funding[getattr(data, "symbol", "")] = data
66
+ strat.notify_funding(data)
67
+ elif channel_type == "bar":
68
+ strat.notify_bar(data)
69
+ strat._notify_bar_to_observers(data)
70
+
71
+ def _get_channel_data_ref(self, event):
72
+ """Return a stable lightweight data reference for a channel event."""
73
+ event_data = getattr(event, "data", None)
74
+ symbol = getattr(event_data, "symbol", None) or getattr(event, "channel_name", None)
75
+ if symbol is None:
76
+ return None
77
+
78
+ symbol = str(symbol)
79
+ if not hasattr(self, "_channel_data_refs"):
80
+ # Same shape as Cerebro.__init__'s typed mapping (iteration 28
81
+ # note: minimal annotation so the mixin type-checks standalone).
82
+ self._channel_data_refs: Dict[str, ChannelDataRef] = {}
83
+
84
+ data_ref = self._channel_data_refs.get(symbol)
85
+ if data_ref is None:
86
+ data_ref = ChannelDataRef(
87
+ symbol=symbol, channel_name=getattr(event, "channel_name", None)
88
+ )
89
+ self._channel_data_refs[symbol] = data_ref
90
+ return data_ref
91
+
92
+ def _start_channel_strategy(self, strat):
93
+ """Start a channel-mode strategy without assuming bar datas exist."""
94
+ if getattr(strat, "datas", None):
95
+ strat._start()
96
+ return
97
+
98
+ for analyzer in itertools.chain(strat.analyzers, strat._slave_analyzers):
99
+ analyzer._start()
100
+
101
+ for observer in strat._get_all_observers():
102
+ observer._start()
103
+
104
+ strat.start()
105
+
106
+ def _advance_channel_strategy_clock(self, strat, event):
107
+ """Advance no-data channel strategies so observers can run per event."""
108
+ if getattr(strat, "datas", None):
109
+ return
110
+
111
+ try:
112
+ strat.forward()
113
+ except Exception:
114
+ throttled_warning(
115
+ logger,
116
+ "channel_strategy_forward",
117
+ "Channel strategy forward() failed",
118
+ exc_info=False,
119
+ )
120
+
121
+ timestamp = getattr(event, "timestamp", None)
122
+ if timestamp is None:
123
+ return
124
+
125
+ try:
126
+ event_dt = datetime.datetime.fromtimestamp(float(timestamp), UTC)
127
+ event_num = date2num(event_dt)
128
+ strat.lines.datetime[0] = event_num
129
+ strat._last_valid_datetime = event_num
130
+ # `placeholder_data` is an optional strategy-owned mapping. A
131
+ # normal lookup for the standard Strategy path sends its missing
132
+ # case through LineSeries fallback resolution on every event.
133
+ # Bypass only that known fallback; a custom accessor may provide
134
+ # the mapping dynamically and must retain normal getattr() rules.
135
+ strategy_type = type(strat)
136
+ strategy_getattribute = getattr(strategy_type, "__getattribute__", None)
137
+ if (
138
+ strategy_getattribute is object.__getattribute__
139
+ and getattr(strategy_type, "__getattr__", None) is LineSeries.__getattr__
140
+ ):
141
+ try:
142
+ placeholder_map = object.__getattribute__(strat, "placeholder_data")
143
+ except AttributeError:
144
+ placeholder_map = None
145
+ else:
146
+ placeholder_map = getattr(strat, "placeholder_data", None)
147
+ if isinstance(placeholder_map, dict):
148
+ symbol = getattr(getattr(event, "data", None), "symbol", None)
149
+ placeholder = placeholder_map.get(str(symbol)) if symbol is not None else None
150
+ if placeholder is not None:
151
+ try:
152
+ placeholder._len = max(int(getattr(placeholder, "_len", 0)), len(strat))
153
+ except Exception:
154
+ throttled_warning(
155
+ logger,
156
+ "channel_placeholder_length",
157
+ "Channel placeholder length update failed",
158
+ exc_info=False,
159
+ )
160
+
161
+ try:
162
+ placeholder.datetime[0] = event_num
163
+ except Exception:
164
+ throttled_warning(
165
+ logger,
166
+ "channel_placeholder_datetime",
167
+ "Channel placeholder datetime update failed",
168
+ exc_info=False,
169
+ )
170
+
171
+ try:
172
+ last_price = getattr(event.data, "price", None)
173
+ if last_price is None:
174
+ last_price = getattr(event.data, "close", None)
175
+ if last_price is not None:
176
+ placeholder.close[0] = float(last_price)
177
+ except Exception:
178
+ throttled_warning(
179
+ logger,
180
+ "channel_placeholder_price",
181
+ "Channel placeholder price update failed",
182
+ exc_info=False,
183
+ )
184
+ except Exception:
185
+ throttled_warning(
186
+ logger,
187
+ "channel_strategy_datetime",
188
+ "Channel strategy datetime update failed",
189
+ exc_info=False,
190
+ )
191
+
192
+ def _step_channel_strategy(self, strat):
193
+ """Run channel-mode analyzers and observers once per event."""
194
+ if getattr(strat, "datas", None):
195
+ return
196
+
197
+ for analyzer in itertools.chain(strat.analyzers, strat._slave_analyzers):
198
+ analyzer._next()
199
+
200
+ for observer in strat._get_all_observers():
201
+ observer._next()
202
+
203
+ def _stop_channel_strategy(self, strat):
204
+ """Stop a channel-mode strategy without requiring bar datas."""
205
+ if getattr(strat, "datas", None):
206
+ strat._stop()
207
+ return
208
+
209
+ strat.stop()
210
+
211
+ for analyzer in itertools.chain(strat.analyzers, strat._slave_analyzers):
212
+ analyzer._stop()
213
+
214
+ for observer in strat._get_all_observers():
215
+ try:
216
+ if hasattr(observer, "stop"):
217
+ observer.stop()
218
+ except Exception:
219
+ logger.warning(
220
+ "Observer %s.stop() raised an exception",
221
+ type(observer).__name__,
222
+ exc_info=True,
223
+ )
224
+
225
+ # ------------------------------------------------------------------
226
+ # Channel mode implementation (called from run(channel=...))
227
+ # ------------------------------------------------------------------
228
+ def _run_channel(self, channel, **kwargs):
229
+ """Internal: run strategies in channel event mode.
230
+
231
+ ``channel`` may be:
232
+ * An iterable of ``Event`` objects – events are processed in a
233
+ loop, dispatched to broker and strategies.
234
+ * ``True`` – strategies are instantiated and returned immediately
235
+ without entering an event loop (for external async drivers).
236
+ """
237
+ # Override params
238
+ pkeys = self.params._getkeys()
239
+ for key, val in kwargs.items():
240
+ if key in pkeys:
241
+ setattr(self.params, key, val)
242
+
243
+ # Channel-mode brokers emit simulated order notifications; force the
244
+ # quick-notify path so strategy/observer callbacks receive them.
245
+ self.p.quicknotify = True
246
+
247
+ # --- strategy instantiation (simplified, no bar-data required) ---
248
+ self._init_stcount()
249
+ runstrats: list = []
250
+ self.runningstrats = runstrats
251
+ self._channel_data_refs = {}
252
+
253
+ # Start broker
254
+ self._broker.start()
255
+
256
+ # The optional lifecycle summary must only read a broker after it has
257
+ # entered its active state. Do not make a channel run depend on an
258
+ # informational accessor being available.
259
+ if _is_output_enabled_for(logging.INFO):
260
+ try:
261
+ cash = self._broker.getcash()
262
+ except Exception:
263
+ logger.warning("channel broker cash unavailable for lifecycle logging")
264
+ cash = "unavailable"
265
+ logger.info(
266
+ "channel run starting: strategies=%d datas=%d cash=%s",
267
+ len(self.strats),
268
+ len(self.datas),
269
+ cash,
270
+ )
271
+
272
+ self._instantiate_channel_strategies(runstrats)
273
+ self._wire_channel_strategies(runstrats)
274
+
275
+ # If channel is just True, return strategies for external event loops
276
+ if channel is True:
277
+ self.runstrats = [runstrats]
278
+ return runstrats
279
+
280
+ # --- channel event loop ---
281
+ for event in channel:
282
+ if self._event_stop:
283
+ break
284
+
285
+ for strat in runstrats:
286
+ self._advance_channel_strategy_clock(strat, event)
287
+
288
+ # 1. Let the broker process the raw event data
289
+ ch = event.channel_type
290
+ evdata = event.data
291
+ if ch == "tick" and hasattr(self._broker, "process_tick"):
292
+ self._broker.process_tick(evdata)
293
+ elif ch == "orderbook" and hasattr(self._broker, "process_orderbook"):
294
+ self._broker.process_orderbook(evdata)
295
+ elif ch == "bar" and hasattr(self._broker, "process_bar"):
296
+ self._broker.process_bar(evdata)
297
+
298
+ # 2. Deliver broker order-fill notifications to strategies
299
+ while True:
300
+ order = self._broker.get_notification()
301
+ if order is None:
302
+ break
303
+ owner = getattr(order, "owner", None)
304
+ if owner is None:
305
+ owner = getattr(getattr(order, "p", None), "owner", None)
306
+ if owner is None and runstrats:
307
+ owner = runstrats[0]
308
+ if owner is not None:
309
+ owner._addnotification(order, quicknotify=True)
310
+
311
+ # 3. Dispatch channel event to strategies
312
+ self.dispatch_channel_event(event)
313
+
314
+ # 4. Advance analyzers/observers that rely on next()-style hooks
315
+ for strat in runstrats:
316
+ self._step_channel_strategy(strat)
317
+
318
+ # --- teardown ---
319
+ self._teardown_channel(runstrats)
320
+ return runstrats
321
+
322
+ def _teardown_channel(self, runstrats):
323
+ """Stop a channel session after its event loop or owner has finished."""
324
+ for strat in runstrats:
325
+ self._stop_channel_strategy(strat)
326
+
327
+ self._broker.stop()
328
+ self.runstrats = [runstrats]
329
+
330
+ def _instantiate_channel_strategies(self, runstrats):
331
+ """Instantiate strategy classes for channel mode and append to
332
+ ``runstrats``.
333
+
334
+ Extracted from ``_run_channel`` (instantiation phase); behavior
335
+ unchanged. Honors ``StrategySkipError``, ``oldsync``,
336
+ ``tradehistory`` and broker-provided context exactly as before.
337
+ """
338
+ # Instantiate each strategy class added via addstrategy()
339
+ iterstrats = itertools.product(*self.strats)
340
+ for iterstrat in iterstrats:
341
+ for stratcls, sargs, skwargs in iterstrat:
342
+ try:
343
+ with OwnerContext.set_owner(self):
344
+ if hasattr(stratcls, "_create_strategy_safely"):
345
+ strat = stratcls._create_strategy_safely(*sargs, **skwargs)
346
+ else:
347
+ strat = stratcls(*sargs, **skwargs)
348
+ except errors.StrategySkipError:
349
+ logger.warning("channel:297 suppressed bare")
350
+ continue # user requested skip, same as standard run() path
351
+ if self.p.oldsync:
352
+ strat._oldsync = True
353
+ if self.p.tradehistory:
354
+ strat.set_tradehistory()
355
+ runstrats.append(strat)
356
+
357
+ context_getter = getattr(self._broker, "get_context", None)
358
+ if callable(context_getter):
359
+ context = context_getter()
360
+ for strat in runstrats:
361
+ strat.context = context
362
+
363
+ def _wire_channel_strategies(self, runstrats):
364
+ """Attach observers, analyzers and sizers to channel strategies and
365
+ start them.
366
+
367
+ Extracted from ``_run_channel`` (setup phase); behavior unchanged.
368
+ """
369
+ # Channel mode still needs explicit observers/analyzers initialization.
370
+ defaultsizer = self.sizers.get(None, (None, None, None))
371
+ for idx, strat in enumerate(runstrats):
372
+ for multi, obscls, obsargs, obskwargs in self.observers:
373
+ strat._addobserver(multi, obscls, *obsargs, **obskwargs)
374
+
375
+ for ancls, anargs, ankwargs in self.analyzers:
376
+ strat._addanalyzer(ancls, *anargs, **ankwargs)
377
+
378
+ sizer, sargs, skwargs = self.sizers.get(idx, defaultsizer)
379
+ if sizer is not None:
380
+ strat._addsizer(sizer, *sargs, **skwargs)
381
+
382
+ self._start_channel_strategy(strat)