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/analyzer.py ADDED
@@ -0,0 +1,594 @@
1
+ #!/usr/bin/env python
2
+ """Analyzer Module - Strategy performance analysis framework.
3
+
4
+ This module provides the base classes for analyzers that calculate and
5
+ report performance metrics for trading strategies. Analyzers can track
6
+ trades, returns, drawdowns, Sharpe ratios, and other statistics.
7
+
8
+ Key Classes:
9
+ Analyzer: Base class for all analyzers.
10
+ TimeFrameAnalyzerBase: Base for time-frame aware analyzers.
11
+
12
+ Analyzers receive notifications from the strategy during backtesting:
13
+ - notify_trade: Called when a trade is completed
14
+ - notify_order: Called when an order status changes
15
+ - notify_cashvalue: Called when cash/value changes
16
+ - notify_fund: Called when fund data changes
17
+
18
+ Example:
19
+ Creating a custom analyzer:
20
+ >>> class MyAnalyzer(Analyzer):
21
+ ... def __init__(self):
22
+ ... super().__init__()
23
+ ... self.trades = 0
24
+ ...
25
+ ... def notify_trade(self, trade):
26
+ ... if trade.isclosed:
27
+ ... self.trades += 1
28
+ ...
29
+ ... def get_analysis(self):
30
+ ... return {'trade_count': self.trades}
31
+ """
32
+
33
+ import calendar
34
+ import datetime
35
+ import pprint as pp
36
+ from collections import OrderedDict
37
+
38
+ from .dataseries import TimeFrame
39
+ from .metabase import findowner
40
+ from .observer import Observer
41
+ from .parameters import ParameterizedBase
42
+ from .strategy import Strategy
43
+ from .utils.py3 import MAXINT
44
+
45
+
46
+ # Analyzer class - refactored to not use metaclass
47
+ class Analyzer(ParameterizedBase):
48
+ """Analyzer base class. All analyzers are subclass of this one
49
+
50
+ An Analyzer instance operates in the frame of a strategy and provides an
51
+ analysis for that strategy.
52
+
53
+ # Analyzer class, all analyzers are base classes of this class. An analyzer operates within the strategy framework and provides analysis of strategy execution
54
+
55
+ Automagically set member attributes:
56
+
57
+ - ``self.strategy`` (giving access to the *strategy* and anything
58
+ accessible from it)
59
+
60
+ # Access to strategy instance
61
+
62
+ - ``self.datas[x]`` giving access to the array of data feeds present in
63
+ the the system, which could also be accessed via the strategy reference
64
+
65
+ - ``self.data``, giving access to ``self.datas[0]``
66
+
67
+ - ``self.dataX`` -> ``self.datas[X]``
68
+
69
+ - ``self.dataX_Y`` -> ``self.datas[X].lines[Y]``
70
+
71
+ - ``self.dataX_name`` -> ``self.datas[X].name``
72
+
73
+ - ``self.data_name`` -> ``self.datas[0].name``
74
+
75
+ - ``self.data_Y`` -> ``self.datas[0].lines[Y]``
76
+
77
+ # Methods to access data
78
+
79
+ This is not a *Lines* object, but the methods and operation follow the same
80
+ design
81
+
82
+ - ``__init__`` during instantiation and initial setup
83
+
84
+ - ``start`` / ``stop`` to signal the begin and end of operations
85
+
86
+ - ``prenext`` / ``nextstart`` / ``next`` family of methods that follow
87
+ the calls made to the same methods in the strategy
88
+
89
+ - ``notify_trade`` / ``notify_order`` / ``notify_cashvalue`` /
90
+ ``notify_fund`` which receive the same notifications as the equivalent
91
+ methods of the strategy
92
+
93
+ The mode of operation is open and no pattern is preferred. As such the
94
+ analysis can be generated with the ``next`` calls, at the end of operations
95
+ during ``stop`` and even with a single method like ``notify_trade``
96
+
97
+ The important thing is to override ``get_analysis`` to return a *dict-like*
98
+ object containing the results of the analysis (the actual format is
99
+ implementation dependent)
100
+
101
+ # Below are not line objects, but methods and operation design are similar to strategy. The most important thing is to override get_analysis,
102
+ # to return a dict-like object to store analysis results
103
+
104
+ """
105
+
106
+ # Save results to csv
107
+ csv = True
108
+
109
+ def __init__(self, *args, **kwargs):
110
+ """
111
+ Initialize Analyzer with basic functionality.
112
+
113
+ Note: __new__ removed - _children initialization moved here.
114
+ """
115
+ # Initialize children list (moved from __new__)
116
+ self._children = []
117
+
118
+ # Initialize parent first
119
+ super().__init__(*args, **kwargs)
120
+
121
+ # findowner is used to find _obj's parent, Strategy instance, returns None if not found
122
+ self.strategy = strategy = findowner(self, Strategy)
123
+ # findowner is used to find _obj's parent, belonging to Analyzer instance, returns None if not found
124
+ self._parent = findowner(self, Analyzer)
125
+ # Register with a master observer if created inside one
126
+ # findowner is used to find _obj's parent, but belonging to Observer instance, returns None if not found
127
+ masterobs = findowner(self, Observer)
128
+ # If there is obs, register analyzer to obs
129
+ if masterobs is not None:
130
+ masterobs._register_analyzer(self)
131
+ # analyzer's data
132
+ self.datas = strategy.datas if strategy is not None else []
133
+
134
+ # For each data add aliases: for first data: data and data0
135
+ # If analyzer's data is not None
136
+ if self.datas:
137
+ # analyzer's data is the first data
138
+ self.data = data = self.datas[0]
139
+ # For each line in data
140
+ for line_index, line in enumerate(data.lines):
141
+ # Get line name
142
+ linealias = data._getlinealias(line_index)
143
+ # If line name is not None, set attribute
144
+ if linealias:
145
+ setattr(self, "data_%s" % linealias, line)
146
+ # Set line name based on index
147
+ setattr(self, "data_%d" % line_index, line)
148
+ # Loop through data, set different names for data, can be accessed via data_d
149
+ for d, data in enumerate(self.datas):
150
+ setattr(self, "data%d" % d, data)
151
+ # Set specific attribute names for different data, can access line via attribute name
152
+ for line_index, line in enumerate(data.lines):
153
+ linealias = data._getlinealias(line_index)
154
+ if linealias:
155
+ setattr(self, "data%d_%s" % (d, linealias), line)
156
+ setattr(self, "data%d_%d" % (d, line_index), line)
157
+
158
+ # Call create_analysis method
159
+ self.create_analysis()
160
+
161
+ # Handle parent registration (previously in dopostinit)
162
+ if self._parent is not None:
163
+ self._parent._register(self)
164
+
165
+ # When getting analyzer's length, actually returns strategy's length
166
+ def __len__(self):
167
+ """Support for invoking ``len`` on analyzers by actually returning the
168
+ current length of the strategy the analyzer operates on"""
169
+ return len(self.strategy)
170
+
171
+ # Add a child to self._children
172
+ def _register(self, child):
173
+ self._children.append(child)
174
+
175
+ # Call _prenext, for each child, call _prenext
176
+ def _prenext(self):
177
+ for child in self._children:
178
+ child._prenext()
179
+ # Call prenext
180
+ self.prenext()
181
+
182
+ # Notify cash and value
183
+ # PERFORMANCE OPTIMIZATION: Cache children check, called 3.1M+ times
184
+ def _notify_cashvalue(self, cash, value):
185
+ children = self._children
186
+ if children:
187
+ for child in children:
188
+ child._notify_cashvalue(cash, value)
189
+ self.notify_cashvalue(cash, value)
190
+
191
+ # Notify cash, value, fundvalue, shares
192
+ # PERFORMANCE OPTIMIZATION: Cache children check, called 3.1M+ times
193
+ def _notify_fund(self, cash, value, fundvalue, shares):
194
+ children = self._children
195
+ if children:
196
+ for child in children:
197
+ child._notify_fund(cash, value, fundvalue, shares)
198
+ self.notify_fund(cash, value, fundvalue, shares)
199
+
200
+ # Notify trade
201
+ def _notify_trade(self, trade):
202
+ for child in self._children:
203
+ child._notify_trade(trade)
204
+
205
+ self.notify_trade(trade)
206
+
207
+ # Notify order
208
+ def _notify_order(self, order):
209
+ for child in self._children:
210
+ child._notify_order(order)
211
+
212
+ self.notify_order(order)
213
+
214
+ # Call _nextstart
215
+ def _nextstart(self):
216
+ for child in self._children:
217
+ child._nextstart()
218
+
219
+ self.nextstart()
220
+
221
+ # Call _next
222
+ def _next(self):
223
+ for child in self._children:
224
+ child._next()
225
+
226
+ self.next()
227
+
228
+ # _start, call _start for all children
229
+ def _start(self):
230
+ for child in self._children:
231
+ child._start()
232
+
233
+ self.start()
234
+
235
+ # _stop, call _stop for all children
236
+ def _stop(self):
237
+ for child in self._children:
238
+ child._stop()
239
+
240
+ self.stop()
241
+
242
+ # Notify cash, value
243
+ def notify_cashvalue(self, cash, value):
244
+ """Notify the analyzer of cash and value changes.
245
+
246
+ Args:
247
+ cash: Current available cash.
248
+ value: Current portfolio value.
249
+
250
+ Note:
251
+ Override this method to react to cash/value changes.
252
+ """
253
+
254
+ # Notify fund
255
+ def notify_fund(self, cash, value, fundvalue, shares):
256
+ """Notify the analyzer of fund-related changes.
257
+
258
+ Args:
259
+ cash: Current available cash.
260
+ value: Current portfolio value.
261
+ fundvalue: Current fund value.
262
+ shares: Number of fund shares.
263
+
264
+ Note:
265
+ Override this method to react to fund changes.
266
+ """
267
+
268
+ # Notify order, can be overridden in subclasses
269
+ def notify_order(self, order):
270
+ """Notify the analyzer of an order status change.
271
+
272
+ Args:
273
+ order: The order that was updated.
274
+
275
+ Note:
276
+ Override this method to track order status.
277
+ """
278
+
279
+ # Notify trade, can be overridden in subclasses
280
+ def notify_trade(self, trade):
281
+ """Notify the analyzer of a trade status change.
282
+
283
+ Args:
284
+ trade: The trade that was updated.
285
+
286
+ Note:
287
+ Override this method to track trade status.
288
+ """
289
+
290
+ # next, can be overridden in subclasses
291
+ def next(self):
292
+ """Called on each bar after minimum period is reached.
293
+
294
+ Note:
295
+ Override this method to implement per-bar analysis logic.
296
+ """
297
+
298
+ # prenext, if equal to next, override prenext in subclasses,
299
+ # generally, prenext needs to do the same calculation as next or pass
300
+ def prenext(self):
301
+ """Called on each bar before minimum period is reached.
302
+
303
+ By default calls next(). Override if different behavior is needed.
304
+ """
305
+ # prenext and next until a minimum period of total_lines has been
306
+ # reached
307
+ # By default call next, unless prenext is specially overridden in subclass, otherwise prenext calls next
308
+ self.next()
309
+
310
+ # nextstart, generally overridden by subclasses, or call next
311
+ def nextstart(self):
312
+ """Called once when minimum period is first reached.
313
+
314
+ By default calls next(). Override if different behavior is needed.
315
+ """
316
+ # Called once when the minimum period for all lines has been meet
317
+ # It's default behavior is to call next
318
+ # By default call next
319
+ self.next()
320
+
321
+ # start, can be overridden in subclasses
322
+ def start(self):
323
+ """Called at the start of the backtest.
324
+
325
+ Note:
326
+ Override this method to initialize analyzer state.
327
+ """
328
+
329
+ # stop, can be overridden in subclasses
330
+ def stop(self):
331
+ """Called at the end of the backtest.
332
+
333
+ Note:
334
+ Override this method to perform final calculations.
335
+ """
336
+
337
+ # Create analysis, override in subclasses
338
+ def create_analysis(self):
339
+ """Create the analysis results container.
340
+
341
+ Creates the rets OrderedDict that will hold analysis results.
342
+ Override this method to customize the results structure.
343
+ """
344
+ # create a dict placeholder for the analysis
345
+ # Create a dict placeholder for analysis results
346
+ # self.rets can be accessed via get_analysis
347
+ self.rets = OrderedDict()
348
+
349
+ # Get analysis
350
+ def get_analysis(self):
351
+ """Returns a *dict-like* object with the results of the analysis
352
+
353
+ The keys and format of analysis results in the dictionary is
354
+ implementation dependent.
355
+
356
+ It is not even enforced that the result is a *dict-like object*, just
357
+ the convention
358
+
359
+ The default implementation returns the default OrderedDict ``rets``
360
+ created by the default ``create_analysis`` method
361
+
362
+ # Return dict-like result analysis, specific format depends on implementation
363
+ """
364
+ return self.rets
365
+
366
+ # Print analysis
367
+ def print(self, *args, **kwargs):
368
+ """Prints the results returned by ``get_analysis`` via a standard
369
+ ``print`` call"""
370
+ # print analysis, print analysis results by calling, this content can be accessed via get_analysis
371
+ print(self.get_analysis())
372
+
373
+ # Pretty print analysis
374
+ def pprint(self, *args, **kwargs):
375
+ """Prints the results returned by ``get_analysis`` via a pretty print
376
+ call"""
377
+ # pretty print analysis, similar to above
378
+ pp.pprint(self.get_analysis(), *args, **kwargs)
379
+
380
+
381
+ # TimeFrameAnalyzerBase class - refactored to not use metaclass
382
+ class TimeFrameAnalyzerBase(Analyzer):
383
+ """Base class for time-frame aware analyzers.
384
+
385
+ This analyzer base operates on a specific timeframe (daily, weekly,
386
+ monthly, etc.) and calls on_dt_over() when the timeframe changes.
387
+
388
+ Params:
389
+ timeframe: TimeFrame to use (None = use data's timeframe).
390
+ compression: Compression factor (None = use data's compression).
391
+ _doprenext: Whether to call prenext (default: True).
392
+
393
+ Methods:
394
+ on_dt_over(): Override to handle timeframe changes.
395
+ """
396
+
397
+ # Parameters
398
+ params = (
399
+ ("timeframe", None),
400
+ ("compression", None),
401
+ ("_doprenext", True),
402
+ )
403
+
404
+ def __init__(self, *args, **kwargs):
405
+ """Initialize with functionality previously in MetaTimeFrameAnalyzerBase"""
406
+ super().__init__(*args, **kwargs)
407
+
408
+ # Backward compatibility: alias on_dt_over_orig to on_dt_over if needed
409
+ if hasattr(self, "on_dt_over_orig") and not hasattr(self, "on_dt_over"):
410
+ self.on_dt_over = self.on_dt_over_orig
411
+
412
+ def _start(self):
413
+ # Override to add specific attributes
414
+ # Set trading period, e.g., minutes
415
+ # Set trading period - use data's timeframe if not specified
416
+ self.timeframe = self.p.timeframe or self.data._timeframe
417
+ # Set compression - use data's compression if not specified
418
+ self.compression = self.p.compression or self.data._compression
419
+ # CRITICAL FIX: Initialize dtcmp with datetime.min to match master branch behavior
420
+ # This ensures first _dt_over() call detects a change and counts correctly
421
+ self.dtcmp, self.dtkey = self._get_dt_cmpkey(datetime.datetime.min)
422
+ super()._start()
423
+
424
+ def _prenext(self):
425
+ # Match master branch: call children, check _dt_over, then prenext
426
+ for child in self._children:
427
+ child._prenext()
428
+
429
+ if self._dt_over():
430
+ self.on_dt_over()
431
+
432
+ if self.p._doprenext:
433
+ self.prenext()
434
+
435
+ def _nextstart(self):
436
+ # Match master branch: call children, check _dt_over or not doprenext, then nextstart
437
+ for child in self._children:
438
+ child._nextstart()
439
+
440
+ if self._dt_over() or not self.p._doprenext:
441
+ self.on_dt_over()
442
+
443
+ self.nextstart()
444
+
445
+ def _next(self):
446
+ # Match master branch: call children, check _dt_over, then next
447
+ for child in self._children:
448
+ child._next()
449
+
450
+ if self._dt_over():
451
+ self.on_dt_over()
452
+
453
+ self.next()
454
+
455
+ # This method generally needs to be overridden in subclasses
456
+ def on_dt_over(self):
457
+ """Called when the timeframe period changes.
458
+
459
+ This method is called when the datetime crosses into a new
460
+ period of the configured timeframe (e.g., new week, new month).
461
+
462
+ Note:
463
+ Override this method to implement period-based analysis logic.
464
+ """
465
+
466
+ # CRITICAL FIX: Match master branch - return boolean and update dtcmp atomically
467
+ # PERFORMANCE OPTIMIZATION: Cache attribute access, called 1.4M+ times
468
+ def _dt_over(self):
469
+ # If trading period equals NoTimeFrame, dtcmp equals maximum integer, dtkey equals maximum time
470
+ tf = self.timeframe
471
+ if tf == TimeFrame.NoTimeFrame:
472
+ dtcmp, dtkey = MAXINT, datetime.datetime.max
473
+ else:
474
+ # Get current datetime from strategy
475
+ dt = self.strategy.datetime.datetime()
476
+ dtcmp, dtkey = self._get_dt_cmpkey(dt, tf)
477
+
478
+ # If dtcmp is None, or dtcmp is greater than self.dtcmp
479
+ cur_dtcmp = self.dtcmp
480
+ if cur_dtcmp is None or dtcmp > cur_dtcmp:
481
+ # Set dtkey, dtkey1, dtcmp, dtcmp1 return True
482
+ self.dtkey, self.dtkey1 = dtkey, self.dtkey
483
+ self.dtcmp, self.dtcmp1 = dtcmp, cur_dtcmp
484
+ return True
485
+ # Return False
486
+ return False
487
+
488
+ # Get dtcmp, dtkey
489
+ # PERFORMANCE OPTIMIZATION: Accept tf parameter to avoid repeated attribute access
490
+ def _get_dt_cmpkey(self, dt, tf=None):
491
+ # If current trading period has NoTimeFrame, return two Nones
492
+ if tf is None:
493
+ tf = self.timeframe
494
+ if tf == TimeFrame.NoTimeFrame:
495
+ return None, None
496
+ # If current trading period is years
497
+ if tf == TimeFrame.Years:
498
+ dtcmp = dt.year
499
+ dtkey = datetime.date(dt.year, 12, 31)
500
+ # If trading period is months
501
+ elif tf == TimeFrame.Months:
502
+ dtcmp = dt.year * 100 + dt.month
503
+ # Get last day
504
+ _, lastday = calendar.monthrange(dt.year, dt.month)
505
+ # Get last day of each month
506
+ dtkey = datetime.datetime(dt.year, dt.month, lastday)
507
+ # If trading period is weeks
508
+ elif tf == TimeFrame.Weeks:
509
+ # Return year, week number and weekday for date
510
+ isoyear, isoweek, isoweekday = dt.isocalendar()
511
+ dtcmp = isoyear * 1000 + isoweek
512
+ # Weekend
513
+ sunday = dt + datetime.timedelta(days=7 - isoweekday)
514
+ # Get last day of each week
515
+ dtkey = datetime.datetime(sunday.year, sunday.month, sunday.day)
516
+ # If trading period is days, calculate specific dtcmp, dtkey
517
+ elif tf == TimeFrame.Days:
518
+ dtcmp = dt.year * 10000 + dt.month * 100 + dt.day
519
+ dtkey = datetime.datetime(dt.year, dt.month, dt.day)
520
+ # If trading period is less than days, call _get_subday_cmpkey to get
521
+ else:
522
+ dtcmp, dtkey = self._get_subday_cmpkey(dt)
523
+
524
+ return dtcmp, dtkey
525
+
526
+ # If trading period is less than days
527
+ def _get_subday_cmpkey(self, dt):
528
+ # Calculate intraday position
529
+ # Calculate current number of minutes
530
+ point = dt.hour * 60 + dt.minute
531
+ # If current trading period is less than minutes, convert point to seconds
532
+ if self.timeframe < TimeFrame.Minutes:
533
+ point = point * 60 + dt.second
534
+ # If current trading period is less than seconds, convert point to microseconds
535
+ if self.timeframe < TimeFrame.Seconds:
536
+ point = point * 1e6 + dt.microsecond
537
+
538
+ # Apply compression to update point position (comp 5 -> 200 // 5)
539
+ # Calculate current point based on number of periods
540
+ point = point // self.compression
541
+
542
+ # Move to next boundary
543
+ # Move to next
544
+ point += 1
545
+
546
+ # Restore point to the timeframe units by de-applying compression
547
+ # Calculate end position of next point
548
+ point *= self.compression
549
+
550
+ # Get hours, minutes, seconds and microseconds
551
+ # If trading period equals minutes, get ph, pm
552
+ if self.timeframe == TimeFrame.Minutes:
553
+ ph, pm = divmod(point, 60)
554
+ ps = 0
555
+ pus = 0
556
+ # If trading period equals seconds, get ph, pm, ps
557
+ elif self.timeframe == TimeFrame.Seconds:
558
+ ph, pm = divmod(point, 60 * 60)
559
+ pm, ps = divmod(pm, 60)
560
+ pus = 0
561
+ # If microseconds, get ph, pm, ps, pus
562
+ elif self.timeframe == TimeFrame.MicroSeconds:
563
+ ph, pm = divmod(point, 60 * 60 * 1e6)
564
+ pm, psec = divmod(pm, 60 * 1e6)
565
+ ps, pus = divmod(psec, 1e6)
566
+ # Whether it's the next day
567
+ extradays = 0
568
+ # If hour is greater than 23, divide, calculate if it's the next day
569
+ if ph > 23: # went over midnight:
570
+ extradays = ph // 24
571
+ ph %= 24
572
+
573
+ # moving 1 minor unit to the left to be in the boundary
574
+ # Time to adjust
575
+ tadjust = datetime.timedelta(
576
+ minutes=self.timeframe == TimeFrame.Minutes,
577
+ seconds=self.timeframe == TimeFrame.Seconds,
578
+ microseconds=self.timeframe == TimeFrame.MicroSeconds,
579
+ )
580
+
581
+ # Add extra day if present
582
+ # If next day is True, adjust time to next day
583
+ if extradays:
584
+ dt += datetime.timedelta(days=extradays)
585
+
586
+ # Replace intraday parts with the calculated ones and update it
587
+ # Calculate dtcmp
588
+ dtcmp = dt.replace(hour=int(ph), minute=int(pm), second=int(ps), microsecond=int(pus))
589
+ # Adjust dtcmp
590
+ dtcmp -= tadjust
591
+ # dtkey equals dtcmp
592
+ dtkey = dtcmp
593
+
594
+ return dtcmp, dtkey
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env python
2
+ """Performance Analyzers Module.
3
+
4
+ This module provides a collection of analyzers for evaluating strategy
5
+ performance. Analyzers calculate metrics like returns, drawdowns, Sharpe
6
+ ratio, trade statistics, and more.
7
+
8
+ Available Analyzers:
9
+ - AnnualReturn: Annual return breakdown
10
+ - Calmar: Calmar ratio (return / max drawdown)
11
+ - DrawDown: Drawdown analysis
12
+ - Leverage: Leverage tracking
13
+ - LogReturnsRolling: Rolling log returns
14
+ - PeriodStats: Statistics by period
15
+ - Positions: Position analysis
16
+ - PyFolio: PyFolio integration
17
+ - Returns: Return analysis
18
+ - Sharpe: Sharpe ratio
19
+ - SQN: System Quality Number
20
+ - TimeReturn: Time-weighted returns
21
+ - TotalValue: Total value tracking
22
+ - TradeAnalyzer: Detailed trade statistics
23
+ - Transactions: Transaction log
24
+ - VWR: Variance-Weighted Return
25
+
26
+ Example:
27
+ Adding analyzers to a strategy:
28
+ >>> cerebro.addanalyzer(bt.analyzers.Sharpe, _name='sharpe')
29
+ >>> cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')
30
+ """
31
+
32
+ # The modules below should/must define __all__ with the objects wishes
33
+ # or prepend an "_" (underscore) to private classes/variables
34
+
35
+ from .annualreturn import *
36
+ from .calmar import *
37
+ from .drawdown import *
38
+ from .leverage import *
39
+ from .logreturnsrolling import *
40
+ from .periodstats import *
41
+ from .positions import *
42
+ from .pyfolio import *
43
+ from .returns import *
44
+ from .sharpe import *
45
+ from .sqn import *
46
+ from .timereturn import *
47
+ from .total_value import *
48
+ from .tradeanalyzer import *
49
+ from .transactions import *
50
+ from .vwr import *