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/cerebro.py ADDED
@@ -0,0 +1,828 @@
1
+ #!/usr/bin/env python
2
+ """Cerebro - The main engine of the Backtrader framework.
3
+
4
+ This module contains the Cerebro class, which is the central orchestrator for
5
+ backtesting and live trading operations. Cerebro manages data feeds, strategies,
6
+ brokers, analyzers, observers, and all other components of the trading system.
7
+
8
+ Key Features:
9
+ - Data feed management and synchronization
10
+ - Strategy instantiation and execution
11
+ - Broker integration for order execution
12
+ - Multi-core optimization support
13
+ - Live trading and backtesting modes
14
+ - Plotting and analysis capabilities
15
+
16
+ Example:
17
+ Basic backtest setup::
18
+
19
+ import backtrader as bt
20
+
21
+ cerebro = bt.Cerebro()
22
+ data = bt.feeds.GenericCSVData(dataname='data.csv')
23
+ cerebro.adddata(data)
24
+ cerebro.addstrategy(MyStrategy)
25
+ cerebro.broker.setcash(100000)
26
+ results = cerebro.run()
27
+ cerebro.plot()
28
+
29
+ Classes:
30
+ OptReturn: Lightweight result object for optimization runs.
31
+ Cerebro: Main backtesting/trading engine.
32
+ """
33
+
34
+ # pylint: disable=unused-import
35
+ # ruff: noqa: F401
36
+ # NOTE (iteration 28): the module-level imports below are intentionally kept
37
+ # even where the facade no longer references every name: ``backtrader.cerebro``
38
+ # defines no ``__all__`` and ``from backtrader.cerebro import *`` has always
39
+ # exported these bindings. Narrowing them would be a breaking change
40
+ # (AC28-03 star-export parity).
41
+
42
+ import collections
43
+ import datetime
44
+ import functools
45
+ import itertools
46
+ import multiprocessing
47
+ import threading
48
+ from datetime import timezone
49
+ from typing import Dict
50
+
51
+ from . import errors, feeds, indicator, linebuffer, observers
52
+
53
+ # Iteration 28: implementation mixins (imported under private aliases so the
54
+ # star-export namespace of ``backtrader.cerebro`` stays unchanged).
55
+ from ._cerebro.channel import ChannelMixin as _ChannelMixin
56
+ from ._cerebro.execution import ExecutionMixin as _ExecutionMixin
57
+ from ._cerebro.lifecycle import RunLifecycleMixin as _RunLifecycleMixin
58
+ from ._cerebro.notifications import NotificationMixin as _NotificationMixin
59
+ from ._cerebro.presentation import PresentationMixin as _PresentationMixin
60
+ from ._cerebro.registry import RegistryMixin as _RegistryMixin
61
+ from ._cerebro.runnext import RunNextMixin as _RunNextMixin
62
+ from ._cerebro.runonce import RunOnceMixin as _RunOnceMixin
63
+ from .brokers import BackBroker
64
+ from .channel import ChannelDataRef
65
+ from .dataseries import TimeFrame
66
+ from .feed import AbstractDataBase
67
+ from .metabase import OwnerContext
68
+ from .parameters import ParameterDescriptor, ParameterizedBase
69
+ from .strategy import SignalStrategy, Strategy
70
+ from .timer import Timer
71
+ from .tradingcal import PandasMarketCalendar, TradingCalendarBase
72
+ from .utils import OrderedDict, date2num, tzparse
73
+ from .utils.dateintern import _num2date_cached
74
+ from .utils.log_message import (
75
+ _get_logging_config_snapshot,
76
+ _restore_logging_config,
77
+ get_logger,
78
+ )
79
+ from .utils.py3 import integer_types, map, range, string_types, zip
80
+ from .writer import WriterFile
81
+
82
+ logger = get_logger(__name__)
83
+
84
+ # Python 3 always provides collections.abc (the only supported baseline).
85
+ collectionsAbc = collections.abc # collections.Iterable -> collections.abc.Iterable
86
+
87
+ # Python 3.11+ has datetime.UTC, earlier versions use timezone.utc
88
+ UTC = timezone.utc
89
+
90
+
91
+ class _RunStopEvent(threading.Event):
92
+ """A thread-safe stop signal that preserves the legacy bool checks."""
93
+
94
+ def __bool__(self):
95
+ return self.is_set()
96
+
97
+
98
+ def _runstop_scoped(run_method):
99
+ """Publish an active run before its body and retire synchronous runs."""
100
+
101
+ @functools.wraps(run_method)
102
+ def _wrapped(self, *args, **kwargs):
103
+ token = self._open_run_scope()
104
+ retain_external_channel_scope = False
105
+ try:
106
+ result = run_method(self, *args, **kwargs)
107
+ if kwargs.get("channel") is True:
108
+ self._retain_external_channel_scope(token, result)
109
+ retain_external_channel_scope = True
110
+ return result
111
+ finally:
112
+ if not retain_external_channel_scope:
113
+ self._end_run(token)
114
+
115
+ return _wrapped
116
+
117
+
118
+ class OptReturn:
119
+ """Lightweight result container for optimization runs.
120
+
121
+ This class is defined at module level to make it picklable for
122
+ multiprocessing. It stores only essential information from strategy
123
+ runs during optimization to reduce memory usage.
124
+
125
+ Attributes:
126
+ p: Alias for params.
127
+ params: Strategy parameters used in this optimization run.
128
+ analyzers: Analyzer results (if returned during optimization).
129
+
130
+ Note:
131
+ Additional attributes may be set dynamically via kwargs.
132
+ """
133
+
134
+ def __init__(self, params, **kwargs):
135
+ """Initialize the OptReturn object.
136
+
137
+ Args:
138
+ params: Strategy parameters used in this optimization run.
139
+ **kwargs: Additional keyword arguments to set as attributes.
140
+ """
141
+ self.p = self.params = params
142
+ for k, v in kwargs.items():
143
+ setattr(self, k, v)
144
+
145
+
146
+ # pylint: disable=too-many-ancestors
147
+ # The eight implementation mixins keep the single public Cerebro class under
148
+ # the 900-line file budget (iteration 28); see backtrader/_cerebro/.
149
+ class Cerebro(
150
+ _RegistryMixin,
151
+ _NotificationMixin,
152
+ _RunLifecycleMixin,
153
+ _ChannelMixin,
154
+ _ExecutionMixin,
155
+ _RunNextMixin,
156
+ _RunOnceMixin,
157
+ _PresentationMixin,
158
+ ParameterizedBase,
159
+ ):
160
+ """Params:
161
+
162
+ - ``preload`` (default: ``True``)
163
+
164
+ Whether to preload the different ``data feeds`` passed to cerebro for
165
+ the Strategies
166
+
167
+ Note: When True (default), data is loaded into memory before backtesting,
168
+ which uses more memory but significantly improves execution speed.
169
+
170
+ - ``runonce`` (default: ``True``)
171
+
172
+ Run `Indicators` in vectorized mode to speed up the entire system.
173
+ Strategies and Observers will always be run on an event-based basis
174
+
175
+ Note: When True, indicators are calculated using vectorized operations
176
+ for better performance. Strategies and observers still run event-by-event.
177
+
178
+ - ``live`` (default: ``False``)
179
+
180
+ If no data has reported itself as *live* (via the data's ``islive``
181
+ method but the end user still wants to run in ``live`` mode, this
182
+ parameter can be set to true
183
+
184
+ This will simultaneously deactivate ``preload`` and ``runonce``. It
185
+ will have no effect on memory saving schemes.
186
+
187
+ Note: Setting to True forces live mode behavior, disabling preload and
188
+ runonce optimizations, which slows down backtesting.
189
+
190
+ - ``maxcpus`` (default: None -> all available cores)
191
+
192
+ How many cores to use simultaneously for optimization
193
+
194
+ Note: Set to number of CPU cores minus 1 to avoid system overload.
195
+ Use None (default) to use all available cores.
196
+
197
+ - ``stdstats`` (default: ``True``)
198
+
199
+ If True, default Observers will be added: Broker (Cash and Value),
200
+ Trades and BuySell
201
+
202
+ Note: These observers are used for plotting. Set to False if not needed.
203
+
204
+ - ``oldbuysell`` (default: ``False``)
205
+
206
+ If ``stdstats`` is ``True`` and observers are getting automatically
207
+ added, this switch controls the main behavior of the ``BuySell``
208
+ observer
209
+
210
+ - ``False``: use the modern behavior in which the buy / sell signals
211
+ are plotted below / above the low / high prices respectively to avoid
212
+ cluttering the plot
213
+
214
+ - ``True``: use the deprecated behavior in which the buy / sell signals
215
+ are plotted where the average price of the order executions for the
216
+ given moment in time is. This will, of course, be on top of an OHLC bar
217
+ or on a Line on Cloe bar, difficult the recognition of the plot.
218
+
219
+ Note: False (modern) plots signals outside the price bars for clarity.
220
+ True (old) plots signals at execution price, overlapping with bars.
221
+
222
+ - ``oldtrades`` (default: ``False``)
223
+
224
+ If ``stdstats`` is ``True`` and observers are getting automatically
225
+ added, this switch controls the main behavior of the ``Trades``
226
+ observer
227
+
228
+ - ``False``: use the modern behavior in which trades for all datas are
229
+ plotted with different markers
230
+
231
+ - ``True``: use the old Trades observer which plots the trades with the
232
+ same markers, differentiating only if they are positive or negative
233
+
234
+ Note: False uses different markers for different trades.
235
+ True uses same markers, only distinguishing positive/negative.
236
+
237
+
238
+ - ``exactbars`` (default: ``False``)
239
+
240
+ With the default value, each and every value stored in a line is kept in
241
+ memory
242
+
243
+ Possible values:
244
+ - ``True`` or ``1``: all "lines" objects reduce memory usage to the
245
+ automatically calculated minimum period.
246
+
247
+ If a Simple Moving Average has a period of 30, the underlying data
248
+ will have always a running buffer of 30 bars to allow the
249
+ calculation of the Simple Moving Average
250
+
251
+ - This setting will deactivate ``preload`` and ``runonce``
252
+ - Using this setting also deactivates **plotting**
253
+
254
+ - ``-1``: datafeeds and indicators/operations at strategy level will
255
+ keep all data in memory.
256
+
257
+ For example: a ``RSI`` internally uses the indicator ``UpDay`` to
258
+ make calculations. This subindicator will not keep all data in
259
+ memory
260
+
261
+ - This allows keeping ``plotting`` and ``preloading`` active.
262
+
263
+ - ``runonce`` will be deactivated
264
+
265
+ - ``-2``: data feeds and indicators kept as attributes of the
266
+ strategy will keep all points in memory.
267
+
268
+ For example: a ``RSI`` internally uses the indicator ``UpDay`` to
269
+ make calculations. This subindicator will not keep all data in
270
+ memory
271
+
272
+ If in the ``__init__`` something like
273
+ ``a = self.data.close - self.data.high`` is defined, then ``a``
274
+ will not keep all data in memory
275
+
276
+ - This allows keeping ``plotting`` and ``preloading`` active.
277
+
278
+ - ``runonce`` will be deactivated
279
+
280
+ Note on exactbars values:
281
+ - True/1: Minimum memory, disables preload/runonce/plotting
282
+ - -1: Keeps data/indicators but not sub-indicator internals, disables runonce
283
+ - -2: Keeps strategy-level data/indicators, sub-indicators not using self are discarded
284
+
285
+ - ``objcache`` (default: ``False``)
286
+
287
+ Experimental option to implement a cache of lines objects and reduce
288
+ the amount of them. Example from UltimateOscillator:
289
+
290
+ bp = self.data.close - TrueLow(self.data)
291
+ tr = TrueRange(self.data) # -> creates another TrueLow(self.data)
292
+
293
+ If this is `True`, the second ``TrueLow(self.data)`` inside ``TrueRange``
294
+ matches the signature of the one in the ``bp`` calculation. It will be
295
+ reused.
296
+
297
+ Corner cases may happen in which this drives a line object off its
298
+ minimum period and breaks things, and it is therefore disabled.
299
+
300
+ Note: When True, identical indicator calculations are cached and reused
301
+ to reduce computation. Disabled by default due to edge cases.
302
+
303
+ - ``writer`` (default: ``False``)
304
+
305
+ If set to ``True`` a default WriterFile will be created which will
306
+ print to stdout. It will be added to the strategy (in addition to any
307
+ other writers added by the user code)
308
+
309
+ Note: Outputs trading information to stdout. Custom logging in strategy
310
+ is usually preferred for more control.
311
+
312
+ - ``tradehistory`` (default: ``False``)
313
+
314
+ If set to ``True``, it will activate update event logging in each trade
315
+ for all strategies. This can also be achieved on a per-strategy
316
+ basis with the strategy method ``set_tradehistory``
317
+
318
+ Note: Enables trade update logging for all strategies. Can also be
319
+ enabled per-strategy using set_tradehistory method.
320
+
321
+ - ``optdatas`` (default: ``True``)
322
+
323
+ If ``True`` and optimizing (and the system can ``preload`` and use
324
+ ``runonce``, data preloading will be done only once in the main process
325
+ to save time and resources.
326
+
327
+ The tests show an approximate ``20%`` speed-up moving from a sample
328
+ execution in ``83`` seconds to ``66``
329
+
330
+ Note: When True with preload/runonce, data is preloaded once in the
331
+ main process and shared across optimization workers (~20% speedup).
332
+
333
+
334
+ - ``optreturn`` (default: ``True``)
335
+
336
+ If `True`, the optimization results will not be full ``Strategy``
337
+ objects (and all *datas*, *indicators*, *observers* ...) but object
338
+ with the following attributes (same as in ``Strategy``):
339
+
340
+ - ``params`` (or ``p``) the strategy had for the execution
341
+ - ``analyzers`` the strategy has executed
342
+
343
+ On most occasions, only the *analyzers* and with which *params* are
344
+ the things needed to evaluate the performance of a strategy. If
345
+ detailed analysis of the generated values for (for example)
346
+ *indicators* is needed, turn this off
347
+
348
+ The tests show a 13% - 15% improvement in execution time. Combined
349
+ with `optdatas` the total gain increases to a total speed-up of
350
+ `32%` in an optimization run.
351
+
352
+ Note: Returns only params and analyzers during optimization, discarding
353
+ data/indicators/observers for ~15% speedup (32% combined with optdatas).
354
+
355
+ - ``oldsync`` (default: ``False``)
356
+
357
+ Starting with release 1.9.0.99, the synchronization of multiple datas
358
+ (same or different timeframes) has been changed to allow datas of
359
+ different lengths.
360
+
361
+ If the old behavior with data0 as the master of the system is wished,
362
+ set this parameter to true
363
+
364
+ Note: False allows data feeds of different lengths.
365
+ True uses data0 as master (legacy behavior).
366
+
367
+ - ``tz`` (default: ``None``)
368
+
369
+ Adds a global timezone for strategies. The argument ``tz`` can be
370
+
371
+ - ``None``: in this case the datetime displayed by strategies will be
372
+ in UTC, which has always been the standard behavior
373
+
374
+ - ``pytz`` instance. It will be used as such to convert UTC times to
375
+ the chosen timezone
376
+
377
+ - ``string``. Instantiating a ``pytz`` instance will be attempted.
378
+
379
+ - ``integer``. Use, for the strategy, the same timezone as the
380
+ corresponding ``data`` in the ``self.datas`` iterable (``0`` would
381
+ use the timezone from ``data0``)
382
+
383
+ Note: None=UTC, pytz instance converts from UTC, string creates pytz,
384
+ integer uses timezone from corresponding data feed index.
385
+
386
+ - ``cheat_on_open`` (default: ``False``)
387
+
388
+ The ``next_open`` method of strategies will be called. This happens
389
+ before ``next`` and before the broker has had a chance to evaluate
390
+ orders. The indicators have not yet been recalculated. This allows
391
+ issuing an order which takes into account the indicators of the previous
392
+ day but uses the ``open`` price for stake calculations
393
+
394
+ For cheat_on_open order execution, it is also necessary to make the
395
+ call ``cerebro.broker.set_coo(True)`` or instantiate a broker with
396
+ ``BackBroker(coo=True)`` (where *coo* stands for cheat-on-open) or set
397
+ the ``broker_coo`` parameter to ``True``. Cerebro will do it
398
+ automatically unless disabled below.
399
+
400
+ Note: Enables using next bar's open price for position sizing.
401
+ Useful for precise capital allocation. Requires broker_coo=True.
402
+
403
+ - ``broker_coo`` (default: ``True``)
404
+
405
+ This will automatically invoke the ``set_coo`` method of the broker
406
+ with ``True`` to activate ``cheat_on_open`` execution. Will only do it
407
+ if ``cheat_on_open`` is also ``True``
408
+
409
+ Note: Works together with cheat_on_open parameter.
410
+
411
+ - ``quicknotify`` (default: ``False``)
412
+
413
+ Broker notifications are delivered right before the delivery of the
414
+ *next* prices. For backtesting, this has no implications, but with live
415
+ brokers, a notification can take place long before the bar is
416
+ delivered. When set to ``True`` notifications will be delivered as soon
417
+ as possible (see ``qcheck`` in live feeds)
418
+
419
+ Set to ``False`` for compatibility. May be changed to ``True``
420
+
421
+ Note: False delays notifications until next bar. True sends immediately.
422
+ Mainly relevant for live trading.
423
+
424
+ """
425
+
426
+ # Parameter descriptors using new system
427
+ preload = ParameterDescriptor(
428
+ default=True, type_=bool, doc="Whether to preload the different data feeds"
429
+ )
430
+ runonce = ParameterDescriptor(default=True, type_=bool, doc="Run Indicators in vectorized mode")
431
+ maxcpus = ParameterDescriptor(default=None, doc="How many cores to use for optimization")
432
+ stdstats = ParameterDescriptor(default=True, type_=bool, doc="Add default Observers")
433
+ oldbuysell = ParameterDescriptor(
434
+ default=False, type_=bool, doc="Use old BuySell observer behavior"
435
+ )
436
+ oldtrades = ParameterDescriptor(
437
+ default=False, type_=bool, doc="Use old Trades observer behavior"
438
+ )
439
+ lookahead = ParameterDescriptor(default=0, type_=int, doc="Lookahead parameter")
440
+ exactbars = ParameterDescriptor(default=False, doc="Memory usage control for lines objects")
441
+ optdatas = ParameterDescriptor(
442
+ default=True, type_=bool, doc="Optimize data preloading during optimization"
443
+ )
444
+ optreturn = ParameterDescriptor(
445
+ default=True, type_=bool, doc="Return simplified objects during optimization"
446
+ )
447
+ objcache = ParameterDescriptor(
448
+ default=False, type_=bool, doc="Cache lines objects to reduce memory"
449
+ )
450
+ live = ParameterDescriptor(default=False, type_=bool, doc="Run in live mode")
451
+ writer = ParameterDescriptor(default=False, type_=bool, doc="Add a default WriterFile")
452
+ tradehistory = ParameterDescriptor(
453
+ default=False, type_=bool, doc="Activate trade history logging"
454
+ )
455
+ oldsync = ParameterDescriptor(default=False, type_=bool, doc="Use old synchronization behavior")
456
+ tz = ParameterDescriptor(default=None, doc="Global timezone for strategies")
457
+ cheat_on_open = ParameterDescriptor(
458
+ default=False, type_=bool, doc="Enable cheat-on-open execution"
459
+ )
460
+ broker_coo = ParameterDescriptor(
461
+ default=True, type_=bool, doc="Auto-activate broker cheat-on-open"
462
+ )
463
+ quicknotify = ParameterDescriptor(
464
+ default=False, type_=bool, doc="Deliver broker notifications quickly"
465
+ )
466
+
467
+ def __init__(self, **kwargs):
468
+ """Initialize Cerebro with optional parameter overrides.
469
+
470
+ Args:
471
+ **kwargs: Parameter overrides (preload, runonce, maxcpus, etc.)
472
+ """
473
+ super().__init__(**kwargs)
474
+
475
+ # Internal state flags
476
+ self._timerscheat = None
477
+ self._timers = None
478
+ self.runningstrats: list = []
479
+ self.runstrats = None
480
+ self.writers_csv = None
481
+ self.runwriters = None
482
+ self._dopreload = None
483
+ self._dorunonce = None
484
+ self._exactbars = 0
485
+ # ``runstop`` may be called by a Timer or another thread while the
486
+ # engine is running. The event publishes that request safely; the
487
+ # lock defines the start/end boundary so stop requests made between
488
+ # runs cannot leak into a later run.
489
+ self._event_stop = _RunStopEvent()
490
+ self._runstop_lock = threading.RLock()
491
+ self._run_active = False
492
+ self._run_scope_token = 0
493
+ self._run_scope_owner = None
494
+ self._external_channel_token = None
495
+ self._external_channel_runstrats = None
496
+ self._external_channel_closing = False
497
+ self._dolive = False # Live trading mode flag
498
+ self._doreplay = False # Data replay mode flag
499
+ self._dooptimize = False # Optimization mode flag
500
+
501
+ # Component containers
502
+ self.stores = [] # Data stores
503
+ self.feeds = [] # Data feeds
504
+ self.datas = [] # Data objects
505
+ self.datasbyname = collections.OrderedDict() # Data lookup by name
506
+ self._channel_data_refs: Dict[str, ChannelDataRef] = {}
507
+ self.strats = [] # Strategy classes/instances
508
+ self.optcbs = [] # Optimization callbacks
509
+ self.observers = [] # Observer classes
510
+ self.analyzers = [] # Analyzer classes
511
+ self.indicators = [] # Indicator classes
512
+ self.sizers = {} # Position sizers
513
+ self.writers = [] # Output writers
514
+ self.storecbs = [] # Store callbacks
515
+ self.datacbs = [] # Data callbacks
516
+ self.signals = [] # Signal definitions
517
+
518
+ # Signal strategy configuration
519
+ self._signal_strat = (None, None, None)
520
+ self._signal_concurrent = False # Allow concurrent signals
521
+ self._signal_accumulate = False # Allow accumulating positions
522
+
523
+ # Internal counters and references
524
+ self._dataid = itertools.count(1) # Data ID counter
525
+ self._broker = BackBroker() # Default broker
526
+ self._broker.cerebro = self # Back-reference to cerebro
527
+ self._tradingcal = None # Trading calendar
528
+ self._pretimers = [] # Pre-run timers
529
+ self._ohistory = [] # Order history
530
+ self._fhistory = None # Fund history
531
+
532
+ # Override parameters from kwargs
533
+ pkeys = self.params._getkeys()
534
+ for key, val in kwargs.items():
535
+ if key in pkeys:
536
+ setattr(self.params, key, val)
537
+
538
+ def setbroker(self, broker):
539
+ """
540
+ Sets a specific ``broker`` instance for this strategy, replacing the
541
+ one inherited from cerebro.
542
+ """
543
+ self._broker = broker
544
+ broker.cerebro = self
545
+ self._maybe_add_store(broker)
546
+ return broker
547
+
548
+ def getbroker(self):
549
+ """
550
+ Returns the broker instance.
551
+
552
+ This is also available as a ``property`` by the name ``broker``
553
+ """
554
+ return self._broker
555
+
556
+ # Module passed to cerebro for multiprocessing during optimization
557
+ def __call__(self, iterstrat):
558
+ """
559
+ Used during optimization to pass the cerebro over the multiprocessing
560
+ module without complaints
561
+ """
562
+ token = self._open_run_scope()
563
+ try:
564
+ predata = self.p.optdatas and self._dopreload and self._dorunonce
565
+ return self.runstrategies(iterstrat, predata=predata)
566
+ finally:
567
+ self._end_run(token)
568
+
569
+ # Delete runstrats when pickling
570
+ def __getstate__(self):
571
+ """
572
+ Used during optimization to prevent optimization result `runstrats`
573
+ from being pickled to subprocesses
574
+ """
575
+
576
+ rv = vars(self).copy()
577
+ if "runstrats" in rv:
578
+ del rv["runstrats"]
579
+ # ``threading.Event`` and ``RLock`` are intentionally process-local.
580
+ # Optimization workers create a fresh inactive scope in ``__setstate__``.
581
+ rv.pop("_event_stop", None)
582
+ rv.pop("_runstop_lock", None)
583
+ rv["_run_active"] = False
584
+ rv["_run_scope_owner"] = None
585
+ rv.pop("_external_channel_token", None)
586
+ rv.pop("_external_channel_runstrats", None)
587
+ rv.pop("_external_channel_closing", None)
588
+ # Iteration 29: propagate only opt-in configuration, never handlers.
589
+ logging_config = _get_logging_config_snapshot()
590
+ if logging_config is not None:
591
+ rv["_logging_config"] = logging_config
592
+ else:
593
+ rv.pop("_logging_config", None)
594
+ return rv
595
+
596
+ def __setstate__(self, state):
597
+ """Restore process-local run-stop state after multiprocessing pickle."""
598
+ state = state.copy()
599
+ logging_config = state.pop("_logging_config", None)
600
+ self.__dict__.update(state)
601
+ self._event_stop = _RunStopEvent()
602
+ self._runstop_lock = threading.RLock()
603
+ self._run_active = False
604
+ self._run_scope_token = 0
605
+ self._run_scope_owner = None
606
+ self._external_channel_token = None
607
+ self._external_channel_runstrats = None
608
+ self._external_channel_closing = False
609
+ _restore_logging_config(logging_config)
610
+
611
+ # Core method for backtesting. Any passed kwargs affect cerebro standard parameters.
612
+ # If no data added, will stop immediately. Return value differs based on optimization.
613
+ def _resolve_run_flags(self):
614
+ """Resolve runonce/preload/exactbars/replay/live flags and build writers.
615
+
616
+ Extracted from run() to keep that method readable. Sets the private
617
+ execution-mode flags on self and populates self.runwriters /
618
+ self.writers_csv. No behavior change.
619
+ """
620
+ # Check if _dorunonce, _dopreload, _exactbars
621
+ self._dorunonce = self.p.runonce
622
+ self._dopreload = self.p.preload
623
+ self._exactbars = int(self.p.exactbars)
624
+ # If _exactbars is not 0, _dorunonce must be False; if _dopreload is True and _exactbars < 1, set _dopreload to True
625
+ if self._exactbars:
626
+ self._dorunonce = False # something is saving memory, no runonce
627
+ self._dopreload = self._dopreload and self._exactbars < 1
628
+ # If _doreplay is True or any data has replaying attribute True, set _doreplay to True
629
+ self._doreplay = self._doreplay or any(x.replaying for x in self.datas)
630
+ # If _doreplay, need to set _dopreload to False
631
+ if self._doreplay:
632
+ # preloading is not supported with replay. full timeframe bars
633
+ # are constructed in realtime
634
+ self._dopreload = False
635
+ # If _dolive or live, need to set _dorunonce and _dopreload to False
636
+ if self._dolive or self.p.live:
637
+ # in this case, both preload and runonce must be off
638
+ self._dorunonce = False
639
+ self._dopreload = False
640
+
641
+ # Writer list
642
+ self.runwriters = []
643
+
644
+ # Add the system default writer if requested
645
+ if self.p.writer is True:
646
+ wr = WriterFile()
647
+ self.runwriters.append(wr)
648
+
649
+ # Instantiate any other writers
650
+ for wrcls, wrargs, wrkwargs in self.writers:
651
+ wr = wrcls(*wrargs, **wrkwargs)
652
+ self.runwriters.append(wr)
653
+
654
+ # Write down if any writer wants the full csv output
655
+ self.writers_csv = any(map(lambda x: x.p.csv, self.runwriters))
656
+
657
+ @_runstop_scoped
658
+ def run(self, **kwargs) -> list:
659
+ """The core method to perform backtesting. Any ``kwargs`` passed to it
660
+ will affect the value of the standard parameters ``Cerebro`` was
661
+ instantiated with.
662
+
663
+ If `cerebro` has no data **and** no ``channel`` is given, the method
664
+ will immediately bail out.
665
+
666
+ Extra keyword arguments
667
+ -----------------------
668
+ channel : iterable or True, optional
669
+ When provided the engine runs in **channel mode** instead of the
670
+ traditional bar-based mode.
671
+
672
+ * *iterable* – an ``Event`` stream (``StreamingEventQueue``,
673
+ ``LiveEventQueue``, or any iterable yielding ``Event``
674
+ objects). Events are dispatched to the broker and then to
675
+ every strategy via their ``notify_*`` callbacks.
676
+ * ``True`` – strategies are instantiated and returned
677
+ immediately **without** entering an event loop. This is
678
+ useful when an external async loop drives the data (e.g.
679
+ external market-data watchers calling ``strategy.notify_tick()``
680
+ directly). Call ``cerebro.close_channel()`` from the same
681
+ thread when that external loop is done to tear down brokers and
682
+ strategies.
683
+
684
+ It has different return values:
685
+
686
+ - For No Optimization: a list contanining instances of the Strategy
687
+ classes added with ``addstrategy``
688
+
689
+ - For Optimization: a list of lists which contain instances of the
690
+ Strategy classes added with ``addstrategy``
691
+ """
692
+ # --- channel mode ---------------------------------------------------
693
+ channel = kwargs.pop("channel", None)
694
+ if channel is not None:
695
+ # _run_channel is dynamically typed; run() advertises -> list.
696
+ return self._run_channel(channel, **kwargs)
697
+
698
+ # If no data, return empty list immediately
699
+ if not self.datas:
700
+ return [] # nothing can be run
701
+ # Override standard parameters with passed kwargs
702
+ pkeys = self.params._getkeys()
703
+ for key, val in kwargs.items():
704
+ if key in pkeys:
705
+ setattr(self.params, key, val)
706
+
707
+ # Manage activate/deactivate object cache
708
+ # Manage object cache
709
+ linebuffer.LineActions.cleancache() # clean cache
710
+ indicator.Indicator.cleancache() # clean cache
711
+
712
+ linebuffer.LineActions.usecache(self.p.objcache)
713
+ indicator.Indicator.usecache(self.p.objcache)
714
+
715
+ # Resolve runonce/preload/exactbars/replay/live execution flags + writers
716
+ self._resolve_run_flags()
717
+
718
+ # Running strategy list
719
+ self.runstrats = []
720
+ # If signals is not None, handle signalstrategy related issues
721
+ if self.signals: # allow processing of signals
722
+ signalst, sargs, skwargs = self._signal_strat
723
+ if signalst is None:
724
+ # Try to see if the 1st regular strategy is a signal strategy
725
+ try:
726
+ signalst, sargs, skwargs = self.strats.pop(0)
727
+ except IndexError:
728
+ logger.debug("cerebro:715 ignored IndexError")
729
+ # Nothing there
730
+ else:
731
+ if not isinstance(signalst, SignalStrategy):
732
+ # no signal ... reinsert at the beginning
733
+ self.strats.insert(0, (signalst, sargs, skwargs))
734
+ signalst = None # flag as not present
735
+
736
+ if signalst is None: # recheck
737
+ # Still None, create a default one
738
+ signalst, sargs, skwargs = SignalStrategy, (), {}
739
+
740
+ # sargs/skwargs always come from a (args, kwargs) pair or the
741
+ # tuple()/dict() defaults above; normalize for safe unpacking.
742
+ sargs = sargs or ()
743
+ skwargs = skwargs or {}
744
+
745
+ # Add the signal strategy
746
+ self.addstrategy(
747
+ signalst,
748
+ *sargs,
749
+ _accumulate=self._signal_accumulate,
750
+ _concurrent=self._signal_concurrent,
751
+ signals=self.signals,
752
+ **skwargs,
753
+ )
754
+ # If strategy list is empty, add strategy
755
+ if not self.strats: # Datas are present, add a strategy
756
+ self.addstrategy(Strategy)
757
+ # Iterate strategies
758
+ iterstrats = itertools.product(*self.strats)
759
+ # If not optimization parameters, or using 1 cpu core
760
+ if not self._dooptimize or self.p.maxcpus == 1:
761
+ # If no optimmization is wished ... or 1 core is to be used
762
+ # let's skip process "spawning"
763
+ # Iterate through strategies
764
+ for iterstrat in iterstrats:
765
+ # Run strategy
766
+ runstrat = self.runstrategies(iterstrat)
767
+ # Add running strategy to running strategy list
768
+ self.runstrats.append(runstrat)
769
+ # If optimization parameters
770
+ if self._dooptimize:
771
+ # Iterate all optcbs to return stopped strategy results
772
+ for cb in self.optcbs:
773
+ cb(runstrat) # callback receives finished strategy
774
+ # If optimization parameters
775
+ else:
776
+ # If optdatas is True, and _dopreload, and _dorunonce
777
+ if self.p.optdatas and self._dopreload and self._dorunonce:
778
+ # Iterate each data, reset, if _exactbars < 1, extend data
779
+ # Start data
780
+ # If data _dopreload, call preload on data
781
+ for data in self.datas:
782
+ data.reset()
783
+ if self._exactbars < 1: # datas can be a full length
784
+ data.extend(size=self.params.lookahead)
785
+ data._start()
786
+ data.preload()
787
+ # Start process pool
788
+ pool = multiprocessing.Pool(self.p.maxcpus or None)
789
+ for r in pool.imap(self, iterstrats):
790
+ self.runstrats.append(r)
791
+ for cb in self.optcbs:
792
+ cb(r) # callback receives finished strategy
793
+ # Close process pool
794
+ pool.close()
795
+ # If optdatas is True, and _dopreload, and _dorunonce, iterate data and stop data
796
+ if self.p.optdatas and self._dopreload and self._dorunonce:
797
+ for data in self.datas:
798
+ data.stop()
799
+ # If not optimization parameters
800
+ if not self._dooptimize:
801
+ # avoid a list of list for regular cases
802
+ return self.runstrats[0]
803
+
804
+ return self.runstrats
805
+
806
+ def _build_optreturn_results(self, runstrats):
807
+ """Build OptReturn results for an optimization run.
808
+
809
+ Detaches analyzers from their strategy/data references (so the result
810
+ is lightweight and picklable across process boundaries) and wraps each
811
+ strategy's params + analyzers in an OptReturn.
812
+ """
813
+ results = []
814
+ for strat in runstrats:
815
+ for a in strat.analyzers:
816
+ a.strategy = None
817
+ a._parent = None
818
+ # OPTIMIZED: Use __dict__ instead of dir() for better performance
819
+ for attrname in list(a.__dict__.keys()):
820
+ if attrname.startswith("data"):
821
+ setattr(a, attrname, None)
822
+
823
+ oreturn = OptReturn(strat.params, analyzers=strat.analyzers, strategycls=type(strat))
824
+ results.append(oreturn)
825
+
826
+ return results
827
+
828
+ broker = property(getbroker, setbroker)