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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. back_trader_python-1.4.0.dist-info/METADATA +1491 -0
  2. back_trader_python-1.4.0.dist-info/RECORD +465 -0
  3. back_trader_python-1.4.0.dist-info/WHEEL +5 -0
  4. back_trader_python-1.4.0.dist-info/licenses/LICENSE +674 -0
  5. back_trader_python-1.4.0.dist-info/top_level.txt +1 -0
  6. backtrader/__init__.py +148 -0
  7. backtrader/_cerebro/__init__.py +5 -0
  8. backtrader/_cerebro/channel.py +382 -0
  9. backtrader/_cerebro/execution.py +377 -0
  10. backtrader/_cerebro/lifecycle.py +143 -0
  11. backtrader/_cerebro/notifications.py +150 -0
  12. backtrader/_cerebro/presentation.py +230 -0
  13. backtrader/_cerebro/registry.py +593 -0
  14. backtrader/_cerebro/runnext.py +551 -0
  15. backtrader/_cerebro/runonce.py +142 -0
  16. backtrader/analyzer.py +594 -0
  17. backtrader/analyzers/__init__.py +50 -0
  18. backtrader/analyzers/annualreturn.py +226 -0
  19. backtrader/analyzers/calmar.py +165 -0
  20. backtrader/analyzers/drawdown.py +287 -0
  21. backtrader/analyzers/leverage.py +112 -0
  22. backtrader/analyzers/logreturnsrolling.py +190 -0
  23. backtrader/analyzers/periodstats.py +153 -0
  24. backtrader/analyzers/positions.py +119 -0
  25. backtrader/analyzers/pyfolio.py +470 -0
  26. backtrader/analyzers/returns.py +192 -0
  27. backtrader/analyzers/sharpe.py +307 -0
  28. backtrader/analyzers/sharpe_ratio_stats.py +534 -0
  29. backtrader/analyzers/sqn.py +112 -0
  30. backtrader/analyzers/timereturn.py +192 -0
  31. backtrader/analyzers/total_value.py +75 -0
  32. backtrader/analyzers/tradeanalyzer.py +278 -0
  33. backtrader/analyzers/transactions.py +141 -0
  34. backtrader/analyzers/vwr.py +245 -0
  35. backtrader/bokeh/__init__.py +155 -0
  36. backtrader/bokeh/analyzers/__init__.py +13 -0
  37. backtrader/bokeh/analyzers/plot.py +192 -0
  38. backtrader/bokeh/analyzers/recorder.py +181 -0
  39. backtrader/bokeh/app.py +1094 -0
  40. backtrader/bokeh/live/__init__.py +11 -0
  41. backtrader/bokeh/live/client.py +352 -0
  42. backtrader/bokeh/live/datahandler.py +346 -0
  43. backtrader/bokeh/plot_adapter.py +200 -0
  44. backtrader/bokeh/schemes/__init__.py +14 -0
  45. backtrader/bokeh/schemes/blackly.py +76 -0
  46. backtrader/bokeh/schemes/scheme.py +150 -0
  47. backtrader/bokeh/schemes/tradimo.py +82 -0
  48. backtrader/bokeh/tab.py +125 -0
  49. backtrader/bokeh/tabs/__init__.py +30 -0
  50. backtrader/bokeh/tabs/analyzer.py +120 -0
  51. backtrader/bokeh/tabs/config.py +154 -0
  52. backtrader/bokeh/tabs/live.py +109 -0
  53. backtrader/bokeh/tabs/log.py +185 -0
  54. backtrader/bokeh/tabs/metadata.py +182 -0
  55. backtrader/bokeh/tabs/performance.py +359 -0
  56. backtrader/bokeh/tabs/source.py +70 -0
  57. backtrader/bokeh/utils/__init__.py +8 -0
  58. backtrader/bokeh/utils/helpers.py +167 -0
  59. backtrader/bokeh/webapp.py +164 -0
  60. backtrader/broker.py +478 -0
  61. backtrader/brokers/__init__.py +36 -0
  62. backtrader/brokers/bbroker.py +2576 -0
  63. backtrader/brokers/btapibroker.py +8227 -0
  64. backtrader/brokers/hft/__init__.py +89 -0
  65. backtrader/brokers/hft/binance_bbo.py +625 -0
  66. backtrader/brokers/hft/binance_bbo_compare.py +1398 -0
  67. backtrader/brokers/hft/examples.py +1228 -0
  68. backtrader/brokers/hft/exchange.py +380 -0
  69. backtrader/brokers/hft/latency.py +309 -0
  70. backtrader/brokers/hft/matching_core.py +572 -0
  71. backtrader/brokers/hft/queue.py +238 -0
  72. backtrader/brokers/hft/recorder.py +88 -0
  73. backtrader/brokers/hft/state.py +138 -0
  74. backtrader/brokers/impact_models.py +118 -0
  75. backtrader/brokers/mixbroker.py +895 -0
  76. backtrader/brokers/tickbroker.py +1991 -0
  77. backtrader/btrun/__init__.py +12 -0
  78. backtrader/btrun/btrun.py +1218 -0
  79. backtrader/cerebro.py +828 -0
  80. backtrader/channel.py +682 -0
  81. backtrader/channels/__init__.py +23 -0
  82. backtrader/channels/bridge.py +186 -0
  83. backtrader/channels/funding.py +248 -0
  84. backtrader/channels/live_queue.py +216 -0
  85. backtrader/channels/live_validator.py +294 -0
  86. backtrader/channels/orderbook.py +257 -0
  87. backtrader/channels/tick.py +202 -0
  88. backtrader/comminfo.py +665 -0
  89. backtrader/commissions/__init__.py +106 -0
  90. backtrader/commissions/ctpoption.py +993 -0
  91. backtrader/configs/account_config_example.yaml +8 -0
  92. backtrader/dataseries.py +379 -0
  93. backtrader/errors.py +106 -0
  94. backtrader/events.py +980 -0
  95. backtrader/feed.py +1523 -0
  96. backtrader/feeds/__init__.py +75 -0
  97. backtrader/feeds/barrier.py +2006 -0
  98. backtrader/feeds/blaze.py +118 -0
  99. backtrader/feeds/btapifeed.py +1538 -0
  100. backtrader/feeds/btcsv.py +203 -0
  101. backtrader/feeds/chainer.py +114 -0
  102. backtrader/feeds/cryptohftdata.py +164 -0
  103. backtrader/feeds/csvgeneric.py +1205 -0
  104. backtrader/feeds/ctpcohort.py +1051 -0
  105. backtrader/feeds/influxfeed.py +158 -0
  106. backtrader/feeds/livefeed.py +71 -0
  107. backtrader/feeds/mixed_channel.py +108 -0
  108. backtrader/feeds/mt4csv.py +42 -0
  109. backtrader/feeds/pandafeed.py +381 -0
  110. backtrader/feeds/quandl.py +256 -0
  111. backtrader/feeds/rollover.py +229 -0
  112. backtrader/feeds/sierrachart.py +30 -0
  113. backtrader/feeds/vchart.py +162 -0
  114. backtrader/feeds/vchartcsv.py +84 -0
  115. backtrader/feeds/vchartfile.py +153 -0
  116. backtrader/feeds/yahoo.py +399 -0
  117. backtrader/fillers.py +148 -0
  118. backtrader/filters/__init__.py +34 -0
  119. backtrader/filters/bsplitter.py +127 -0
  120. backtrader/filters/calendardays.py +121 -0
  121. backtrader/filters/datafiller.py +192 -0
  122. backtrader/filters/datafilter.py +74 -0
  123. backtrader/filters/daysteps.py +96 -0
  124. backtrader/filters/heikinashi.py +63 -0
  125. backtrader/filters/renko.py +164 -0
  126. backtrader/filters/session.py +289 -0
  127. backtrader/flt.py +80 -0
  128. backtrader/functions.py +960 -0
  129. backtrader/indicator.py +449 -0
  130. backtrader/indicators/__init__.py +148 -0
  131. backtrader/indicators/accdecoscillator.py +110 -0
  132. backtrader/indicators/aroon.py +300 -0
  133. backtrader/indicators/atr.py +315 -0
  134. backtrader/indicators/awesomeoscillator.py +122 -0
  135. backtrader/indicators/basicops.py +834 -0
  136. backtrader/indicators/bollinger.py +223 -0
  137. backtrader/indicators/cci.py +89 -0
  138. backtrader/indicators/channels_ext.py +83 -0
  139. backtrader/indicators/contrib/__init__.py +228 -0
  140. backtrader/indicators/contrib/absolutely_no_lag_lwma.py +28 -0
  141. backtrader/indicators/contrib/absolutely_no_lag_lwma_color.py +44 -0
  142. backtrader/indicators/contrib/accumulation_distribution_line.py +92 -0
  143. backtrader/indicators/contrib/adx_cross_hull_style_indicator.py +249 -0
  144. backtrader/indicators/contrib/adxdmi.py +34 -0
  145. backtrader/indicators/contrib/ai_acceleration_deceleration_oscillator.py +34 -0
  146. backtrader/indicators/contrib/altr_trend_signal_v22.py +85 -0
  147. backtrader/indicators/contrib/anchored_momentum_line.py +115 -0
  148. backtrader/indicators/contrib/any_range_cld_tail_indicator.py +82 -0
  149. backtrader/indicators/contrib/aroon_horn_sign_indicator.py +96 -0
  150. backtrader/indicators/contrib/aroon_oscillator_sign_alert.py +50 -0
  151. backtrader/indicators/contrib/arrows_curves_indicator.py +112 -0
  152. backtrader/indicators/contrib/as_ctrend_indicator.py +143 -0
  153. backtrader/indicators/contrib/asimmetric_stoch_nr_indicator.py +187 -0
  154. backtrader/indicators/contrib/atr_normalize_histogram.py +118 -0
  155. backtrader/indicators/contrib/average_change_candle.py +165 -0
  156. backtrader/indicators/contrib/bb_squeeze_indicator.py +60 -0
  157. backtrader/indicators/contrib/bezier_st_dev_indicator.py +135 -0
  158. backtrader/indicators/contrib/binary_wave_indicator.py +233 -0
  159. backtrader/indicators/contrib/blau_c_momentum_indicator.py +123 -0
  160. backtrader/indicators/contrib/blau_cmi_indicator.py +141 -0
  161. backtrader/indicators/contrib/blau_csi.py +76 -0
  162. backtrader/indicators/contrib/blau_ergodic.py +53 -0
  163. backtrader/indicators/contrib/blau_t_stoch_i.py +72 -0
  164. backtrader/indicators/contrib/blau_ts_stochastic.py +85 -0
  165. backtrader/indicators/contrib/blau_tvi.py +55 -0
  166. backtrader/indicators/contrib/brain_trend2_indicator.py +128 -0
  167. backtrader/indicators/contrib/brain_trend_signal_proxy.py +47 -0
  168. backtrader/indicators/contrib/brake_parb_indicator.py +85 -0
  169. backtrader/indicators/contrib/breakout_bars_trend_v2.py +121 -0
  170. backtrader/indicators/contrib/bsi_indicator.py +87 -0
  171. backtrader/indicators/contrib/bulls_bears_eyes.py +67 -0
  172. backtrader/indicators/contrib/bulls_power.py +56 -0
  173. backtrader/indicators/contrib/bw_wise_man1_signal.py +102 -0
  174. backtrader/indicators/contrib/bykov_trend_indicator.py +85 -0
  175. backtrader/indicators/contrib/candle_stop_color.py +46 -0
  176. backtrader/indicators/contrib/candles_x_smoothed_indicator.py +69 -0
  177. backtrader/indicators/contrib/candlesticks_bw.py +45 -0
  178. backtrader/indicators/contrib/caudate_x_period_candle_color.py +56 -0
  179. backtrader/indicators/contrib/cci_histogram_indicator.py +53 -0
  180. backtrader/indicators/contrib/cci_woodies_indicator.py +80 -0
  181. backtrader/indicators/contrib/center_of_gravity_candle_indicator.py +83 -0
  182. backtrader/indicators/contrib/center_of_gravity_indicator.py +70 -0
  183. backtrader/indicators/contrib/cg_oscillator.py +40 -0
  184. backtrader/indicators/contrib/close_line_cci.py +38 -0
  185. backtrader/indicators/contrib/close_price_fractals.py +47 -0
  186. backtrader/indicators/contrib/color3rd_gen_xma_indicator.py +122 -0
  187. backtrader/indicators/contrib/color_bb_candles_indicator.py +108 -0
  188. backtrader/indicators/contrib/color_coppock_indicator.py +157 -0
  189. backtrader/indicators/contrib/color_hma.py +71 -0
  190. backtrader/indicators/contrib/color_j_variation_indicator.py +53 -0
  191. backtrader/indicators/contrib/color_metro_de_marker_indicator.py +78 -0
  192. backtrader/indicators/contrib/color_metro_stochastic_indicator.py +93 -0
  193. backtrader/indicators/contrib/color_metro_wpr_indicator.py +85 -0
  194. backtrader/indicators/contrib/color_schaff_de_marker_trend_cycle.py +92 -0
  195. backtrader/indicators/contrib/color_schaff_trend_cycle_indicator.py +203 -0
  196. backtrader/indicators/contrib/color_step_xccx_indicator.py +193 -0
  197. backtrader/indicators/contrib/color_x2_ma.py +49 -0
  198. backtrader/indicators/contrib/color_x_derivative.py +63 -0
  199. backtrader/indicators/contrib/color_zerolag_de_marker.py +84 -0
  200. backtrader/indicators/contrib/corrected_average_indicator.py +127 -0
  201. backtrader/indicators/contrib/darvas_boxes_system.py +73 -0
  202. backtrader/indicators/contrib/dema_range_channel_color.py +42 -0
  203. backtrader/indicators/contrib/derivative_indicator.py +95 -0
  204. backtrader/indicators/contrib/digital_ft01_indicator.py +112 -0
  205. backtrader/indicators/contrib/digital_macd.py +200 -0
  206. backtrader/indicators/contrib/donchian_channels_system.py +45 -0
  207. backtrader/indicators/contrib/dots_indicator.py +93 -0
  208. backtrader/indicators/contrib/ef_distance_indicator.py +82 -0
  209. backtrader/indicators/contrib/ema_rsi_va.py +80 -0
  210. backtrader/indicators/contrib/envelopes_jp_alonso.py +32 -0
  211. backtrader/indicators/contrib/f2a_ao_indicator.py +120 -0
  212. backtrader/indicators/contrib/fatl_filter.py +179 -0
  213. backtrader/indicators/contrib/fibo_candles_indicator.py +78 -0
  214. backtrader/indicators/contrib/fine_tuning_ma.py +100 -0
  215. backtrader/indicators/contrib/fisher_org_v1.py +102 -0
  216. backtrader/indicators/contrib/fisher_org_v1_sign.py +118 -0
  217. backtrader/indicators/contrib/force_index_ema.py +96 -0
  218. backtrader/indicators/contrib/force_index_ema_2.py +27 -0
  219. backtrader/indicators/contrib/forecast_oscilator.py +145 -0
  220. backtrader/indicators/contrib/fractal_amambk.py +81 -0
  221. backtrader/indicators/contrib/frama_series.py +84 -0
  222. backtrader/indicators/contrib/frasm_av2_indicator.py +104 -0
  223. backtrader/indicators/contrib/go_indicator.py +93 -0
  224. backtrader/indicators/contrib/hlr_indicator.py +95 -0
  225. backtrader/indicators/contrib/hma.py +50 -0
  226. backtrader/indicators/contrib/i4_drfv2.py +34 -0
  227. backtrader/indicators/contrib/i4_drfv3.py +38 -0
  228. backtrader/indicators/contrib/i_anch_mom_indicator.py +72 -0
  229. backtrader/indicators/contrib/i_de_marker_sign_indicator.py +64 -0
  230. backtrader/indicators/contrib/i_gap_indicator.py +45 -0
  231. backtrader/indicators/contrib/i_stoch_komposter_indicator.py +77 -0
  232. backtrader/indicators/contrib/i_trend_indicator.py +125 -0
  233. backtrader/indicators/contrib/iamma_indicator.py +39 -0
  234. backtrader/indicators/contrib/indexed_moving_average.py +33 -0
  235. backtrader/indicators/contrib/instantaneous_trend_filter_indicator.py +51 -0
  236. backtrader/indicators/contrib/inverse_reaction_indicator.py +41 -0
  237. backtrader/indicators/contrib/irsi_sign_indicator.py +95 -0
  238. backtrader/indicators/contrib/iwpr_sign_indicator.py +59 -0
  239. backtrader/indicators/contrib/j_brain_trend1_sig_indicator.py +233 -0
  240. backtrader/indicators/contrib/j_tpo_proxy.py +32 -0
  241. backtrader/indicators/contrib/jma_slope_indicator.py +73 -0
  242. backtrader/indicators/contrib/kalman_filter_indicator.py +119 -0
  243. backtrader/indicators/contrib/kalman_filter_line.py +127 -0
  244. backtrader/indicators/contrib/kama_indicator.py +150 -0
  245. backtrader/indicators/contrib/karacatica_indicator.py +99 -0
  246. backtrader/indicators/contrib/kdj_indicator.py +59 -0
  247. backtrader/indicators/contrib/kwan_ccc_indicator.py +195 -0
  248. backtrader/indicators/contrib/kwan_nrp_indicator.py +113 -0
  249. backtrader/indicators/contrib/kwan_rdp_indicator.py +192 -0
  250. backtrader/indicators/contrib/laguerre_adx_indicator.py +85 -0
  251. backtrader/indicators/contrib/laguerre_filter_indicator.py +66 -0
  252. backtrader/indicators/contrib/laguerre_plus_di_proxy.py +57 -0
  253. backtrader/indicators/contrib/laguerre_roc_indicator.py +81 -0
  254. backtrader/indicators/contrib/le_man_signal_indicator.py +63 -0
  255. backtrader/indicators/contrib/linear_reg_slope_v2_indicator.py +136 -0
  256. backtrader/indicators/contrib/loco_indicator.py +88 -0
  257. backtrader/indicators/contrib/lrma_indicator.py +185 -0
  258. backtrader/indicators/contrib/lsma_angle_indicator.py +106 -0
  259. backtrader/indicators/contrib/ma_rounding_channel_indicator.py +149 -0
  260. backtrader/indicators/contrib/macd2_indicator.py +61 -0
  261. backtrader/indicators/contrib/macd_candle_indicator.py +80 -0
  262. backtrader/indicators/contrib/malr_indicator.py +77 -0
  263. backtrader/indicators/contrib/momentum_candle_sign_indicator.py +51 -0
  264. backtrader/indicators/contrib/moving_average_fn_indicator.py +139 -0
  265. backtrader/indicators/contrib/mt5_stochastic_close_close.py +57 -0
  266. backtrader/indicators/contrib/muv_nor_diff_cloud_indicator.py +107 -0
  267. backtrader/indicators/contrib/non_lag_dot_indicator.py +124 -0
  268. backtrader/indicators/contrib/nrtr_extr_indicator.py +95 -0
  269. backtrader/indicators/contrib/nrtr_indicator.py +95 -0
  270. backtrader/indicators/contrib/p_channel_system.py +40 -0
  271. backtrader/indicators/contrib/percent_envelope.py +37 -0
  272. backtrader/indicators/contrib/percentage_crossover_channel.py +47 -0
  273. backtrader/indicators/contrib/pivot_zig_zag_proxy.py +47 -0
  274. backtrader/indicators/contrib/price_channel_stop_indicator.py +104 -0
  275. backtrader/indicators/contrib/price_extreme_channel.py +35 -0
  276. backtrader/indicators/contrib/qqe_cloud_indicator.py +129 -0
  277. backtrader/indicators/contrib/ravi_indicator.py +40 -0
  278. backtrader/indicators/contrib/raw_close_close_stochastic.py +74 -0
  279. backtrader/indicators/contrib/rd_trend_trigger_indicator.py +51 -0
  280. backtrader/indicators/contrib/renko_level.py +85 -0
  281. backtrader/indicators/contrib/renko_line_break.py +91 -0
  282. backtrader/indicators/contrib/rftl_indicator.py +41 -0
  283. backtrader/indicators/contrib/rkd_indicator.py +53 -0
  284. backtrader/indicators/contrib/roc2_vg_indicator.py +68 -0
  285. backtrader/indicators/contrib/rsi_histogram_indicator.py +43 -0
  286. backtrader/indicators/contrib/rsi_slowdown.py +57 -0
  287. backtrader/indicators/contrib/rsioma_v2.py +41 -0
  288. backtrader/indicators/contrib/rvi_histogram_indicator.py +107 -0
  289. backtrader/indicators/contrib/safe_adx.py +89 -0
  290. backtrader/indicators/contrib/shared_strategy_indicators.py +1651 -0
  291. backtrader/indicators/contrib/sidus_indicator.py +105 -0
  292. backtrader/indicators/contrib/silver_trend_indicator.py +79 -0
  293. backtrader/indicators/contrib/sliding_range_color.py +56 -0
  294. backtrader/indicators/contrib/slow_stoch.py +42 -0
  295. backtrader/indicators/contrib/smoothed_adx_indicator.py +86 -0
  296. backtrader/indicators/contrib/smoothed_rsi.py +31 -0
  297. backtrader/indicators/contrib/spearman_rank_correlation_histogram.py +60 -0
  298. backtrader/indicators/contrib/stalin_indicator.py +152 -0
  299. backtrader/indicators/contrib/starter_laguerre_filter.py +62 -0
  300. backtrader/indicators/contrib/step_manrtr_indicator.py +137 -0
  301. backtrader/indicators/contrib/stochastic_histogram_indicator.py +143 -0
  302. backtrader/indicators/contrib/t3_alarm_indicator.py +125 -0
  303. backtrader/indicators/contrib/t3_average.py +76 -0
  304. backtrader/indicators/contrib/t3_indicator.py +40 -0
  305. backtrader/indicators/contrib/the20s_v020_signal.py +93 -0
  306. backtrader/indicators/contrib/three_candles_indicator.py +70 -0
  307. backtrader/indicators/contrib/three_line_break_indicator.py +64 -0
  308. backtrader/indicators/contrib/time_line.py +57 -0
  309. backtrader/indicators/contrib/trading_channel_index_proxy.py +48 -0
  310. backtrader/indicators/contrib/trend_arrows_indicator.py +109 -0
  311. backtrader/indicators/contrib/trend_continuation_indicator.py +127 -0
  312. backtrader/indicators/contrib/trend_intensity_index_proxy.py +51 -0
  313. backtrader/indicators/contrib/trend_manager_indicator.py +39 -0
  314. backtrader/indicators/contrib/tri_x_candle_indicator.py +51 -0
  315. backtrader/indicators/contrib/trigger_line.py +66 -0
  316. backtrader/indicators/contrib/triple_ema_rate.py +34 -0
  317. backtrader/indicators/contrib/trvi_indicator.py +194 -0
  318. backtrader/indicators/contrib/two_pb_ideal_xosma_indicator.py +127 -0
  319. backtrader/indicators/contrib/ultra_absolutely_no_lag_lwma_color.py +92 -0
  320. backtrader/indicators/contrib/ultra_wpr_indicator.py +173 -0
  321. backtrader/indicators/contrib/up_down_candle_strength.py +68 -0
  322. backtrader/indicators/contrib/vinin_i_trend_indicator.py +139 -0
  323. backtrader/indicators/contrib/volume_weighted_ma_indicator.py +78 -0
  324. backtrader/indicators/contrib/volume_weighted_ma_st_dev_indicator.py +111 -0
  325. backtrader/indicators/contrib/vwap_close_indicator.py +65 -0
  326. backtrader/indicators/contrib/vwma_candle.py +57 -0
  327. backtrader/indicators/contrib/vwma_digit_system.py +70 -0
  328. backtrader/indicators/contrib/wami.py +43 -0
  329. backtrader/indicators/contrib/wprsi_signal_indicator.py +105 -0
  330. backtrader/indicators/contrib/x_de_marker_histogram_vol_direct_indicator.py +145 -0
  331. backtrader/indicators/contrib/x_fisher_indicator.py +64 -0
  332. backtrader/indicators/contrib/xcci_histogram_vol_direct_indicator.py +56 -0
  333. backtrader/indicators/contrib/xcci_histogram_vol_indicator.py +85 -0
  334. backtrader/indicators/contrib/xma_ichimoku.py +163 -0
  335. backtrader/indicators/contrib/xma_ishimoku_channel_indicator.py +65 -0
  336. backtrader/indicators/contrib/xma_ishimoku_line.py +68 -0
  337. backtrader/indicators/contrib/xma_range_bands_indicator.py +107 -0
  338. backtrader/indicators/contrib/xmacd_indicator.py +70 -0
  339. backtrader/indicators/contrib/xrsi_de_marker_histogram.py +67 -0
  340. backtrader/indicators/contrib/xrsi_histogram_vol_direct_indicator.py +52 -0
  341. backtrader/indicators/contrib/xrsi_histogram_vol_indicator.py +81 -0
  342. backtrader/indicators/contrib/xrvi_indicator.py +130 -0
  343. backtrader/indicators/contrib/zero_lag_macd.py +36 -0
  344. backtrader/indicators/contrib/zig_zag_recent_pivot_signal.py +90 -0
  345. backtrader/indicators/contrib/zpf_indicator.py +115 -0
  346. backtrader/indicators/crossover.py +337 -0
  347. backtrader/indicators/dema.py +175 -0
  348. backtrader/indicators/demarker.py +270 -0
  349. backtrader/indicators/deviation.py +284 -0
  350. backtrader/indicators/directionalmove.py +1071 -0
  351. backtrader/indicators/dma.py +112 -0
  352. backtrader/indicators/dpo.py +96 -0
  353. backtrader/indicators/dv2.py +56 -0
  354. backtrader/indicators/ema.py +145 -0
  355. backtrader/indicators/envelope.py +475 -0
  356. backtrader/indicators/hadelta.py +198 -0
  357. backtrader/indicators/heikinashi.py +153 -0
  358. backtrader/indicators/hma.py +153 -0
  359. backtrader/indicators/hurst.py +151 -0
  360. backtrader/indicators/ichimoku.py +267 -0
  361. backtrader/indicators/kama.py +181 -0
  362. backtrader/indicators/kst.py +159 -0
  363. backtrader/indicators/lrsi.py +125 -0
  364. backtrader/indicators/mabase.py +147 -0
  365. backtrader/indicators/macd.py +322 -0
  366. backtrader/indicators/momentum.py +267 -0
  367. backtrader/indicators/moneyflow.py +237 -0
  368. backtrader/indicators/mt5atr.py +124 -0
  369. backtrader/indicators/myind.py +179 -0
  370. backtrader/indicators/obv.py +94 -0
  371. backtrader/indicators/ols.py +265 -0
  372. backtrader/indicators/oscillator.py +161 -0
  373. backtrader/indicators/percentchange.py +83 -0
  374. backtrader/indicators/percentrank.py +46 -0
  375. backtrader/indicators/pivotpoint.py +469 -0
  376. backtrader/indicators/prettygoodoscillator.py +113 -0
  377. backtrader/indicators/priceops_ext.py +123 -0
  378. backtrader/indicators/priceoscillator.py +262 -0
  379. backtrader/indicators/psar.py +212 -0
  380. backtrader/indicators/rmi.py +69 -0
  381. backtrader/indicators/rsi.py +440 -0
  382. backtrader/indicators/sma.py +141 -0
  383. backtrader/indicators/smma.py +116 -0
  384. backtrader/indicators/spread.py +54 -0
  385. backtrader/indicators/stochastic.py +263 -0
  386. backtrader/indicators/supertrend.py +436 -0
  387. backtrader/indicators/trend_ext.py +105 -0
  388. backtrader/indicators/trix.py +202 -0
  389. backtrader/indicators/tsi.py +155 -0
  390. backtrader/indicators/ultimateoscillator.py +158 -0
  391. backtrader/indicators/vortex.py +62 -0
  392. backtrader/indicators/williams.py +194 -0
  393. backtrader/indicators/wma.py +103 -0
  394. backtrader/indicators/zlema.py +135 -0
  395. backtrader/indicators/zlind.py +104 -0
  396. backtrader/linebuffer.py +3155 -0
  397. backtrader/lineiterator.py +2911 -0
  398. backtrader/lineroot.py +1106 -0
  399. backtrader/lineseries.py +2559 -0
  400. backtrader/live_trading/__init__.py +31 -0
  401. backtrader/live_trading/interface.py +404 -0
  402. backtrader/mathsupport.py +94 -0
  403. backtrader/metabase.py +1804 -0
  404. backtrader/mixins/__init__.py +21 -0
  405. backtrader/mixins/singleton.py +118 -0
  406. backtrader/observer.py +106 -0
  407. backtrader/observers/__init__.py +45 -0
  408. backtrader/observers/benchmark.py +126 -0
  409. backtrader/observers/broker.py +184 -0
  410. backtrader/observers/buysell.py +144 -0
  411. backtrader/observers/drawdown.py +161 -0
  412. backtrader/observers/logreturns.py +113 -0
  413. backtrader/observers/timereturn.py +86 -0
  414. backtrader/observers/trade_logger.py +2972 -0
  415. backtrader/observers/tradelogger.py +6 -0
  416. backtrader/observers/trades.py +258 -0
  417. backtrader/order.py +1114 -0
  418. backtrader/parameters.py +2345 -0
  419. backtrader/plot/__init__.py +54 -0
  420. backtrader/plot/finance.py +1022 -0
  421. backtrader/plot/formatters.py +200 -0
  422. backtrader/plot/locator.py +353 -0
  423. backtrader/plot/multicursor.py +495 -0
  424. backtrader/plot/plot.py +2500 -0
  425. backtrader/plot/plot_plotly.py +1351 -0
  426. backtrader/plot/scheme.py +253 -0
  427. backtrader/plot/utils.py +104 -0
  428. backtrader/position.py +290 -0
  429. backtrader/position_modes.py +132 -0
  430. backtrader/profiles.py +254 -0
  431. backtrader/reports/__init__.py +39 -0
  432. backtrader/reports/charts.py +371 -0
  433. backtrader/reports/performance.py +620 -0
  434. backtrader/reports/reporter.py +660 -0
  435. backtrader/resamplerfilter.py +1001 -0
  436. backtrader/signal.py +118 -0
  437. backtrader/signals/__init__.py +17 -0
  438. backtrader/sizer.py +114 -0
  439. backtrader/sizers/__init__.py +26 -0
  440. backtrader/sizers/fixedsize.py +161 -0
  441. backtrader/sizers/percents_sizer.py +119 -0
  442. backtrader/store.py +221 -0
  443. backtrader/stores/__init__.py +33 -0
  444. backtrader/stores/btapistore.py +15506 -0
  445. backtrader/stores/livestore.py +137 -0
  446. backtrader/stores/vchartfile.py +96 -0
  447. backtrader/strategy.py +3655 -0
  448. backtrader/talib.py +280 -0
  449. backtrader/test_helpers.py +96 -0
  450. backtrader/timer.py +358 -0
  451. backtrader/trade.py +442 -0
  452. backtrader/tradingcal.py +361 -0
  453. backtrader/utils/__init__.py +68 -0
  454. backtrader/utils/autodict.py +251 -0
  455. backtrader/utils/date.py +71 -0
  456. backtrader/utils/dateintern.py +509 -0
  457. backtrader/utils/flushfile.py +94 -0
  458. backtrader/utils/fractal.py +101 -0
  459. backtrader/utils/get_metrics.py +101 -0
  460. backtrader/utils/load_data.py +209 -0
  461. backtrader/utils/log_message.py +998 -0
  462. backtrader/utils/ordereddefaultdict.py +75 -0
  463. backtrader/utils/py3.py +296 -0
  464. backtrader/version.py +21 -0
  465. backtrader/writer.py +372 -0
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env python
2
+ """Date/Time Conversion Utilities Module.
3
+
4
+ This module provides functions for converting between datetime objects
5
+ and numeric representations used internally by backtrader. It also
6
+ provides timezone handling utilities.
7
+
8
+ Exports:
9
+ date2num: Convert datetime to internal float representation.
10
+ num2date: Convert internal float to datetime.
11
+ num2dt: Alias for num2date.
12
+ time2num: Convert time to internal float representation.
13
+ num2time: Convert internal float to time.
14
+ tzparse: Parse timezone string.
15
+ Localizer: Timezone localization helper.
16
+ TZLocal: Local timezone instance.
17
+ UTC: UTC timezone instance.
18
+ TIME_MAX/TIME_MIN: Maximum/minimum time values.
19
+
20
+ Example:
21
+ >>> from backtrader.utils import date2num, num2date
22
+ >>> import datetime
23
+ >>> dt = datetime.datetime(2020, 1, 1)
24
+ >>> num = date2num(dt)
25
+ >>> print(num2date(num))
26
+ 2020-01-01 00:00:00+00:00
27
+ """
28
+
29
+ # from backtrader.utils.cython_func import date2num
30
+ # from backtrader.utils.cython_func import num2dt
31
+ # from backtrader.utils.cython_func import num2date
32
+ # from backtrader.utils.cython_func import time2num
33
+ # from backtrader.utils.cython_func import num2time
34
+
35
+ from .dateintern import (
36
+ TIME_MAX,
37
+ TIME_MIN,
38
+ UTC,
39
+ Localizer,
40
+ TZLocal,
41
+ date2num,
42
+ datetime2str,
43
+ datetime2timestamp,
44
+ get_last_timeframe_timestamp,
45
+ num2date,
46
+ num2dt,
47
+ num2time,
48
+ str2datetime,
49
+ time2num,
50
+ timestamp2datetime,
51
+ tzparse,
52
+ )
53
+
54
+ __all__ = (
55
+ "num2date",
56
+ "num2dt",
57
+ "date2num",
58
+ "time2num",
59
+ "num2time",
60
+ "get_last_timeframe_timestamp",
61
+ "UTC",
62
+ "TZLocal",
63
+ "Localizer",
64
+ "tzparse",
65
+ "TIME_MAX",
66
+ "TIME_MIN",
67
+ "timestamp2datetime",
68
+ "datetime2timestamp",
69
+ "str2datetime",
70
+ "datetime2str",
71
+ )
@@ -0,0 +1,509 @@
1
+ #!/usr/bin/env python
2
+ """Date Internal Module - Date/time conversion and timezone utilities.
3
+
4
+ This module provides internal utilities for date/time conversions,
5
+ timezone handling, and numeric date representations used throughout
6
+ backtrader.
7
+
8
+ Classes:
9
+ _UTC: UTC timezone implementation.
10
+ _LocalTimezone: Local timezone with DST support.
11
+
12
+ Functions:
13
+ tzparse: Parse timezone specification.
14
+ Localizer: Add localize method to timezone objects.
15
+ num2date: Convert numeric date to datetime.
16
+ num2dt: Convert numeric date to date.
17
+ num2time: Convert numeric date to time.
18
+ date2num: Convert datetime to numeric format.
19
+ time2num: Convert time to numeric format.
20
+
21
+ Constants:
22
+ UTC: Singleton UTC timezone instance.
23
+ TZLocal: Singleton local timezone instance.
24
+ TIME_MAX: Maximum time value (23:59:59.999990).
25
+ TIME_MIN: Minimum time value (00:00:00).
26
+ """
27
+
28
+ import datetime
29
+ import math
30
+ import time as _time
31
+ from functools import lru_cache
32
+
33
+ import pytz
34
+
35
+ from .py3 import string_types
36
+
37
+ # from numba import jit
38
+
39
+ # Time difference for 0
40
+ ZERO = datetime.timedelta(0)
41
+ # Use time module's timezone attribute to return local timezone's (without DST) offset seconds from Greenwich (>0 Americas, <=0 most Europe, Asia, Africa)
42
+ # STDOFFSET represents offset when not in DST
43
+ STDOFFSET = datetime.timedelta(seconds=-_time.timezone)
44
+ # time.daylight being 0 means no DST, non-zero means DST
45
+ if _time.daylight:
46
+ # time.altzone returns local DST timezone offset, seconds west of UTC (if one is defined)
47
+ # DSTOFFSET offset during DST
48
+ DSTOFFSET = datetime.timedelta(seconds=-_time.altzone)
49
+ else:
50
+ DSTOFFSET = STDOFFSET
51
+ # DSTDIFF represents difference between DST and non-DST offsets
52
+ DSTDIFF = DSTOFFSET - STDOFFSET
53
+
54
+ # To avoid rounding errors, taking dates to next day
55
+ # Set TIME_MAX to avoid rounding errors causing dates to enter next day
56
+ TIME_MAX = datetime.time(23, 59, 59, 999990)
57
+
58
+ # To avoid rounding errors, taking dates to next day
59
+ # Set TIME_MIN to avoid rounding errors causing dates to enter next day
60
+ TIME_MIN = datetime.time.min
61
+
62
+
63
+ # Get the most recent bar update time point
64
+ def get_last_timeframe_timestamp(timestamp, time_diff):
65
+ """Get previous whole minute timestamp based on current timestamp
66
+ :params timestamp int, calculate from int(time.time())
67
+ :params time_diff int, e.g. 1m timeframe using 60
68
+ :returns timestamp int
69
+ :raises ValueError: if time_diff is <= 0 (would cause infinite loop)
70
+ """
71
+ if time_diff <= 0:
72
+ raise ValueError(f"time_diff must be positive, got {time_diff}")
73
+ return timestamp - (timestamp % time_diff)
74
+
75
+
76
+ def get_string_tz_time(tz="Asia/Singapore", string_format="%Y-%m-%d %H:%M:%S.%f"):
77
+ """generate string timezone datetime in particular timezone
78
+ param: tz (str): timezone in pytz.common_timezones
79
+ param: string_format (str): string format
80
+
81
+ Return: now (String): timestamp
82
+ """
83
+ tz = pytz.timezone(tz)
84
+ now = datetime.datetime.now(tz).strftime(string_format)
85
+ return now
86
+
87
+
88
+ def timestamp2datetime(timestamp):
89
+ """Convert timestamp to datetime
90
+ param: timestamp timestamp
91
+ param: string_format (str): string format
92
+ Return: formatted_time (Str): timestamp
93
+ """
94
+ # Convert timestamp to datetime object
95
+ dt_object = datetime.datetime.fromtimestamp(timestamp)
96
+ return dt_object
97
+
98
+
99
+ def timestamp2datestr(timestamp):
100
+ """Convert timestamp to string time
101
+ param: timestamp timestamp
102
+ param: string_format (str): string format
103
+ Return: formatted_time (Str): timestamp
104
+ """
105
+ # Convert timestamp to datetime object
106
+ dt_object = datetime.datetime.fromtimestamp(timestamp)
107
+ # Format datetime object as string
108
+ formatted_time = dt_object.strftime("%Y-%m-%d %H:%M:%S.%f")
109
+ return formatted_time
110
+
111
+
112
+ def datetime2timestamp(time_date, string_format="%Y-%m-%d %H:%M:%S.%f"):
113
+ """Convert datetime to timestamp
114
+ param: datetime_string (str): timezone in pytz.common_timezones
115
+ param: string_format (str): string format
116
+ Return: timestamp
117
+ """
118
+ # Format datetime object as timestamp
119
+ timestamp = time_date.timestamp()
120
+ return timestamp
121
+
122
+
123
+ def datestr2timestamp(
124
+ datetime_string="2023-06-01 09:30:00.0", string_format="%Y-%m-%d %H:%M:%S.%f"
125
+ ):
126
+ """Convert datetime to timestamp
127
+ param: datetime_string (str): timezone in pytz.common_timezones
128
+ param: string_format (str): string format
129
+ Return: timestamp
130
+ """
131
+ # Convert timestamp to datetime object
132
+ time_date = datetime.datetime.strptime(datetime_string, string_format)
133
+ # Format datetime object as timestamp
134
+ timestamp = time_date.timestamp()
135
+ return timestamp
136
+
137
+
138
+ def str2datetime(datetime_string="2023-06-01 09:30:00.0", string_format="%Y-%m-%d %H:%M:%S.%f"):
139
+ """Convert string format time to datetime
140
+ param: datetime_string (str): timezone in pytz.common_timezones
141
+ param: string_format (str): string format
142
+ Return: datetime
143
+ """
144
+ return datetime.datetime.strptime(datetime_string, string_format)
145
+
146
+
147
+ def datetime2str(datetime_obj, string_format="%Y-%m-%d %H:%M:%S.%f"):
148
+ """Convert datetime to string format time
149
+ param: datetime_obj (datetime): timezone in pytz.common_timezones
150
+ param: string_format (str): string format
151
+ Return: datetime_str
152
+ """
153
+ return datetime_obj.strftime(string_format)
154
+
155
+
156
+ def tzparse(tz):
157
+ """Parse a timezone specification into a tzinfo object.
158
+
159
+ Args:
160
+ tz: Timezone specification (string, tzinfo object, or None).
161
+
162
+ Returns:
163
+ A tzinfo object. If pytz is available and tz is a string,
164
+ returns the corresponding pytz timezone. Otherwise returns
165
+ a Localizer-wrapped tz object.
166
+ """
167
+ # This function attempts to convert tz
168
+ # If no object has been provided by the user and a timezone can be
169
+ # found via contractdtails, then try to get it from pytz, which may or
170
+ # may not be available.
171
+ tzstr = isinstance(tz, string_types)
172
+ if tz is None or not tzstr:
173
+ return Localizer(tz)
174
+
175
+ try:
176
+ import pytz # keep the import very local
177
+ except ImportError:
178
+ return Localizer(tz) # nothing can be done
179
+
180
+ tzs = tz
181
+ if tzs == "CST": # usual alias
182
+ tzs = "CST6CDT"
183
+
184
+ try:
185
+ tz = pytz.timezone(tzs)
186
+ except pytz.UnknownTimeZoneError:
187
+ return None # unknown timezone, nothing can be done
188
+
189
+ return tz
190
+
191
+
192
+ def Localizer(tz):
193
+ """Add a localize method to a timezone object.
194
+
195
+ This function adds a localize method to tz objects that don't
196
+ have one, allowing consistent timezone localization across
197
+ different timezone implementations.
198
+
199
+ Args:
200
+ tz: Timezone object to add localize method to.
201
+
202
+ Returns:
203
+ The same timezone object with a localize method added.
204
+ """
205
+ # This function adds a localize method to tz, this localize method adds timezone info to dt
206
+ # tzparse and Localizer are mainly for handling different timezones during live trading
207
+ import types
208
+
209
+ def localize(self, dt):
210
+ return dt.replace(tzinfo=self)
211
+
212
+ if tz is not None and not hasattr(tz, "localize"):
213
+ # patch the tz instance with a bound method
214
+ tz.localize = types.MethodType(localize, tz)
215
+
216
+ return tz
217
+
218
+
219
+ # A UTC class, same as the one in the Python Docs
220
+ class _UTC(datetime.tzinfo):
221
+ """UTC timezone implementation.
222
+
223
+ A simple UTC timezone class that implements the tzinfo interface
224
+ with zero offset (no DST).
225
+ """
226
+
227
+ # UTC class
228
+ def utcoffset(self, dt):
229
+ """Return UTC offset (always zero)."""
230
+ return ZERO
231
+
232
+ def tzname(self, dt):
233
+ """Return timezone name (UTC)."""
234
+ return "UTC"
235
+
236
+ def dst(self, dt):
237
+ """Return DST offset (always zero - UTC has no DST)."""
238
+ return ZERO
239
+
240
+ def localize(self, dt):
241
+ """Localize a naive datetime to UTC.
242
+
243
+ Args:
244
+ dt: Naive datetime to localize.
245
+
246
+ Returns:
247
+ Datetime with UTC timezone info.
248
+ """
249
+ return dt.replace(tzinfo=self)
250
+
251
+
252
+ class _LocalTimezone(datetime.tzinfo):
253
+ """Local timezone with DST support.
254
+
255
+ Implements the local system timezone with automatic DST
256
+ (daylight saving time) calculation.
257
+ """
258
+
259
+ # Timezone offset
260
+ def utcoffset(self, dt):
261
+ """Return the UTC offset for this timezone.
262
+
263
+ Args:
264
+ dt: Datetime to calculate offset for.
265
+
266
+ Returns:
267
+ Timedelta offset from UTC (includes DST if applicable).
268
+ """
269
+ if self._isdst(dt):
270
+ return DSTOFFSET
271
+ return STDOFFSET
272
+
273
+ # DST offset, offset is 0 when not in DST
274
+ def dst(self, dt):
275
+ """Return the DST offset.
276
+
277
+ Args:
278
+ dt: Datetime to calculate DST offset for.
279
+
280
+ Returns:
281
+ Timedelta DST adjustment (zero if not in DST).
282
+ """
283
+ if self._isdst(dt):
284
+ return DSTDIFF
285
+ return ZERO
286
+
287
+ # Possibly timezone name
288
+ def tzname(self, dt):
289
+ """Return the timezone name.
290
+
291
+ Args:
292
+ dt: Datetime to get name for.
293
+
294
+ Returns:
295
+ String timezone name (e.g., 'EST' or 'EDT').
296
+ """
297
+ return _time.tzname[self._isdst(dt)]
298
+
299
+ # Determine if current time is DST
300
+ def _isdst(self, dt):
301
+ tt = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.weekday(), 0, 0)
302
+ try:
303
+ stamp = _time.mktime(tt)
304
+ except (ValueError, OverflowError):
305
+ return False # Too far in the future, not relevant
306
+
307
+ tt = _time.localtime(stamp)
308
+ return tt.tm_isdst > 0
309
+
310
+ # Add timezone info to dt
311
+ def localize(self, dt):
312
+ """Localize a naive datetime to this timezone.
313
+
314
+ Args:
315
+ dt: Naive datetime to localize.
316
+
317
+ Returns:
318
+ Datetime with local timezone info.
319
+ """
320
+ return dt.replace(tzinfo=self)
321
+
322
+
323
+ UTC = _UTC()
324
+ TZLocal = _LocalTimezone()
325
+
326
+ HOURS_PER_DAY = 24.0 # 24 hours in a day
327
+ MINUTES_PER_HOUR = 60.0 # 60 minutes in 1 hour
328
+ SECONDS_PER_MINUTE = 60.0 # 60 seconds in 1 minute
329
+ MUSECONDS_PER_SECOND = 1e6 # How many microseconds in 1 second
330
+ MINUTES_PER_DAY = MINUTES_PER_HOUR * HOURS_PER_DAY # How many minutes in 1 day
331
+ SECONDS_PER_DAY = SECONDS_PER_MINUTE * MINUTES_PER_DAY # How many seconds in 1 day
332
+ MUSECONDS_PER_DAY = MUSECONDS_PER_SECOND * SECONDS_PER_DAY # How many microseconds in 1 day
333
+
334
+
335
+ # The following four functions are frequently used, after comments are completed,
336
+ # try using cython to rewrite, see how much speed can be improved
337
+
338
+
339
+ @lru_cache(maxsize=8192)
340
+ def _num2date_cached(x):
341
+ """Cached core computation for num2date (tz=None, naive=True case).
342
+
343
+ PERFORMANCE OPTIMIZATION: Cache common datetime conversions.
344
+ Called 2.2M+ times, caching reduces repeated calculations.
345
+ """
346
+ # CRITICAL FIX: Handle invalid datetime values (0, NaN, negative)
347
+ if x != x or x <= 0: # NaN check or invalid value
348
+ return datetime.datetime(1970, 1, 1)
349
+
350
+ ix = int(x)
351
+ if ix < 1:
352
+ ix = 1
353
+ dt = datetime.datetime.fromordinal(ix)
354
+ remainder = float(x) - ix
355
+ hour, remainder = divmod(HOURS_PER_DAY * remainder, 1)
356
+ minute, remainder = divmod(MINUTES_PER_HOUR * remainder, 1)
357
+ second, remainder = divmod(SECONDS_PER_MINUTE * remainder, 1)
358
+ microsecond = int(MUSECONDS_PER_SECOND * remainder)
359
+
360
+ if microsecond < 10:
361
+ microsecond = 0
362
+
363
+ dt = datetime.datetime(
364
+ dt.year, dt.month, dt.day, int(hour), int(minute), int(second), microsecond
365
+ )
366
+
367
+ if microsecond > 999990:
368
+ dt += datetime.timedelta(microseconds=1e6 - microsecond)
369
+
370
+ return dt
371
+
372
+
373
+ def num2date(x, tz=None, naive=True):
374
+ # Same as matplotlib except if tz is None, a naive datetime object
375
+ # will be returned.
376
+ """
377
+ *x* is a float value that gives the number of days
378
+ (fraction part represents hours, minutes, seconds) since
379
+ 0001-01-01 00:00:00 UTC *plus* *one*.
380
+ The addition of one here is a historical artifact. Also, note
381
+ that the Gregorian calendar is assumed; this is not universal
382
+ practice. For details, see the module docstring.
383
+ Return value is a: class:`datetime` instance in timezone *tz* (default to
384
+ rcparams TZ value).
385
+ If *x* is a sequence, a sequence of: class:`datetime` objects will
386
+ be returned.
387
+ """
388
+ # PERFORMANCE OPTIMIZATION: Fast path for most common case (tz=None, naive=True)
389
+ if tz is None:
390
+ return _num2date_cached(x)
391
+
392
+ # Slow path: handle timezone conversion
393
+ # CRITICAL FIX: Handle invalid datetime values (0, NaN, negative)
394
+ if x != x or x <= 0: # NaN check or invalid value
395
+ return datetime.datetime(1970, 1, 1)
396
+
397
+ ix = int(x)
398
+ if ix < 1:
399
+ ix = 1
400
+ dt = datetime.datetime.fromordinal(ix)
401
+ remainder = float(x) - ix
402
+ hour, remainder = divmod(HOURS_PER_DAY * remainder, 1)
403
+ minute, remainder = divmod(MINUTES_PER_HOUR * remainder, 1)
404
+ second, remainder = divmod(SECONDS_PER_MINUTE * remainder, 1)
405
+ microsecond = int(MUSECONDS_PER_SECOND * remainder)
406
+
407
+ if microsecond < 10:
408
+ microsecond = 0
409
+
410
+ # Compose time with timezone
411
+ dt = datetime.datetime(
412
+ dt.year, dt.month, dt.day, int(hour), int(minute), int(second), microsecond, tzinfo=UTC
413
+ )
414
+ dt = dt.astimezone(tz)
415
+ if naive:
416
+ dt = dt.replace(tzinfo=None)
417
+
418
+ if microsecond > 999990:
419
+ dt += datetime.timedelta(microseconds=1e6 - microsecond)
420
+
421
+ return dt
422
+
423
+
424
+ # Convert number to date
425
+
426
+
427
+ def num2dt(num, tz=None, naive=True):
428
+ """Convert numeric date to date object.
429
+
430
+ Args:
431
+ num: Numeric date value (days since 0001-01-01 UTC + 1).
432
+ tz: Timezone for the result (optional).
433
+ naive: If True, return naive date without timezone info.
434
+
435
+ Returns:
436
+ date: Date object extracted from the datetime.
437
+ """
438
+ return num2date(num, tz=tz, naive=naive).date()
439
+
440
+
441
+ # Convert number to time
442
+
443
+
444
+ def num2time(num, tz=None, naive=True):
445
+ """Convert numeric date to time object.
446
+
447
+ Args:
448
+ num: Numeric date value (days since 0001-01-01 UTC + 1).
449
+ tz: Timezone for the result (optional).
450
+ naive: If True, return naive time without timezone info.
451
+
452
+ Returns:
453
+ time: Time object extracted from the datetime.
454
+ """
455
+ return num2date(num, tz=tz, naive=naive).time()
456
+
457
+
458
+ # Convert datetime to number
459
+
460
+
461
+ def date2num(dt, tz=None):
462
+ """
463
+ Convert: mod:`datetime` to the Gregorian date as UTC float days,
464
+ preserving hours, minutes, seconds and microseconds. Return value
465
+ is a: func:`float`.
466
+ """
467
+ if tz is not None:
468
+ dt = tz.localize(dt)
469
+
470
+ if hasattr(dt, "tzinfo") and dt.tzinfo is not None:
471
+ delta = dt.tzinfo.utcoffset(dt)
472
+ if delta is not None:
473
+ dt -= delta
474
+
475
+ base = float(dt.toordinal())
476
+ if hasattr(dt, "hour"):
477
+ # base += (dt.hour / HOURS_PER_DAY +
478
+ # dt.minute / MINUTES_PER_DAY +
479
+ # dt.second / SECONDS_PER_DAY +
480
+ # dt.microsecond / MUSECONDS_PER_DAY)
481
+ base = math.fsum(
482
+ (
483
+ base,
484
+ dt.hour / HOURS_PER_DAY,
485
+ dt.minute / MINUTES_PER_DAY,
486
+ dt.second / SECONDS_PER_DAY,
487
+ dt.microsecond / MUSECONDS_PER_DAY,
488
+ )
489
+ )
490
+
491
+ return base
492
+
493
+
494
+ # Convert time to number
495
+
496
+
497
+ def time2num(tm):
498
+ """
499
+ Converts the hour/minute/second/microsecond part of tm (datetime.datetime
500
+ or time) to a num
501
+ """
502
+ num = (
503
+ tm.hour / HOURS_PER_DAY
504
+ + tm.minute / MINUTES_PER_DAY
505
+ + tm.second / SECONDS_PER_DAY
506
+ + tm.microsecond / MUSECONDS_PER_DAY
507
+ )
508
+
509
+ return num
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env python
2
+ """Flush File Module - Auto-flushing file wrapper for Windows.
3
+
4
+ This module provides a wrapper for file-like objects that automatically
5
+ flushes after each write. On Windows platforms, it replaces sys.stdout
6
+ and sys.stderr with auto-flushing versions to ensure immediate output.
7
+
8
+ Classes:
9
+ flushfile: Wrapper that auto-flushes after each write.
10
+ StdOutDevNull: Null output device that suppresses stdout.
11
+
12
+ Note:
13
+ This is primarily for Windows compatibility where output buffering
14
+ can cause delayed display of stdout/stderr.
15
+ """
16
+
17
+ import sys
18
+
19
+
20
+ # By literal meaning, this class should flush output during output to make it display immediately, but looking at the usage of this class, it doesn't seem to serve this purpose
21
+ # Only in btrun file is this file imported, import backtrader.utils.flushfile, when imported it will directly check if this system
22
+ # Is win32, if win32 it uses flushfile to create two instances, during initialization uses sys.stdout, sys.stderr these two methods
23
+ # In reality, it doesn't seem to serve any purpose. Similar to the py3 file, it may be for compatibility purposes, but who uses python2 anymore, almost never
24
+ # So the entire framework appears to have quite a few redundant functions and classes
25
+ class flushfile:
26
+ """File wrapper that auto-flushes after each write.
27
+
28
+ This class wraps a file-like object and ensures that each write
29
+ operation is immediately flushed to the underlying file descriptor.
30
+
31
+ Attributes:
32
+ f: The underlying file-like object.
33
+
34
+ Note:
35
+ On Windows, this module automatically wraps sys.stdout and
36
+ sys.stderr with flushfile instances.
37
+ """
38
+
39
+ def __init__(self, f):
40
+ """Initialize the flushfile wrapper.
41
+
42
+ Args:
43
+ f: File-like object to wrap (typically sys.stdout or sys.stderr).
44
+ """
45
+ self.f = f
46
+
47
+ def write(self, x):
48
+ """Write data to the file and immediately flush.
49
+
50
+ Args:
51
+ x: Data to write to the file.
52
+ """
53
+ self.f.write(x)
54
+ self.f.flush()
55
+
56
+ def flush(self):
57
+ """Flush the underlying file buffer."""
58
+ self.f.flush()
59
+
60
+
61
+ if sys.platform == "win32":
62
+ sys.stdout = flushfile(sys.stdout)
63
+ sys.stderr = flushfile(sys.stderr)
64
+
65
+
66
+ # Unused class, by type it should be for output
67
+ class StdOutDevNull:
68
+ """Null output device that suppresses stdout.
69
+
70
+ When active, all writes to stdout are discarded. The original
71
+ stdout can be restored by calling the stop() method.
72
+
73
+ Attributes:
74
+ stdout: The original sys.stdout saved for restoration.
75
+ """
76
+
77
+ def __init__(self):
78
+ """Initialize StdOutDevNull and replace sys.stdout."""
79
+ self.stdout = sys.stdout
80
+ sys.stdout = self
81
+
82
+ def write(self, x):
83
+ """Discard written data instead of outputting.
84
+
85
+ Args:
86
+ x: Data to discard.
87
+ """
88
+
89
+ def flush(self):
90
+ """No-op flush method for compatibility."""
91
+
92
+ def stop(self):
93
+ """Restore the original sys.stdout."""
94
+ sys.stdout = self.stdout