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,361 @@
1
+ #!/usr/bin/env python
2
+ """Trading Calendar Module - Market calendar and session handling.
3
+
4
+ This module provides trading calendar functionality for handling market
5
+ sessions, holidays, and trading days. It supports custom calendars
6
+ and pandas market calendar integration.
7
+
8
+ Classes:
9
+ TradingCalendarBase: Base class for trading calendars.
10
+ TradingCalendar: Standard trading calendar implementation.
11
+ PandasMarketCalendar: Wrapper for pandas_market_cal calendars.
12
+
13
+ Constants:
14
+ MONDAY-SUNDAY: Weekday constants.
15
+ WEEKEND: Weekend days (Saturday, Sunday).
16
+ ONEDAY: Timedelta of one day.
17
+
18
+ Example:
19
+ Using a trading calendar:
20
+ >>> cal = bt.TradingCalendar()
21
+ >>> next_day = cal.nextday(datetime.date(2020, 1, 1))
22
+ """
23
+
24
+ from datetime import datetime, time, timedelta
25
+
26
+ from backtrader.utils import UTC
27
+ from backtrader.utils.py3 import string_types
28
+
29
+ from .parameters import ParameterizedBase
30
+
31
+ # All classes that can be imported via "from tradingcal import *"
32
+ __all__ = ["TradingCalendarBase", "TradingCalendar", "PandasMarketCalendar"]
33
+
34
+ # Imprecision in the full time conversion to float would wrap over to next day
35
+ # if microseconds are 999,999 as defined in time.max
36
+ # Maximum time of the day
37
+ _time_max = time(hour=23, minute=59, second=59, microsecond=999990)
38
+
39
+ # Constants for seven days of the week, Monday is 0, Sunday is 6
40
+ MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY = range(7)
41
+ # Determine day of week, no date is 0, Monday is 1, Sunday is 7
42
+ ISONODAY, ISOMONDAY, ISOTUESDAY, ISOWEDNESDAY, ISOTHURSDAY, ISOFRIDAY, ISOSATURDAY, ISOSUNDAY = (
43
+ range(8)
44
+ )
45
+ # Weekend is Saturday and Sunday
46
+ WEEKEND = [SATURDAY, SUNDAY]
47
+ # Whether it is weekend
48
+ ISOWEEKEND = [ISOSATURDAY, ISOSUNDAY]
49
+ # Time difference of one day
50
+ ONEDAY = timedelta(days=1)
51
+
52
+
53
+ # Trading calendar base class, defines specific methods - refactored to not use metaclass
54
+ class TradingCalendarBase(ParameterizedBase):
55
+ """Base class for trading calendars.
56
+
57
+ Provides methods for calculating trading days, session times,
58
+ and determining if a day is the last trading day of a week or month.
59
+
60
+ Methods:
61
+ _nextday(day): Returns next trading day and isocalendar components.
62
+ schedule(day): Returns opening and closing times for a day.
63
+ nextday(day): Returns next trading day.
64
+ last_weekday(day): Returns True if day is last trading day of week.
65
+ last_monthday(day): Returns True if day is last trading day of month.
66
+ """
67
+
68
+ # Return the next trading day after day and calendar composition
69
+ def _nextday(self, day):
70
+ """
71
+ Returns the next trading day (datetime/date instance) after ``day``
72
+ (datetime/date instance) and the isocalendar components
73
+
74
+ The return value is a tuple with two parts: (nextday, (y, w, d))
75
+ """
76
+ raise NotImplementedError
77
+
78
+ # Return opening and closing times of a day
79
+ def schedule(self, day):
80
+ """
81
+ Returns a tuple with the opening and closing times (``datetime.time``)
82
+ for the given ``date`` (``datetime/date`` instance)
83
+ """
84
+ raise NotImplementedError
85
+
86
+ # Return the next trading day after day
87
+ def nextday(self, day):
88
+ """
89
+ Returns the next trading day (datetime/date instance) after ``day``
90
+ (datetime/date instance)
91
+ """
92
+ return self._nextday(day)[0] # 1st ret elem is next day
93
+
94
+ # Return the week number of the next trading day after day
95
+ def nextday_week(self, day):
96
+ """
97
+ Returns the iso week number of the next trading day, given a ``day``
98
+ (datetime/date) instance
99
+ """
100
+ return self._nextday(day)[1][1] # 2 elem is isocal / 0 - y, 1 - wk, 2 - day
101
+
102
+ # Calculate if the current day is the last day of this week
103
+ def last_weekday(self, day):
104
+ """
105
+ Returns ``True`` if the given ``day`` (datetime/date) instance is the
106
+ last trading day of this week
107
+ """
108
+ # Next day must be greater than day.
109
+ # If the week changes are enough for
110
+ # a week change even if the number is smaller (year change)
111
+ return day.isocalendar()[1] != self._nextday(day)[1][1]
112
+
113
+ # Determine if the current day is the last day of this month
114
+ def last_monthday(self, day):
115
+ """
116
+ Returns ``True`` if the given ``day`` (datetime/date) instance is the
117
+ last trading day of this month
118
+ """
119
+ # Next day must be greater than day.
120
+ # If the week changes are enough for
121
+ # a week change even if the number is smaller (year change)
122
+ return day.month != self._nextday(day)[0].month
123
+
124
+ # Determine if the current day is the last day of this year
125
+ def last_yearday(self, day):
126
+ """
127
+ Returns ``True`` if the given ``day`` (datetime/date) instance is the
128
+ last trading day of this month
129
+ """
130
+ # Next day must be greater than day.
131
+ # If the week changes are enough for
132
+ # a week change even if the number is smaller (year change)
133
+ return day.year != self._nextday(day)[0].year
134
+
135
+
136
+ # Trading calendar class - refactored to not use metaclass
137
+ class TradingCalendar(TradingCalendarBase):
138
+ """
139
+ Wrapper of ``pandas_market_calendars`` for a trading calendar. The package
140
+ ``pandas_market_calendar`` must be installed
141
+ # In this class, it seems that pandas_market_calendar is not strictly required
142
+ Params:
143
+
144
+ - ``open`` (default ``time.min``)
145
+
146
+ Regular start of the session
147
+
148
+ # open, trading day start time, default is minimum time
149
+
150
+ - ``close`` (default ``time.max``)
151
+
152
+ Regular end of the session
153
+ # close, trading day end time, default is maximum time
154
+
155
+ - ``holidays`` (default ``[]``)
156
+
157
+ List of non-trading days (``datetime.datetime`` instances)
158
+
159
+ # holidays, holidays, list of datetime times
160
+
161
+ - ``earlydays`` (default ``[]``)
162
+
163
+ List of tuples determining the date and opening/closing times of days
164
+ which do not conform to the regular trading hours when each tuple has
165
+ (``datetime.datetime``, ``datetime.time``, ``datetime.time``)
166
+ # earlydays, trading days with non-standard trading start and end times
167
+
168
+ - ``offdays`` (default ``ISOWEEKEND``)
169
+
170
+ A list of weekdays in ISO format (Monday: 1 -> Sunday: 7) in which the
171
+ market doesn't trade. This is usually Saturday and Sunday and hence the
172
+ default
173
+
174
+ # offdays, non-trading dates from Monday to Sunday, usually Saturday and Sunday
175
+
176
+ """
177
+
178
+ # Parameters
179
+ params: tuple = (
180
+ ("open", time.min),
181
+ ("close", _time_max),
182
+ ("holidays", []), # list of non-trading days (date)
183
+ ("earlydays", []), # list of tuples (date, opentime, closetime)
184
+ ("offdays", ISOWEEKEND), # list of non-trading (isoweekdays)
185
+ )
186
+
187
+ # Initialize, get these dates based on earlydays to speed up searches
188
+ def __init__(self, **kwargs):
189
+ """Initialize the TradingCalendar.
190
+
191
+ Args:
192
+ **kwargs: Keyword arguments for calendar parameters.
193
+ """
194
+ super().__init__(**kwargs)
195
+ self._earlydays = [x[0] for x in self.p.earlydays] # speed up searches
196
+
197
+ # Get the next trading day
198
+ def _nextday(self, day):
199
+ """
200
+ Returns the next trading day (datetime/date instance) after ``day``
201
+ (datetime/date instance) and the isocalendar components
202
+
203
+ The return value is a tuple with two parts: (nextday, (y, w, d))
204
+ """
205
+ # while loop
206
+ while True:
207
+ # Next trading day
208
+ day += ONEDAY
209
+ # Get calendar information of day
210
+ isocal = day.isocalendar()
211
+ # If day is Saturday, Sunday or a holiday, continue loop to get next day
212
+ if isocal[2] in self.p.offdays or day in self.p.holidays:
213
+ continue
214
+ # If day is not Saturday, Sunday or holiday, day is the desired next trading day
215
+ return day, isocal
216
+
217
+ # Get opening and closing times of day
218
+ def schedule(self, day, tz=None):
219
+ """
220
+ Returns the opening and closing times for the given ``day``. If the
221
+ method is called, the assumption is that `day` is an actual trading
222
+ day
223
+
224
+ The return value is a tuple with 2 components: opentime, closetime
225
+ """
226
+ # while loop
227
+ while True:
228
+ # Get date of day
229
+ dt = day.date()
230
+ # Try to get if trading day is in earlydays, if so, get specific opening and closing times
231
+ # If not, opening defaults to current minimum time, closing defaults to maximum time of the day
232
+ try:
233
+ i = self._earlydays.index(dt)
234
+ o, c = self.p.earlydays[i][1:]
235
+ except ValueError: # not found
236
+ o, c = self.p.open, self.p.close
237
+ # Combine closing date and time
238
+ closing = datetime.combine(dt, c)
239
+ # If timezone is not None, convert closing time according to timezone
240
+ if tz is not None:
241
+ closing = tz.localize(closing).astimezone(UTC)
242
+ closing = closing.replace(tzinfo=None)
243
+ # If day is greater than closing time, skip to next trading day and restart loop
244
+ if day > closing: # current time over eos
245
+ day += ONEDAY
246
+ continue
247
+ # Opening date and time
248
+ opening = datetime.combine(dt, o)
249
+ # If timezone is not None, convert closing time according to timezone
250
+ if tz is not None:
251
+ opening = tz.localize(opening).astimezone(UTC)
252
+ opening = opening.replace(tzinfo=None)
253
+
254
+ return opening, closing
255
+
256
+
257
+ class PandasMarketCalendar(TradingCalendarBase):
258
+ """
259
+ Wrapper of ``pandas_market_calendars`` for a trading calendar. The package
260
+ ``pandas_market_calendar`` must be installed
261
+ # pandas_market_calendar must be installed
262
+ Params:
263
+
264
+ - ``calendar`` (default ``None``)
265
+
266
+ The param ``calendar`` accepts the following:
267
+
268
+ - string: the name of one of the calendars supported, for example,
269
+ `NYSE`. The wrapper will attempt to get a calendar instance
270
+
271
+ - Calendar instance: as returned by ``get_calendar('NYSE')``
272
+
273
+ # calendar information, can be string or calendar instance
274
+
275
+ - ``cachesize`` (default ``365``)
276
+
277
+ Number of days to cache in advance for lookup
278
+
279
+ # How many dates to cache in advance for convenient lookup
280
+
281
+ See also:
282
+
283
+ - https://github.com/rsheftel/pandas_market_calendars
284
+
285
+ - http://pandas-market-calendars.readthedocs.io/
286
+
287
+ """
288
+
289
+ # Parameters
290
+ params = (
291
+ ("calendar", None), # A pandas_market_calendars instance or exch name
292
+ ("cachesize", 365), # Number of days to cache in advance
293
+ )
294
+
295
+ # Initialize
296
+ def __init__(self, **kwargs):
297
+ """Initialize the PandasMarketCalendar.
298
+
299
+ Args:
300
+ **kwargs: Keyword arguments for calendar parameters.
301
+ """
302
+ super().__init__(**kwargs)
303
+ self._calendar = self.p.calendar
304
+ # If self._calendar is a string, use get_calendar to convert to calendar instance
305
+ if isinstance(self._calendar, string_types): # use passed mkt name
306
+ import pandas_market_calendars as mcal
307
+
308
+ self._calendar = mcal.get_calendar(self._calendar)
309
+ # Create self.dcache, self.idcache, self.csize
310
+ import pandas as pd # guaranteed because of pandas_market_calendars
311
+
312
+ self.dcache = pd.DatetimeIndex([0.0])
313
+ self.idcache = pd.DataFrame(index=pd.DatetimeIndex([0.0]))
314
+ self.csize = timedelta(days=self.p.cachesize)
315
+
316
+ # Get the next trading day
317
+ def _nextday(self, day):
318
+ """
319
+ Returns the next trading day (datetime/date instance) after ``day``
320
+ (datetime/date instance) and the isocalendar components
321
+
322
+ The return value is a tuple with two parts: (nextday, (y, w, d))
323
+ """
324
+ day += ONEDAY
325
+ while True:
326
+ # Get the index where day is located
327
+ i = self.dcache.searchsorted(day)
328
+ # If index equals self.dcache length, dates have been used up and need to be updated
329
+ if i == len(self.dcache):
330
+ # keep a cache of 1 year to speed up searching
331
+ self.dcache = self._calendar.valid_days(day, day + self.csize)
332
+ continue
333
+ # If can get the index where day is located from self.dcache, then convert to time
334
+ d = self.dcache[i].to_pydatetime()
335
+ return d, d.isocalendar()
336
+
337
+ # Get specific opening and closing times
338
+ def schedule(self, day, tz=None):
339
+ """
340
+ Returns the opening and closing times for the given ``day``. If the
341
+ method is called, the assumption is that `day` is an actual trading
342
+ day
343
+
344
+ The return value is a tuple with 2 components: opentime, closetime
345
+ """
346
+ while True:
347
+ # Get the index where trading day is located, then determine if calendar data needs to be updated
348
+ i = self.idcache.index.searchsorted(day.date())
349
+ if i == len(self.idcache):
350
+ # keep a cache of 1 year to speed up searching
351
+ self.idcache = self._calendar.schedule(day, day + self.csize)
352
+ continue
353
+ # Convert calendar information to generate tuple of opening and closing times
354
+ st = (x.tz_localize(None) for x in self.idcache.iloc[i, 0:2])
355
+ opening, closing = st # Get utc naive times
356
+ # If current day is already greater than closing time, skip to next day, update latest opening and closing times, then return
357
+ if day > closing: # passed time is over the sessionend
358
+ day += ONEDAY # wrap over to next day
359
+ continue
360
+
361
+ return opening.to_pydatetime(), closing.to_pydatetime()
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env python
2
+ """Utilities Module - Common utility functions and classes.
3
+
4
+ This module provides common utilities used throughout the backtrader framework
5
+ including data structures, date/time conversions, and helper functions.
6
+
7
+ Exports:
8
+ AutoDict, AutoDictList, AutoOrderedDict, DotDict: Dictionary utilities.
9
+ OrderedDict: Ordered dictionary from collections.
10
+ num2date, date2num, num2dt, num2time, time2num: Date/time conversions.
11
+ tzparse, Localizer, TIME_MAX: Timezone utilities.
12
+
13
+ Example:
14
+ >>> from backtrader.utils import OrderedDict, date2num
15
+ >>> od = OrderedDict()
16
+ >>> od['key'] = 'value'
17
+ """
18
+
19
+ from collections import OrderedDict as OrderedDict
20
+
21
+ from .autodict import AutoDict as AutoDict
22
+ from .autodict import AutoDictList as AutoDictList
23
+ from .autodict import AutoOrderedDict as AutoOrderedDict
24
+ from .autodict import DotDict as DotDict
25
+ from .dateintern import TIME_MAX as TIME_MAX
26
+ from .dateintern import UTC as UTC
27
+ from .dateintern import Localizer as Localizer
28
+ from .dateintern import TZLocal as TZLocal
29
+ from .dateintern import date2num as date2num
30
+ from .dateintern import num2date as num2date
31
+ from .dateintern import num2dt as num2dt
32
+ from .dateintern import num2time as num2time
33
+ from .dateintern import time2num as time2num
34
+ from .dateintern import tzparse as tzparse
35
+ from .get_metrics import STANDARD_METRIC_FIELDS as STANDARD_METRIC_FIELDS
36
+ from .get_metrics import extract_backtest_metrics as extract_backtest_metrics
37
+ from .get_metrics import get_backtest_metrics as get_backtest_metrics
38
+ from .get_metrics import write_metrics as write_metrics
39
+ from .log_message import configure_logging as configure_logging
40
+ from .log_message import get_logger as get_logger
41
+ from .log_message import reset_logging as reset_logging
42
+ from .log_message import set_level as set_level
43
+
44
+ __all__ = [
45
+ "OrderedDict",
46
+ "AutoDict",
47
+ "AutoDictList",
48
+ "AutoOrderedDict",
49
+ "DotDict",
50
+ "TIME_MAX",
51
+ "UTC",
52
+ "Localizer",
53
+ "TZLocal",
54
+ "date2num",
55
+ "num2date",
56
+ "num2dt",
57
+ "num2time",
58
+ "time2num",
59
+ "tzparse",
60
+ "STANDARD_METRIC_FIELDS",
61
+ "get_backtest_metrics",
62
+ "extract_backtest_metrics",
63
+ "write_metrics",
64
+ "get_logger",
65
+ "configure_logging",
66
+ "set_level",
67
+ "reset_logging",
68
+ ]
@@ -0,0 +1,251 @@
1
+ #!/usr/bin/env python
2
+ """AutoDict Module - Enhanced dictionary classes.
3
+
4
+ This module provides dictionary subclasses with automatic key creation,
5
+ dot notation access, and ordered dict support.
6
+
7
+ Classes:
8
+ AutoDict: Dict with automatic nested dict creation.
9
+ AutoOrderedDict: OrderedDict with automatic nested dict creation.
10
+ DotDict: Dict with attribute-style access (obj.key).
11
+ AutoDictList: Dict with automatic list creation for missing keys.
12
+
13
+ Example:
14
+ >>> d = AutoOrderedDict()
15
+ >>> d['a']['b']['c'] = 1 # Automatically creates nested dicts
16
+ >>> print(d['a']['b']['c'])
17
+ 1
18
+ """
19
+
20
+ from collections import OrderedDict, defaultdict
21
+
22
+ from ..utils.log_message import get_logger
23
+ from .py3 import values as py3lvalues
24
+
25
+ logger = get_logger(__name__)
26
+
27
+
28
+ def Tree():
29
+ """Create a recursive defaultdict structure.
30
+
31
+ Returns a defaultdict that automatically creates nested defaultdicts
32
+ for any missing key, allowing for infinite nesting.
33
+
34
+ Returns:
35
+ defaultdict: A recursive defaultdict structure.
36
+ """
37
+ return defaultdict(Tree)
38
+
39
+
40
+ class AutoDictList(dict):
41
+ """Dictionary that creates an empty list for missing keys.
42
+
43
+ When accessing a key that doesn't exist, automatically creates
44
+ a new empty list for that key.
45
+
46
+ Example:
47
+ >>> d = AutoDictList()
48
+ >>> d['key'].append('value')
49
+ >>> print(d['key'])
50
+ ['value']
51
+ """
52
+
53
+ # Inherits dict, when accessing missing key, will automatically generate a key value, corresponding value is an empty list
54
+ # This newly created class is only used in collections.defaultdict(AutoDictList) line
55
+ def __missing__(self, key):
56
+ value = self[key] = []
57
+ return value
58
+
59
+
60
+ class DotDict(dict):
61
+ """Dictionary with attribute-style access.
62
+
63
+ Allows accessing dictionary values as attributes using dot notation.
64
+ If an attribute is not found in the usual places, the dict itself
65
+ is checked.
66
+
67
+ Example:
68
+ >>> d = DotDict()
69
+ >>> d['key'] = 'value'
70
+ >>> print(d.key)
71
+ 'value'
72
+ """
73
+
74
+ # If the attribute is not found in the usual places, try the dict itself
75
+ # This class is only used in the following line, when accessing attributes, if attribute doesn't exist, __getattr__ will be called
76
+ # _obj.dnames = DotDict([(d._name, d) for d in _obj.datas if getattr(d, '_name', '')])
77
+ def __getattr__(self, key):
78
+ if key.startswith("__"):
79
+ # return super().__getattr__(key)
80
+ raise AttributeError(key)
81
+ return self[key]
82
+
83
+
84
+ # This function has slightly wider usage, mainly called in tradeanalyzer and ibstore, is an extension of Python dict
85
+ # Compared to Python built-in dict, added an attribute: _closed, added functions _close, _open, __missing__, __getattr__, overrode __setattr__
86
+ class AutoDict(dict):
87
+ """Dictionary with automatic nested dict creation and closeable state.
88
+
89
+ Extends dict with:
90
+ - Automatic nested dict creation for missing keys
91
+ - Closeable state (_closed) to prevent further auto-creation
92
+ - Attribute-style access
93
+
94
+ Attributes:
95
+ _closed: If True, __missing__ raises KeyError instead of creating nested dicts.
96
+
97
+ Methods:
98
+ _close(): Set _closed to True to prevent auto-creation.
99
+ _open(): Set _closed to False to enable auto-creation.
100
+ """
101
+
102
+ # Initialize default attribute _closed to False
103
+ _closed = False
104
+
105
+ # _close method
106
+ def _close(self):
107
+ # Change class attribute to True
108
+ self._closed = True
109
+ # For values in dict, if they are instances of AutoDict or AutoOrderedDict, call _close method to set attribute _closed to True
110
+ for key, val in self.items():
111
+ if isinstance(val, (AutoDict, AutoOrderedDict)):
112
+ val._close()
113
+
114
+ # _open method, set _closed attribute to False
115
+ def _open(self):
116
+ self._closed = False
117
+ for key, val in self.items():
118
+ if isinstance(val, (AutoDict, AutoOrderedDict)):
119
+ val._open()
120
+
121
+ # __missing__ method handles case when key doesn't exist, if _closed, return KeyError, if not, create an AutoDict() instance for this key
122
+ def __missing__(self, key):
123
+ if self._closed:
124
+ raise KeyError(key)
125
+
126
+ value = self[key] = AutoDict()
127
+ return value
128
+
129
+ def __getattr__(self, key):
130
+ if key.startswith("_"):
131
+ raise AttributeError(key)
132
+ try:
133
+ return self[key]
134
+ except KeyError:
135
+ logger.debug("autodict: key not found, re-raising KeyError")
136
+ raise AttributeError(key) from None
137
+
138
+ def __setattr__(self, key, value):
139
+ if key.startswith("_"):
140
+ self.__dict__[key] = value
141
+ return
142
+ self[key] = value
143
+
144
+
145
+ # Created a new ordered dict, added some functions, similar to AutoDict
146
+ class AutoOrderedDict(OrderedDict):
147
+ """OrderedDict with automatic nested dict creation and closeable state.
148
+
149
+ Combines OrderedDict's insertion ordering with AutoDict's automatic
150
+ nested dict creation and closeable state.
151
+
152
+ Attributes:
153
+ _closed: If True, __missing__ raises KeyError instead of creating nested dicts.
154
+
155
+ Methods:
156
+ _close(): Set _closed to True to prevent auto-creation.
157
+ _open(): Set _closed to False to enable auto-creation.
158
+
159
+ Example:
160
+ >>> d = AutoOrderedDict()
161
+ >>> d['a']['b'] = 1 # Automatically creates nested dicts
162
+ >>> d._close() # Prevent further auto-creation
163
+ """
164
+
165
+ _closed = False
166
+
167
+ def _close(self):
168
+ self._closed = True
169
+ for key, val in self.items():
170
+ if isinstance(val, (AutoDict, AutoOrderedDict)):
171
+ val._close()
172
+
173
+ def _open(self):
174
+ self._closed = False
175
+ for key, val in self.items():
176
+ if isinstance(val, (AutoDict, AutoOrderedDict)):
177
+ val._open()
178
+
179
+ def __missing__(self, key):
180
+ if self._closed:
181
+ raise KeyError(key)
182
+
183
+ # value = self[key] = type(self)()
184
+ value = self[key] = AutoOrderedDict()
185
+ return value
186
+
187
+ # __getattr__ and __setattr__ functions are much more normal compared to AutoDict
188
+ def __getattr__(self, key):
189
+ if key.startswith("_"):
190
+ raise AttributeError(key)
191
+ try:
192
+ return self[key]
193
+ except KeyError:
194
+ logger.debug("autodict: attribute miss, re-raising KeyError")
195
+ raise AttributeError(key) from None
196
+
197
+ def __setattr__(self, key, value):
198
+ if key.startswith("_"):
199
+ self.__dict__[key] = value
200
+ return
201
+
202
+ self[key] = value
203
+
204
+ # Defined math operations, not sure what they mean for now, but it seems only __iadd__ and __isub__ are normal
205
+ # Define math operations
206
+ def __iadd__(self, other):
207
+ if not isinstance(other, type(self)):
208
+ return type(other)() + other
209
+
210
+ return self + other
211
+
212
+ def __isub__(self, other):
213
+ if not isinstance(other, type(self)):
214
+ return type(other)() - other
215
+
216
+ return self - other
217
+
218
+ def __imul__(self, other):
219
+ if not isinstance(other, type(self)):
220
+ return type(other)() * other
221
+
222
+ return self * other
223
+
224
+ def __idiv__(self, other):
225
+ if not isinstance(other, type(self)):
226
+ return type(other)() // other
227
+
228
+ return self // other
229
+
230
+ def __itruediv__(self, other):
231
+ if not isinstance(other, type(self)):
232
+ return type(other)() / other
233
+
234
+ return self / other
235
+
236
+ def lvalues(self):
237
+ """Return dictionary values as a list.
238
+
239
+ Provides Python 2/3 compatible list of values.
240
+
241
+ Returns:
242
+ list: List of all values in the dictionary.
243
+ """
244
+ return py3lvalues(self)
245
+
246
+
247
+ if __name__ == "__main__":
248
+ aod = AutoOrderedDict()
249
+ print("aod", dir(aod))
250
+ od: dict = OrderedDict()
251
+ print("od", dir(od))