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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. back_trader_python-1.4.0.dist-info/METADATA +1491 -0
  2. back_trader_python-1.4.0.dist-info/RECORD +465 -0
  3. back_trader_python-1.4.0.dist-info/WHEEL +5 -0
  4. back_trader_python-1.4.0.dist-info/licenses/LICENSE +674 -0
  5. back_trader_python-1.4.0.dist-info/top_level.txt +1 -0
  6. backtrader/__init__.py +148 -0
  7. backtrader/_cerebro/__init__.py +5 -0
  8. backtrader/_cerebro/channel.py +382 -0
  9. backtrader/_cerebro/execution.py +377 -0
  10. backtrader/_cerebro/lifecycle.py +143 -0
  11. backtrader/_cerebro/notifications.py +150 -0
  12. backtrader/_cerebro/presentation.py +230 -0
  13. backtrader/_cerebro/registry.py +593 -0
  14. backtrader/_cerebro/runnext.py +551 -0
  15. backtrader/_cerebro/runonce.py +142 -0
  16. backtrader/analyzer.py +594 -0
  17. backtrader/analyzers/__init__.py +50 -0
  18. backtrader/analyzers/annualreturn.py +226 -0
  19. backtrader/analyzers/calmar.py +165 -0
  20. backtrader/analyzers/drawdown.py +287 -0
  21. backtrader/analyzers/leverage.py +112 -0
  22. backtrader/analyzers/logreturnsrolling.py +190 -0
  23. backtrader/analyzers/periodstats.py +153 -0
  24. backtrader/analyzers/positions.py +119 -0
  25. backtrader/analyzers/pyfolio.py +470 -0
  26. backtrader/analyzers/returns.py +192 -0
  27. backtrader/analyzers/sharpe.py +307 -0
  28. backtrader/analyzers/sharpe_ratio_stats.py +534 -0
  29. backtrader/analyzers/sqn.py +112 -0
  30. backtrader/analyzers/timereturn.py +192 -0
  31. backtrader/analyzers/total_value.py +75 -0
  32. backtrader/analyzers/tradeanalyzer.py +278 -0
  33. backtrader/analyzers/transactions.py +141 -0
  34. backtrader/analyzers/vwr.py +245 -0
  35. backtrader/bokeh/__init__.py +155 -0
  36. backtrader/bokeh/analyzers/__init__.py +13 -0
  37. backtrader/bokeh/analyzers/plot.py +192 -0
  38. backtrader/bokeh/analyzers/recorder.py +181 -0
  39. backtrader/bokeh/app.py +1094 -0
  40. backtrader/bokeh/live/__init__.py +11 -0
  41. backtrader/bokeh/live/client.py +352 -0
  42. backtrader/bokeh/live/datahandler.py +346 -0
  43. backtrader/bokeh/plot_adapter.py +200 -0
  44. backtrader/bokeh/schemes/__init__.py +14 -0
  45. backtrader/bokeh/schemes/blackly.py +76 -0
  46. backtrader/bokeh/schemes/scheme.py +150 -0
  47. backtrader/bokeh/schemes/tradimo.py +82 -0
  48. backtrader/bokeh/tab.py +125 -0
  49. backtrader/bokeh/tabs/__init__.py +30 -0
  50. backtrader/bokeh/tabs/analyzer.py +120 -0
  51. backtrader/bokeh/tabs/config.py +154 -0
  52. backtrader/bokeh/tabs/live.py +109 -0
  53. backtrader/bokeh/tabs/log.py +185 -0
  54. backtrader/bokeh/tabs/metadata.py +182 -0
  55. backtrader/bokeh/tabs/performance.py +359 -0
  56. backtrader/bokeh/tabs/source.py +70 -0
  57. backtrader/bokeh/utils/__init__.py +8 -0
  58. backtrader/bokeh/utils/helpers.py +167 -0
  59. backtrader/bokeh/webapp.py +164 -0
  60. backtrader/broker.py +478 -0
  61. backtrader/brokers/__init__.py +36 -0
  62. backtrader/brokers/bbroker.py +2576 -0
  63. backtrader/brokers/btapibroker.py +8227 -0
  64. backtrader/brokers/hft/__init__.py +89 -0
  65. backtrader/brokers/hft/binance_bbo.py +625 -0
  66. backtrader/brokers/hft/binance_bbo_compare.py +1398 -0
  67. backtrader/brokers/hft/examples.py +1228 -0
  68. backtrader/brokers/hft/exchange.py +380 -0
  69. backtrader/brokers/hft/latency.py +309 -0
  70. backtrader/brokers/hft/matching_core.py +572 -0
  71. backtrader/brokers/hft/queue.py +238 -0
  72. backtrader/brokers/hft/recorder.py +88 -0
  73. backtrader/brokers/hft/state.py +138 -0
  74. backtrader/brokers/impact_models.py +118 -0
  75. backtrader/brokers/mixbroker.py +895 -0
  76. backtrader/brokers/tickbroker.py +1991 -0
  77. backtrader/btrun/__init__.py +12 -0
  78. backtrader/btrun/btrun.py +1218 -0
  79. backtrader/cerebro.py +828 -0
  80. backtrader/channel.py +682 -0
  81. backtrader/channels/__init__.py +23 -0
  82. backtrader/channels/bridge.py +186 -0
  83. backtrader/channels/funding.py +248 -0
  84. backtrader/channels/live_queue.py +216 -0
  85. backtrader/channels/live_validator.py +294 -0
  86. backtrader/channels/orderbook.py +257 -0
  87. backtrader/channels/tick.py +202 -0
  88. backtrader/comminfo.py +665 -0
  89. backtrader/commissions/__init__.py +106 -0
  90. backtrader/commissions/ctpoption.py +993 -0
  91. backtrader/configs/account_config_example.yaml +8 -0
  92. backtrader/dataseries.py +379 -0
  93. backtrader/errors.py +106 -0
  94. backtrader/events.py +980 -0
  95. backtrader/feed.py +1523 -0
  96. backtrader/feeds/__init__.py +75 -0
  97. backtrader/feeds/barrier.py +2006 -0
  98. backtrader/feeds/blaze.py +118 -0
  99. backtrader/feeds/btapifeed.py +1538 -0
  100. backtrader/feeds/btcsv.py +203 -0
  101. backtrader/feeds/chainer.py +114 -0
  102. backtrader/feeds/cryptohftdata.py +164 -0
  103. backtrader/feeds/csvgeneric.py +1205 -0
  104. backtrader/feeds/ctpcohort.py +1051 -0
  105. backtrader/feeds/influxfeed.py +158 -0
  106. backtrader/feeds/livefeed.py +71 -0
  107. backtrader/feeds/mixed_channel.py +108 -0
  108. backtrader/feeds/mt4csv.py +42 -0
  109. backtrader/feeds/pandafeed.py +381 -0
  110. backtrader/feeds/quandl.py +256 -0
  111. backtrader/feeds/rollover.py +229 -0
  112. backtrader/feeds/sierrachart.py +30 -0
  113. backtrader/feeds/vchart.py +162 -0
  114. backtrader/feeds/vchartcsv.py +84 -0
  115. backtrader/feeds/vchartfile.py +153 -0
  116. backtrader/feeds/yahoo.py +399 -0
  117. backtrader/fillers.py +148 -0
  118. backtrader/filters/__init__.py +34 -0
  119. backtrader/filters/bsplitter.py +127 -0
  120. backtrader/filters/calendardays.py +121 -0
  121. backtrader/filters/datafiller.py +192 -0
  122. backtrader/filters/datafilter.py +74 -0
  123. backtrader/filters/daysteps.py +96 -0
  124. backtrader/filters/heikinashi.py +63 -0
  125. backtrader/filters/renko.py +164 -0
  126. backtrader/filters/session.py +289 -0
  127. backtrader/flt.py +80 -0
  128. backtrader/functions.py +960 -0
  129. backtrader/indicator.py +449 -0
  130. backtrader/indicators/__init__.py +148 -0
  131. backtrader/indicators/accdecoscillator.py +110 -0
  132. backtrader/indicators/aroon.py +300 -0
  133. backtrader/indicators/atr.py +315 -0
  134. backtrader/indicators/awesomeoscillator.py +122 -0
  135. backtrader/indicators/basicops.py +834 -0
  136. backtrader/indicators/bollinger.py +223 -0
  137. backtrader/indicators/cci.py +89 -0
  138. backtrader/indicators/channels_ext.py +83 -0
  139. backtrader/indicators/contrib/__init__.py +228 -0
  140. backtrader/indicators/contrib/absolutely_no_lag_lwma.py +28 -0
  141. backtrader/indicators/contrib/absolutely_no_lag_lwma_color.py +44 -0
  142. backtrader/indicators/contrib/accumulation_distribution_line.py +92 -0
  143. backtrader/indicators/contrib/adx_cross_hull_style_indicator.py +249 -0
  144. backtrader/indicators/contrib/adxdmi.py +34 -0
  145. backtrader/indicators/contrib/ai_acceleration_deceleration_oscillator.py +34 -0
  146. backtrader/indicators/contrib/altr_trend_signal_v22.py +85 -0
  147. backtrader/indicators/contrib/anchored_momentum_line.py +115 -0
  148. backtrader/indicators/contrib/any_range_cld_tail_indicator.py +82 -0
  149. backtrader/indicators/contrib/aroon_horn_sign_indicator.py +96 -0
  150. backtrader/indicators/contrib/aroon_oscillator_sign_alert.py +50 -0
  151. backtrader/indicators/contrib/arrows_curves_indicator.py +112 -0
  152. backtrader/indicators/contrib/as_ctrend_indicator.py +143 -0
  153. backtrader/indicators/contrib/asimmetric_stoch_nr_indicator.py +187 -0
  154. backtrader/indicators/contrib/atr_normalize_histogram.py +118 -0
  155. backtrader/indicators/contrib/average_change_candle.py +165 -0
  156. backtrader/indicators/contrib/bb_squeeze_indicator.py +60 -0
  157. backtrader/indicators/contrib/bezier_st_dev_indicator.py +135 -0
  158. backtrader/indicators/contrib/binary_wave_indicator.py +233 -0
  159. backtrader/indicators/contrib/blau_c_momentum_indicator.py +123 -0
  160. backtrader/indicators/contrib/blau_cmi_indicator.py +141 -0
  161. backtrader/indicators/contrib/blau_csi.py +76 -0
  162. backtrader/indicators/contrib/blau_ergodic.py +53 -0
  163. backtrader/indicators/contrib/blau_t_stoch_i.py +72 -0
  164. backtrader/indicators/contrib/blau_ts_stochastic.py +85 -0
  165. backtrader/indicators/contrib/blau_tvi.py +55 -0
  166. backtrader/indicators/contrib/brain_trend2_indicator.py +128 -0
  167. backtrader/indicators/contrib/brain_trend_signal_proxy.py +47 -0
  168. backtrader/indicators/contrib/brake_parb_indicator.py +85 -0
  169. backtrader/indicators/contrib/breakout_bars_trend_v2.py +121 -0
  170. backtrader/indicators/contrib/bsi_indicator.py +87 -0
  171. backtrader/indicators/contrib/bulls_bears_eyes.py +67 -0
  172. backtrader/indicators/contrib/bulls_power.py +56 -0
  173. backtrader/indicators/contrib/bw_wise_man1_signal.py +102 -0
  174. backtrader/indicators/contrib/bykov_trend_indicator.py +85 -0
  175. backtrader/indicators/contrib/candle_stop_color.py +46 -0
  176. backtrader/indicators/contrib/candles_x_smoothed_indicator.py +69 -0
  177. backtrader/indicators/contrib/candlesticks_bw.py +45 -0
  178. backtrader/indicators/contrib/caudate_x_period_candle_color.py +56 -0
  179. backtrader/indicators/contrib/cci_histogram_indicator.py +53 -0
  180. backtrader/indicators/contrib/cci_woodies_indicator.py +80 -0
  181. backtrader/indicators/contrib/center_of_gravity_candle_indicator.py +83 -0
  182. backtrader/indicators/contrib/center_of_gravity_indicator.py +70 -0
  183. backtrader/indicators/contrib/cg_oscillator.py +40 -0
  184. backtrader/indicators/contrib/close_line_cci.py +38 -0
  185. backtrader/indicators/contrib/close_price_fractals.py +47 -0
  186. backtrader/indicators/contrib/color3rd_gen_xma_indicator.py +122 -0
  187. backtrader/indicators/contrib/color_bb_candles_indicator.py +108 -0
  188. backtrader/indicators/contrib/color_coppock_indicator.py +157 -0
  189. backtrader/indicators/contrib/color_hma.py +71 -0
  190. backtrader/indicators/contrib/color_j_variation_indicator.py +53 -0
  191. backtrader/indicators/contrib/color_metro_de_marker_indicator.py +78 -0
  192. backtrader/indicators/contrib/color_metro_stochastic_indicator.py +93 -0
  193. backtrader/indicators/contrib/color_metro_wpr_indicator.py +85 -0
  194. backtrader/indicators/contrib/color_schaff_de_marker_trend_cycle.py +92 -0
  195. backtrader/indicators/contrib/color_schaff_trend_cycle_indicator.py +203 -0
  196. backtrader/indicators/contrib/color_step_xccx_indicator.py +193 -0
  197. backtrader/indicators/contrib/color_x2_ma.py +49 -0
  198. backtrader/indicators/contrib/color_x_derivative.py +63 -0
  199. backtrader/indicators/contrib/color_zerolag_de_marker.py +84 -0
  200. backtrader/indicators/contrib/corrected_average_indicator.py +127 -0
  201. backtrader/indicators/contrib/darvas_boxes_system.py +73 -0
  202. backtrader/indicators/contrib/dema_range_channel_color.py +42 -0
  203. backtrader/indicators/contrib/derivative_indicator.py +95 -0
  204. backtrader/indicators/contrib/digital_ft01_indicator.py +112 -0
  205. backtrader/indicators/contrib/digital_macd.py +200 -0
  206. backtrader/indicators/contrib/donchian_channels_system.py +45 -0
  207. backtrader/indicators/contrib/dots_indicator.py +93 -0
  208. backtrader/indicators/contrib/ef_distance_indicator.py +82 -0
  209. backtrader/indicators/contrib/ema_rsi_va.py +80 -0
  210. backtrader/indicators/contrib/envelopes_jp_alonso.py +32 -0
  211. backtrader/indicators/contrib/f2a_ao_indicator.py +120 -0
  212. backtrader/indicators/contrib/fatl_filter.py +179 -0
  213. backtrader/indicators/contrib/fibo_candles_indicator.py +78 -0
  214. backtrader/indicators/contrib/fine_tuning_ma.py +100 -0
  215. backtrader/indicators/contrib/fisher_org_v1.py +102 -0
  216. backtrader/indicators/contrib/fisher_org_v1_sign.py +118 -0
  217. backtrader/indicators/contrib/force_index_ema.py +96 -0
  218. backtrader/indicators/contrib/force_index_ema_2.py +27 -0
  219. backtrader/indicators/contrib/forecast_oscilator.py +145 -0
  220. backtrader/indicators/contrib/fractal_amambk.py +81 -0
  221. backtrader/indicators/contrib/frama_series.py +84 -0
  222. backtrader/indicators/contrib/frasm_av2_indicator.py +104 -0
  223. backtrader/indicators/contrib/go_indicator.py +93 -0
  224. backtrader/indicators/contrib/hlr_indicator.py +95 -0
  225. backtrader/indicators/contrib/hma.py +50 -0
  226. backtrader/indicators/contrib/i4_drfv2.py +34 -0
  227. backtrader/indicators/contrib/i4_drfv3.py +38 -0
  228. backtrader/indicators/contrib/i_anch_mom_indicator.py +72 -0
  229. backtrader/indicators/contrib/i_de_marker_sign_indicator.py +64 -0
  230. backtrader/indicators/contrib/i_gap_indicator.py +45 -0
  231. backtrader/indicators/contrib/i_stoch_komposter_indicator.py +77 -0
  232. backtrader/indicators/contrib/i_trend_indicator.py +125 -0
  233. backtrader/indicators/contrib/iamma_indicator.py +39 -0
  234. backtrader/indicators/contrib/indexed_moving_average.py +33 -0
  235. backtrader/indicators/contrib/instantaneous_trend_filter_indicator.py +51 -0
  236. backtrader/indicators/contrib/inverse_reaction_indicator.py +41 -0
  237. backtrader/indicators/contrib/irsi_sign_indicator.py +95 -0
  238. backtrader/indicators/contrib/iwpr_sign_indicator.py +59 -0
  239. backtrader/indicators/contrib/j_brain_trend1_sig_indicator.py +233 -0
  240. backtrader/indicators/contrib/j_tpo_proxy.py +32 -0
  241. backtrader/indicators/contrib/jma_slope_indicator.py +73 -0
  242. backtrader/indicators/contrib/kalman_filter_indicator.py +119 -0
  243. backtrader/indicators/contrib/kalman_filter_line.py +127 -0
  244. backtrader/indicators/contrib/kama_indicator.py +150 -0
  245. backtrader/indicators/contrib/karacatica_indicator.py +99 -0
  246. backtrader/indicators/contrib/kdj_indicator.py +59 -0
  247. backtrader/indicators/contrib/kwan_ccc_indicator.py +195 -0
  248. backtrader/indicators/contrib/kwan_nrp_indicator.py +113 -0
  249. backtrader/indicators/contrib/kwan_rdp_indicator.py +192 -0
  250. backtrader/indicators/contrib/laguerre_adx_indicator.py +85 -0
  251. backtrader/indicators/contrib/laguerre_filter_indicator.py +66 -0
  252. backtrader/indicators/contrib/laguerre_plus_di_proxy.py +57 -0
  253. backtrader/indicators/contrib/laguerre_roc_indicator.py +81 -0
  254. backtrader/indicators/contrib/le_man_signal_indicator.py +63 -0
  255. backtrader/indicators/contrib/linear_reg_slope_v2_indicator.py +136 -0
  256. backtrader/indicators/contrib/loco_indicator.py +88 -0
  257. backtrader/indicators/contrib/lrma_indicator.py +185 -0
  258. backtrader/indicators/contrib/lsma_angle_indicator.py +106 -0
  259. backtrader/indicators/contrib/ma_rounding_channel_indicator.py +149 -0
  260. backtrader/indicators/contrib/macd2_indicator.py +61 -0
  261. backtrader/indicators/contrib/macd_candle_indicator.py +80 -0
  262. backtrader/indicators/contrib/malr_indicator.py +77 -0
  263. backtrader/indicators/contrib/momentum_candle_sign_indicator.py +51 -0
  264. backtrader/indicators/contrib/moving_average_fn_indicator.py +139 -0
  265. backtrader/indicators/contrib/mt5_stochastic_close_close.py +57 -0
  266. backtrader/indicators/contrib/muv_nor_diff_cloud_indicator.py +107 -0
  267. backtrader/indicators/contrib/non_lag_dot_indicator.py +124 -0
  268. backtrader/indicators/contrib/nrtr_extr_indicator.py +95 -0
  269. backtrader/indicators/contrib/nrtr_indicator.py +95 -0
  270. backtrader/indicators/contrib/p_channel_system.py +40 -0
  271. backtrader/indicators/contrib/percent_envelope.py +37 -0
  272. backtrader/indicators/contrib/percentage_crossover_channel.py +47 -0
  273. backtrader/indicators/contrib/pivot_zig_zag_proxy.py +47 -0
  274. backtrader/indicators/contrib/price_channel_stop_indicator.py +104 -0
  275. backtrader/indicators/contrib/price_extreme_channel.py +35 -0
  276. backtrader/indicators/contrib/qqe_cloud_indicator.py +129 -0
  277. backtrader/indicators/contrib/ravi_indicator.py +40 -0
  278. backtrader/indicators/contrib/raw_close_close_stochastic.py +74 -0
  279. backtrader/indicators/contrib/rd_trend_trigger_indicator.py +51 -0
  280. backtrader/indicators/contrib/renko_level.py +85 -0
  281. backtrader/indicators/contrib/renko_line_break.py +91 -0
  282. backtrader/indicators/contrib/rftl_indicator.py +41 -0
  283. backtrader/indicators/contrib/rkd_indicator.py +53 -0
  284. backtrader/indicators/contrib/roc2_vg_indicator.py +68 -0
  285. backtrader/indicators/contrib/rsi_histogram_indicator.py +43 -0
  286. backtrader/indicators/contrib/rsi_slowdown.py +57 -0
  287. backtrader/indicators/contrib/rsioma_v2.py +41 -0
  288. backtrader/indicators/contrib/rvi_histogram_indicator.py +107 -0
  289. backtrader/indicators/contrib/safe_adx.py +89 -0
  290. backtrader/indicators/contrib/shared_strategy_indicators.py +1651 -0
  291. backtrader/indicators/contrib/sidus_indicator.py +105 -0
  292. backtrader/indicators/contrib/silver_trend_indicator.py +79 -0
  293. backtrader/indicators/contrib/sliding_range_color.py +56 -0
  294. backtrader/indicators/contrib/slow_stoch.py +42 -0
  295. backtrader/indicators/contrib/smoothed_adx_indicator.py +86 -0
  296. backtrader/indicators/contrib/smoothed_rsi.py +31 -0
  297. backtrader/indicators/contrib/spearman_rank_correlation_histogram.py +60 -0
  298. backtrader/indicators/contrib/stalin_indicator.py +152 -0
  299. backtrader/indicators/contrib/starter_laguerre_filter.py +62 -0
  300. backtrader/indicators/contrib/step_manrtr_indicator.py +137 -0
  301. backtrader/indicators/contrib/stochastic_histogram_indicator.py +143 -0
  302. backtrader/indicators/contrib/t3_alarm_indicator.py +125 -0
  303. backtrader/indicators/contrib/t3_average.py +76 -0
  304. backtrader/indicators/contrib/t3_indicator.py +40 -0
  305. backtrader/indicators/contrib/the20s_v020_signal.py +93 -0
  306. backtrader/indicators/contrib/three_candles_indicator.py +70 -0
  307. backtrader/indicators/contrib/three_line_break_indicator.py +64 -0
  308. backtrader/indicators/contrib/time_line.py +57 -0
  309. backtrader/indicators/contrib/trading_channel_index_proxy.py +48 -0
  310. backtrader/indicators/contrib/trend_arrows_indicator.py +109 -0
  311. backtrader/indicators/contrib/trend_continuation_indicator.py +127 -0
  312. backtrader/indicators/contrib/trend_intensity_index_proxy.py +51 -0
  313. backtrader/indicators/contrib/trend_manager_indicator.py +39 -0
  314. backtrader/indicators/contrib/tri_x_candle_indicator.py +51 -0
  315. backtrader/indicators/contrib/trigger_line.py +66 -0
  316. backtrader/indicators/contrib/triple_ema_rate.py +34 -0
  317. backtrader/indicators/contrib/trvi_indicator.py +194 -0
  318. backtrader/indicators/contrib/two_pb_ideal_xosma_indicator.py +127 -0
  319. backtrader/indicators/contrib/ultra_absolutely_no_lag_lwma_color.py +92 -0
  320. backtrader/indicators/contrib/ultra_wpr_indicator.py +173 -0
  321. backtrader/indicators/contrib/up_down_candle_strength.py +68 -0
  322. backtrader/indicators/contrib/vinin_i_trend_indicator.py +139 -0
  323. backtrader/indicators/contrib/volume_weighted_ma_indicator.py +78 -0
  324. backtrader/indicators/contrib/volume_weighted_ma_st_dev_indicator.py +111 -0
  325. backtrader/indicators/contrib/vwap_close_indicator.py +65 -0
  326. backtrader/indicators/contrib/vwma_candle.py +57 -0
  327. backtrader/indicators/contrib/vwma_digit_system.py +70 -0
  328. backtrader/indicators/contrib/wami.py +43 -0
  329. backtrader/indicators/contrib/wprsi_signal_indicator.py +105 -0
  330. backtrader/indicators/contrib/x_de_marker_histogram_vol_direct_indicator.py +145 -0
  331. backtrader/indicators/contrib/x_fisher_indicator.py +64 -0
  332. backtrader/indicators/contrib/xcci_histogram_vol_direct_indicator.py +56 -0
  333. backtrader/indicators/contrib/xcci_histogram_vol_indicator.py +85 -0
  334. backtrader/indicators/contrib/xma_ichimoku.py +163 -0
  335. backtrader/indicators/contrib/xma_ishimoku_channel_indicator.py +65 -0
  336. backtrader/indicators/contrib/xma_ishimoku_line.py +68 -0
  337. backtrader/indicators/contrib/xma_range_bands_indicator.py +107 -0
  338. backtrader/indicators/contrib/xmacd_indicator.py +70 -0
  339. backtrader/indicators/contrib/xrsi_de_marker_histogram.py +67 -0
  340. backtrader/indicators/contrib/xrsi_histogram_vol_direct_indicator.py +52 -0
  341. backtrader/indicators/contrib/xrsi_histogram_vol_indicator.py +81 -0
  342. backtrader/indicators/contrib/xrvi_indicator.py +130 -0
  343. backtrader/indicators/contrib/zero_lag_macd.py +36 -0
  344. backtrader/indicators/contrib/zig_zag_recent_pivot_signal.py +90 -0
  345. backtrader/indicators/contrib/zpf_indicator.py +115 -0
  346. backtrader/indicators/crossover.py +337 -0
  347. backtrader/indicators/dema.py +175 -0
  348. backtrader/indicators/demarker.py +270 -0
  349. backtrader/indicators/deviation.py +284 -0
  350. backtrader/indicators/directionalmove.py +1071 -0
  351. backtrader/indicators/dma.py +112 -0
  352. backtrader/indicators/dpo.py +96 -0
  353. backtrader/indicators/dv2.py +56 -0
  354. backtrader/indicators/ema.py +145 -0
  355. backtrader/indicators/envelope.py +475 -0
  356. backtrader/indicators/hadelta.py +198 -0
  357. backtrader/indicators/heikinashi.py +153 -0
  358. backtrader/indicators/hma.py +153 -0
  359. backtrader/indicators/hurst.py +151 -0
  360. backtrader/indicators/ichimoku.py +267 -0
  361. backtrader/indicators/kama.py +181 -0
  362. backtrader/indicators/kst.py +159 -0
  363. backtrader/indicators/lrsi.py +125 -0
  364. backtrader/indicators/mabase.py +147 -0
  365. backtrader/indicators/macd.py +322 -0
  366. backtrader/indicators/momentum.py +267 -0
  367. backtrader/indicators/moneyflow.py +237 -0
  368. backtrader/indicators/mt5atr.py +124 -0
  369. backtrader/indicators/myind.py +179 -0
  370. backtrader/indicators/obv.py +94 -0
  371. backtrader/indicators/ols.py +265 -0
  372. backtrader/indicators/oscillator.py +161 -0
  373. backtrader/indicators/percentchange.py +83 -0
  374. backtrader/indicators/percentrank.py +46 -0
  375. backtrader/indicators/pivotpoint.py +469 -0
  376. backtrader/indicators/prettygoodoscillator.py +113 -0
  377. backtrader/indicators/priceops_ext.py +123 -0
  378. backtrader/indicators/priceoscillator.py +262 -0
  379. backtrader/indicators/psar.py +212 -0
  380. backtrader/indicators/rmi.py +69 -0
  381. backtrader/indicators/rsi.py +440 -0
  382. backtrader/indicators/sma.py +141 -0
  383. backtrader/indicators/smma.py +116 -0
  384. backtrader/indicators/spread.py +54 -0
  385. backtrader/indicators/stochastic.py +263 -0
  386. backtrader/indicators/supertrend.py +436 -0
  387. backtrader/indicators/trend_ext.py +105 -0
  388. backtrader/indicators/trix.py +202 -0
  389. backtrader/indicators/tsi.py +155 -0
  390. backtrader/indicators/ultimateoscillator.py +158 -0
  391. backtrader/indicators/vortex.py +62 -0
  392. backtrader/indicators/williams.py +194 -0
  393. backtrader/indicators/wma.py +103 -0
  394. backtrader/indicators/zlema.py +135 -0
  395. backtrader/indicators/zlind.py +104 -0
  396. backtrader/linebuffer.py +3155 -0
  397. backtrader/lineiterator.py +2911 -0
  398. backtrader/lineroot.py +1106 -0
  399. backtrader/lineseries.py +2559 -0
  400. backtrader/live_trading/__init__.py +31 -0
  401. backtrader/live_trading/interface.py +404 -0
  402. backtrader/mathsupport.py +94 -0
  403. backtrader/metabase.py +1804 -0
  404. backtrader/mixins/__init__.py +21 -0
  405. backtrader/mixins/singleton.py +118 -0
  406. backtrader/observer.py +106 -0
  407. backtrader/observers/__init__.py +45 -0
  408. backtrader/observers/benchmark.py +126 -0
  409. backtrader/observers/broker.py +184 -0
  410. backtrader/observers/buysell.py +144 -0
  411. backtrader/observers/drawdown.py +161 -0
  412. backtrader/observers/logreturns.py +113 -0
  413. backtrader/observers/timereturn.py +86 -0
  414. backtrader/observers/trade_logger.py +2972 -0
  415. backtrader/observers/tradelogger.py +6 -0
  416. backtrader/observers/trades.py +258 -0
  417. backtrader/order.py +1114 -0
  418. backtrader/parameters.py +2345 -0
  419. backtrader/plot/__init__.py +54 -0
  420. backtrader/plot/finance.py +1022 -0
  421. backtrader/plot/formatters.py +200 -0
  422. backtrader/plot/locator.py +353 -0
  423. backtrader/plot/multicursor.py +495 -0
  424. backtrader/plot/plot.py +2500 -0
  425. backtrader/plot/plot_plotly.py +1351 -0
  426. backtrader/plot/scheme.py +253 -0
  427. backtrader/plot/utils.py +104 -0
  428. backtrader/position.py +290 -0
  429. backtrader/position_modes.py +132 -0
  430. backtrader/profiles.py +254 -0
  431. backtrader/reports/__init__.py +39 -0
  432. backtrader/reports/charts.py +371 -0
  433. backtrader/reports/performance.py +620 -0
  434. backtrader/reports/reporter.py +660 -0
  435. backtrader/resamplerfilter.py +1001 -0
  436. backtrader/signal.py +118 -0
  437. backtrader/signals/__init__.py +17 -0
  438. backtrader/sizer.py +114 -0
  439. backtrader/sizers/__init__.py +26 -0
  440. backtrader/sizers/fixedsize.py +161 -0
  441. backtrader/sizers/percents_sizer.py +119 -0
  442. backtrader/store.py +221 -0
  443. backtrader/stores/__init__.py +33 -0
  444. backtrader/stores/btapistore.py +15506 -0
  445. backtrader/stores/livestore.py +137 -0
  446. backtrader/stores/vchartfile.py +96 -0
  447. backtrader/strategy.py +3655 -0
  448. backtrader/talib.py +280 -0
  449. backtrader/test_helpers.py +96 -0
  450. backtrader/timer.py +358 -0
  451. backtrader/trade.py +442 -0
  452. backtrader/tradingcal.py +361 -0
  453. backtrader/utils/__init__.py +68 -0
  454. backtrader/utils/autodict.py +251 -0
  455. backtrader/utils/date.py +71 -0
  456. backtrader/utils/dateintern.py +509 -0
  457. backtrader/utils/flushfile.py +94 -0
  458. backtrader/utils/fractal.py +101 -0
  459. backtrader/utils/get_metrics.py +101 -0
  460. backtrader/utils/load_data.py +209 -0
  461. backtrader/utils/log_message.py +998 -0
  462. backtrader/utils/ordereddefaultdict.py +75 -0
  463. backtrader/utils/py3.py +296 -0
  464. backtrader/version.py +21 -0
  465. backtrader/writer.py +372 -0
backtrader/events.py ADDED
@@ -0,0 +1,980 @@
1
+ """Unified event data structures for tick-level backtesting and live trading.
2
+
3
+ This module defines the base EventData class and concrete event types used
4
+ across all data channels. Events use Python dataclasses for performance
5
+ and type safety.
6
+
7
+ Event Types:
8
+ - TickEvent: Individual trade/tick data
9
+ - OrderBookSnapshot: Order book depth snapshot
10
+ - FundingEvent: Funding rate data for perpetual contracts
11
+ - BarEvent: OHLCV bar data
12
+
13
+ Example:
14
+ Creating a tick event::
15
+
16
+ tick = TickEvent(
17
+ timestamp=1609459200.123,
18
+ symbol='BTC/USDT',
19
+ price=50000.5,
20
+ volume=1.234,
21
+ direction='buy'
22
+ )
23
+ assert tick.validate()
24
+ assert tick.event_type == 'tick'
25
+ """
26
+
27
+ import os
28
+ import time
29
+ import uuid
30
+ from abc import ABC, abstractmethod
31
+ from dataclasses import asdict, dataclass, field
32
+ from typing import List, Optional, Tuple
33
+
34
+ _CLOCK_DOMAIN_ID = f"process-{os.getpid()}-{uuid.uuid4().hex}"
35
+
36
+
37
+ def _event_id() -> str:
38
+ """Return an opaque process-local identity for causal event accounting."""
39
+ return uuid.uuid4().hex
40
+
41
+
42
+ @dataclass
43
+ class EventData(ABC):
44
+ """Base class for all event data.
45
+
46
+ All event types share common fields: timestamp, symbol, exchange,
47
+ asset_type, and local_time. Subclasses must implement event_type
48
+ property and can override validate() for type-specific checks.
49
+
50
+ Attributes:
51
+ timestamp: Unix timestamp in seconds (supports millisecond precision).
52
+ symbol: Trading pair symbol (e.g., 'BTC/USDT').
53
+ exchange: Exchange name (e.g., 'binance').
54
+ asset_type: Asset type ('spot', 'swap', 'futures').
55
+ local_time: Local receive timestamp (for latency tracking).
56
+ """
57
+
58
+ timestamp: float
59
+ symbol: str
60
+ exchange: str = ""
61
+ asset_type: str = "spot"
62
+ local_time: Optional[float] = None
63
+ exchange_time: Optional[float] = None
64
+ received_wall_time: Optional[float] = None
65
+ received_monotonic_ns: Optional[int] = None
66
+ clock_domain_id: str = _CLOCK_DOMAIN_ID
67
+ sequence: int = 0
68
+ previous_sequence: Optional[int] = None
69
+ snapshot_or_delta: str = ""
70
+ continuity_status: str = "unknown"
71
+ stale: bool = False
72
+ stale_reason: str = ""
73
+ source: str = ""
74
+ event_id: str = field(default_factory=_event_id)
75
+ coalesced_count: int = 1
76
+
77
+ def __post_init__(self) -> None:
78
+ """Fill receive-clock metadata without confusing it with exchange time."""
79
+ if self.exchange_time is None:
80
+ self.exchange_time = self.timestamp
81
+ if self.received_wall_time is None:
82
+ self.received_wall_time = self.local_time or time.time()
83
+ if self.received_monotonic_ns is None:
84
+ self.received_monotonic_ns = time.monotonic_ns()
85
+ if not self.clock_domain_id:
86
+ self.clock_domain_id = _CLOCK_DOMAIN_ID
87
+ if not self.event_id:
88
+ self.event_id = _event_id()
89
+
90
+ @property
91
+ def continuity(self) -> str:
92
+ """Compatibility alias for the canonical continuity status."""
93
+ return self.continuity_status
94
+
95
+ @property
96
+ @abstractmethod
97
+ def event_type(self) -> str:
98
+ """Return the event type identifier string."""
99
+
100
+ def to_dict(self) -> dict:
101
+ """Convert event data to a dictionary for serialization."""
102
+ result = asdict(self)
103
+ result["continuity"] = self.continuity_status
104
+ # Include dynamically-set attributes (e.g. datetime set by btapifeed)
105
+ if hasattr(self, "datetime") and "datetime" not in result:
106
+ result["datetime"] = getattr(self, "datetime")
107
+ return result
108
+
109
+ def validate(self) -> bool:
110
+ """Validate common event fields.
111
+
112
+ Returns:
113
+ True if valid, False otherwise.
114
+ """
115
+ if not isinstance(self.timestamp, (int, float)) or self.timestamp <= 0:
116
+ return False
117
+ if not isinstance(self.symbol, str) or not self.symbol:
118
+ return False
119
+ if self.local_time is not None:
120
+ if not isinstance(self.local_time, (int, float)) or self.local_time <= 0:
121
+ return False
122
+ if self.exchange_time is not None and (
123
+ not isinstance(self.exchange_time, (int, float)) or self.exchange_time <= 0
124
+ ):
125
+ return False
126
+ if self.received_wall_time is not None and (
127
+ not isinstance(self.received_wall_time, (int, float)) or self.received_wall_time <= 0
128
+ ):
129
+ return False
130
+ if self.received_monotonic_ns is not None and (
131
+ not isinstance(self.received_monotonic_ns, int) or self.received_monotonic_ns <= 0
132
+ ):
133
+ return False
134
+ if not isinstance(self.coalesced_count, int) or self.coalesced_count < 1:
135
+ return False
136
+ if self.stale and not self.stale_reason:
137
+ return False
138
+ return True
139
+
140
+
141
+ @dataclass(init=False)
142
+ class TickEvent(EventData):
143
+ """Tick/trade event data.
144
+
145
+ Represents a single trade execution on an exchange. Compatible with
146
+ the existing TickerData interface via adapter pattern.
147
+
148
+ Attributes:
149
+ price: Trade execution price.
150
+ volume: Trade execution volume/amount.
151
+ direction: Trade direction ('buy' or 'sell').
152
+ trade_id: Exchange trade identifier.
153
+ bid_price: Best bid price at time of trade.
154
+ ask_price: Best ask price at time of trade.
155
+ bid_volume: Best bid volume at time of trade.
156
+ ask_volume: Best ask volume at time of trade.
157
+ """
158
+
159
+ price: float = 0.0
160
+ volume: float = 0.0
161
+ direction: str = "buy"
162
+ trade_id: str = ""
163
+ bid_price: Optional[float] = None
164
+ ask_price: Optional[float] = None
165
+ bid_volume: Optional[float] = None
166
+ ask_volume: Optional[float] = None
167
+
168
+ def __init__(
169
+ self,
170
+ timestamp: float,
171
+ symbol: str,
172
+ exchange: str = "",
173
+ asset_type: str = "spot",
174
+ local_time: Optional[float] = None,
175
+ price: float = 0.0,
176
+ volume: float = 0.0,
177
+ direction: str = "buy",
178
+ trade_id: str = "",
179
+ bid_price: Optional[float] = None,
180
+ ask_price: Optional[float] = None,
181
+ bid_volume: Optional[float] = None,
182
+ ask_volume: Optional[float] = None,
183
+ *,
184
+ exchange_time: Optional[float] = None,
185
+ received_wall_time: Optional[float] = None,
186
+ received_monotonic_ns: Optional[int] = None,
187
+ clock_domain_id: str = _CLOCK_DOMAIN_ID,
188
+ sequence: int = 0,
189
+ previous_sequence: Optional[int] = None,
190
+ snapshot_or_delta: str = "",
191
+ continuity_status: str = "unknown",
192
+ stale: bool = False,
193
+ stale_reason: str = "",
194
+ source: str = "",
195
+ event_id: Optional[str] = None,
196
+ coalesced_count: int = 1,
197
+ ) -> None:
198
+ EventData.__init__(
199
+ self,
200
+ timestamp,
201
+ symbol,
202
+ exchange,
203
+ asset_type,
204
+ local_time,
205
+ exchange_time,
206
+ received_wall_time,
207
+ received_monotonic_ns,
208
+ clock_domain_id,
209
+ sequence,
210
+ previous_sequence,
211
+ snapshot_or_delta,
212
+ continuity_status,
213
+ stale,
214
+ stale_reason,
215
+ source,
216
+ event_id or _event_id(),
217
+ coalesced_count,
218
+ )
219
+ self.price = price
220
+ self.volume = volume
221
+ self.direction = direction
222
+ self.trade_id = trade_id
223
+ self.bid_price = bid_price
224
+ self.ask_price = ask_price
225
+ self.bid_volume = bid_volume
226
+ self.ask_volume = ask_volume
227
+
228
+ @property
229
+ def event_type(self) -> str:
230
+ """Return the event type identifier.
231
+
232
+ Returns:
233
+ str: The string 'tick' for tick events.
234
+ """
235
+ return "tick"
236
+
237
+ def validate(self) -> bool:
238
+ """Validate tick-specific fields.
239
+
240
+ Checks:
241
+ - Common fields valid (via super)
242
+ - Price > 0
243
+ - Volume >= 0
244
+ - Direction is 'buy' or 'sell'
245
+ - Optional bid/ask prices > 0 if present
246
+ """
247
+ if not super().validate():
248
+ return False
249
+ if not isinstance(self.price, (int, float)) or self.price <= 0:
250
+ return False
251
+ if not isinstance(self.volume, (int, float)) or self.volume < 0:
252
+ return False
253
+ if self.direction not in ("buy", "sell"):
254
+ return False
255
+ if self.bid_price is not None and self.bid_price <= 0:
256
+ return False
257
+ if self.ask_price is not None and self.ask_price <= 0:
258
+ return False
259
+ if self.bid_volume is not None and self.bid_volume < 0:
260
+ return False
261
+ if self.ask_volume is not None and self.ask_volume < 0:
262
+ return False
263
+ return True
264
+
265
+
266
+ @dataclass(init=False)
267
+ class OrderBookSnapshot(EventData):
268
+ """Order book depth snapshot.
269
+
270
+ Stores bid/ask depth levels as lists of (price, quantity) tuples.
271
+ Bids are in descending price order, asks in ascending price order.
272
+
273
+ Attributes:
274
+ bids: List of (price, quantity) tuples, descending by price.
275
+ asks: List of (price, quantity) tuples, ascending by price.
276
+ """
277
+
278
+ bids: List[Tuple[float, float]] = field(default_factory=list)
279
+ asks: List[Tuple[float, float]] = field(default_factory=list)
280
+
281
+ def __init__(
282
+ self,
283
+ timestamp: float,
284
+ symbol: str,
285
+ exchange: str = "",
286
+ asset_type: str = "spot",
287
+ local_time: Optional[float] = None,
288
+ bids: Optional[List[Tuple[float, float]]] = None,
289
+ asks: Optional[List[Tuple[float, float]]] = None,
290
+ *,
291
+ exchange_time: Optional[float] = None,
292
+ received_wall_time: Optional[float] = None,
293
+ received_monotonic_ns: Optional[int] = None,
294
+ clock_domain_id: str = _CLOCK_DOMAIN_ID,
295
+ sequence: int = 0,
296
+ previous_sequence: Optional[int] = None,
297
+ snapshot_or_delta: str = "",
298
+ continuity_status: str = "unknown",
299
+ stale: bool = False,
300
+ stale_reason: str = "",
301
+ source: str = "",
302
+ event_id: Optional[str] = None,
303
+ coalesced_count: int = 1,
304
+ ) -> None:
305
+ EventData.__init__(
306
+ self,
307
+ timestamp,
308
+ symbol,
309
+ exchange,
310
+ asset_type,
311
+ local_time,
312
+ exchange_time,
313
+ received_wall_time,
314
+ received_monotonic_ns,
315
+ clock_domain_id,
316
+ sequence,
317
+ previous_sequence,
318
+ snapshot_or_delta,
319
+ continuity_status,
320
+ stale,
321
+ stale_reason,
322
+ source,
323
+ event_id or _event_id(),
324
+ coalesced_count,
325
+ )
326
+ self.bids = list(bids or ())
327
+ self.asks = list(asks or ())
328
+
329
+ @property
330
+ def event_type(self) -> str:
331
+ """Return the event type identifier.
332
+
333
+ Returns:
334
+ str: The string 'orderbook' for order book snapshot events.
335
+ """
336
+ return "orderbook"
337
+
338
+ @property
339
+ def best_bid(self) -> Optional[float]:
340
+ """Best (highest) bid price."""
341
+ return self.bids[0][0] if self.bids else None
342
+
343
+ @property
344
+ def best_ask(self) -> Optional[float]:
345
+ """Best (lowest) ask price."""
346
+ return self.asks[0][0] if self.asks else None
347
+
348
+ @property
349
+ def spread(self) -> Optional[float]:
350
+ """Spread between best ask and best bid."""
351
+ if self.best_bid is not None and self.best_ask is not None:
352
+ return self.best_ask - self.best_bid
353
+ return None
354
+
355
+ @property
356
+ def mid_price(self) -> Optional[float]:
357
+ """Mid price between best bid and best ask."""
358
+ if self.best_bid is not None and self.best_ask is not None:
359
+ return (self.best_bid + self.best_ask) / 2.0
360
+ return None
361
+
362
+ def validate(self) -> bool:
363
+ """Validate order book specific fields.
364
+
365
+ Checks:
366
+ - Common fields valid (via super)
367
+ - At least one bid and one ask level
368
+ - Bids in descending order
369
+ - Asks in ascending order
370
+ - Best ask > best bid (positive spread)
371
+ - All prices > 0 and quantities > 0
372
+ """
373
+ if not super().validate():
374
+ return False
375
+ if not self.bids or not self.asks:
376
+ return False
377
+ # Validate bid levels: descending order, positive values
378
+ for i, (price, qty) in enumerate(self.bids):
379
+ if price <= 0 or qty <= 0:
380
+ return False
381
+ if i > 0 and price > self.bids[i - 1][0]:
382
+ return False
383
+ # Validate ask levels: ascending order, positive values
384
+ for i, (price, qty) in enumerate(self.asks):
385
+ if price <= 0 or qty <= 0:
386
+ return False
387
+ if i > 0 and price < self.asks[i - 1][0]:
388
+ return False
389
+ # Spread check: best ask must be greater than best bid
390
+ if self.bids[0][0] >= self.asks[0][0]:
391
+ return False
392
+ return True
393
+
394
+
395
+ @dataclass(init=False)
396
+ class FundingEvent(EventData):
397
+ """Funding rate event for perpetual contracts.
398
+
399
+ Attributes:
400
+ rate: Current funding rate.
401
+ mark_price: Current mark price.
402
+ next_funding_time: Timestamp of next funding settlement.
403
+ predicted_rate: Predicted next funding rate.
404
+ """
405
+
406
+ rate: float = 0.0
407
+ mark_price: float = 0.0
408
+ next_funding_time: float = 0.0
409
+ predicted_rate: float = 0.0
410
+
411
+ def __init__(
412
+ self,
413
+ timestamp: float,
414
+ symbol: str,
415
+ exchange: str = "",
416
+ asset_type: str = "spot",
417
+ local_time: Optional[float] = None,
418
+ rate: float = 0.0,
419
+ mark_price: float = 0.0,
420
+ next_funding_time: float = 0.0,
421
+ predicted_rate: float = 0.0,
422
+ *,
423
+ exchange_time: Optional[float] = None,
424
+ received_wall_time: Optional[float] = None,
425
+ received_monotonic_ns: Optional[int] = None,
426
+ clock_domain_id: str = _CLOCK_DOMAIN_ID,
427
+ sequence: int = 0,
428
+ previous_sequence: Optional[int] = None,
429
+ snapshot_or_delta: str = "",
430
+ continuity_status: str = "unknown",
431
+ stale: bool = False,
432
+ stale_reason: str = "",
433
+ source: str = "",
434
+ event_id: Optional[str] = None,
435
+ coalesced_count: int = 1,
436
+ ) -> None:
437
+ EventData.__init__(
438
+ self,
439
+ timestamp,
440
+ symbol,
441
+ exchange,
442
+ asset_type,
443
+ local_time,
444
+ exchange_time,
445
+ received_wall_time,
446
+ received_monotonic_ns,
447
+ clock_domain_id,
448
+ sequence,
449
+ previous_sequence,
450
+ snapshot_or_delta,
451
+ continuity_status,
452
+ stale,
453
+ stale_reason,
454
+ source,
455
+ event_id or _event_id(),
456
+ coalesced_count,
457
+ )
458
+ self.rate = rate
459
+ self.mark_price = mark_price
460
+ self.next_funding_time = next_funding_time
461
+ self.predicted_rate = predicted_rate
462
+
463
+ @property
464
+ def event_type(self) -> str:
465
+ """Return the event type identifier.
466
+
467
+ Returns:
468
+ str: The string 'funding' for funding rate events.
469
+ """
470
+ return "funding"
471
+
472
+ def validate(self) -> bool:
473
+ """Validate funding event fields.
474
+
475
+ Checks:
476
+ - Common fields valid (via super)
477
+ - Mark price > 0
478
+ - Funding rate within reasonable range (-1, 1)
479
+ - Next funding time > current timestamp
480
+ """
481
+ if not super().validate():
482
+ return False
483
+ if not isinstance(self.mark_price, (int, float)) or self.mark_price <= 0:
484
+ return False
485
+ if not isinstance(self.rate, (int, float)):
486
+ return False
487
+ if abs(self.rate) >= 1.0:
488
+ return False
489
+ if self.next_funding_time > 0 and self.next_funding_time < self.timestamp:
490
+ return False
491
+ return True
492
+
493
+
494
+ @dataclass(init=False)
495
+ class BarEvent(EventData):
496
+ """OHLCV bar event data.
497
+
498
+ Compatible with existing backtrader bar-level data format.
499
+
500
+ Attributes:
501
+ open: Opening price.
502
+ high: Highest price.
503
+ low: Lowest price.
504
+ close: Closing price.
505
+ volume: Total volume during bar period.
506
+ openinterest: Open interest (for futures).
507
+ """
508
+
509
+ open: float = 0.0
510
+ high: float = 0.0
511
+ low: float = 0.0
512
+ close: float = 0.0
513
+ volume: float = 0.0
514
+ openinterest: float = 0.0
515
+
516
+ def __init__(
517
+ self,
518
+ timestamp: float,
519
+ symbol: str,
520
+ exchange: str = "",
521
+ asset_type: str = "spot",
522
+ local_time: Optional[float] = None,
523
+ open: float = 0.0,
524
+ high: float = 0.0,
525
+ low: float = 0.0,
526
+ close: float = 0.0,
527
+ volume: float = 0.0,
528
+ openinterest: float = 0.0,
529
+ *,
530
+ exchange_time: Optional[float] = None,
531
+ received_wall_time: Optional[float] = None,
532
+ received_monotonic_ns: Optional[int] = None,
533
+ clock_domain_id: str = _CLOCK_DOMAIN_ID,
534
+ sequence: int = 0,
535
+ previous_sequence: Optional[int] = None,
536
+ snapshot_or_delta: str = "",
537
+ continuity_status: str = "unknown",
538
+ stale: bool = False,
539
+ stale_reason: str = "",
540
+ source: str = "",
541
+ event_id: Optional[str] = None,
542
+ coalesced_count: int = 1,
543
+ ) -> None:
544
+ EventData.__init__(
545
+ self,
546
+ timestamp,
547
+ symbol,
548
+ exchange,
549
+ asset_type,
550
+ local_time,
551
+ exchange_time,
552
+ received_wall_time,
553
+ received_monotonic_ns,
554
+ clock_domain_id,
555
+ sequence,
556
+ previous_sequence,
557
+ snapshot_or_delta,
558
+ continuity_status,
559
+ stale,
560
+ stale_reason,
561
+ source,
562
+ event_id or _event_id(),
563
+ coalesced_count,
564
+ )
565
+ self.open = open
566
+ self.high = high
567
+ self.low = low
568
+ self.close = close
569
+ self.volume = volume
570
+ self.openinterest = openinterest
571
+
572
+ @property
573
+ def event_type(self) -> str:
574
+ """Return the event type identifier.
575
+
576
+ Returns:
577
+ str: The string 'bar' for OHLCV bar events.
578
+ """
579
+ return "bar"
580
+
581
+ def validate(self) -> bool:
582
+ """Validate bar event fields.
583
+
584
+ Checks:
585
+ - Common fields valid (via super)
586
+ - All OHLC prices > 0
587
+ - High >= Low
588
+ - High >= Open, Close
589
+ - Low <= Open, Close
590
+ - Volume >= 0
591
+ """
592
+ if not super().validate():
593
+ return False
594
+ for price in (self.open, self.high, self.low, self.close):
595
+ if not isinstance(price, (int, float)) or price <= 0:
596
+ return False
597
+ if self.high < self.low:
598
+ return False
599
+ if self.high < self.open or self.high < self.close:
600
+ return False
601
+ if self.low > self.open or self.low > self.close:
602
+ return False
603
+ if not isinstance(self.volume, (int, float)) or self.volume < 0:
604
+ return False
605
+ return True
606
+
607
+
608
+ # --- Adapter classes for backward compatibility ---
609
+
610
+
611
+ class TickEventAdapter:
612
+ """Adapter: TickEvent -> TickerData interface.
613
+
614
+ Wraps a TickEvent to provide the TickerData interface for backward
615
+ compatibility with existing code that uses TickerData.
616
+
617
+ Example::
618
+
619
+ tick = TickEvent(timestamp=100.0, symbol='BTC/USDT', price=50000, volume=1.0, direction='buy')
620
+ adapter = TickEventAdapter(tick)
621
+ assert adapter.get_last_price() == 50000
622
+
623
+ Attributes:
624
+ event: Event type identifier string.
625
+ _tick: The underlying TickEvent instance.
626
+ """
627
+
628
+ def __init__(self, tick_event: TickEvent):
629
+ """Initialize the adapter with a TickEvent.
630
+
631
+ Args:
632
+ tick_event: The TickEvent instance to wrap.
633
+ """
634
+ self.event = "TickerEvent"
635
+ self._tick = tick_event
636
+
637
+ def get_event(self):
638
+ """Return the event type identifier.
639
+
640
+ Returns:
641
+ str: The event type string "TickerEvent".
642
+ """
643
+ return self.event
644
+
645
+ def get_exchange_name(self):
646
+ """Return the exchange name from the tick event.
647
+
648
+ Returns:
649
+ str: The exchange name (e.g., 'binance').
650
+ """
651
+ return self._tick.exchange
652
+
653
+ def get_local_update_time(self):
654
+ """Return the local update timestamp.
655
+
656
+ Returns:
657
+ float: The local receive timestamp, or the server timestamp if
658
+ local_time is not set.
659
+ """
660
+ return self._tick.local_time or self._tick.timestamp
661
+
662
+ def get_symbol_name(self):
663
+ """Return the trading pair symbol.
664
+
665
+ Returns:
666
+ str: The symbol name (e.g., 'BTC/USDT').
667
+ """
668
+ return self._tick.symbol
669
+
670
+ def get_asset_type(self):
671
+ """Return the asset type.
672
+
673
+ Returns:
674
+ str: The asset type ('spot', 'swap', or 'futures').
675
+ """
676
+ return self._tick.asset_type
677
+
678
+ def get_server_time(self):
679
+ """Return the server timestamp from the tick event.
680
+
681
+ Returns:
682
+ float: The Unix timestamp in seconds.
683
+ """
684
+ return self._tick.timestamp
685
+
686
+ def get_bid_price(self):
687
+ """Return the best bid price.
688
+
689
+ Returns:
690
+ Optional[float]: The best bid price, or None if not available.
691
+ """
692
+ return self._tick.bid_price
693
+
694
+ def get_ask_price(self):
695
+ """Return the best ask price.
696
+
697
+ Returns:
698
+ Optional[float]: The best ask price, or None if not available.
699
+ """
700
+ return self._tick.ask_price
701
+
702
+ def get_bid_volume(self):
703
+ """Return the best bid volume.
704
+
705
+ Returns:
706
+ Optional[float]: The best bid volume, or None if not available.
707
+ """
708
+ return self._tick.bid_volume
709
+
710
+ def get_ask_volume(self):
711
+ """Return the best ask volume.
712
+
713
+ Returns:
714
+ Optional[float]: The best ask volume, or None if not available.
715
+ """
716
+ return self._tick.ask_volume
717
+
718
+ def get_last_price(self):
719
+ """Return the last trade price.
720
+
721
+ Returns:
722
+ float: The last execution price.
723
+ """
724
+ return self._tick.price
725
+
726
+ def get_last_volume(self):
727
+ """Return the last trade volume.
728
+
729
+ Returns:
730
+ float: The last execution volume/amount.
731
+ """
732
+ return self._tick.volume
733
+
734
+ def __str__(self):
735
+ """Return a string representation of the adapter.
736
+
737
+ Returns:
738
+ str: A descriptive string showing symbol, price, volume, and direction.
739
+ """
740
+ return (
741
+ f"TickEventAdapter({self._tick.symbol} "
742
+ f"price={self._tick.price} vol={self._tick.volume} "
743
+ f"dir={self._tick.direction})"
744
+ )
745
+
746
+ def __repr__(self):
747
+ """Return the string representation for debugging.
748
+
749
+ Returns:
750
+ str: Same as __str__().
751
+ """
752
+ return self.__str__()
753
+
754
+
755
+ class OrderBookEventAdapter:
756
+ """Adapter: OrderBookSnapshot -> OrderBookData interface.
757
+
758
+ Wraps an OrderBookSnapshot to provide the OrderBookData interface for
759
+ backward compatibility with existing code.
760
+
761
+ Attributes:
762
+ event: Event type identifier string.
763
+ _ob: The underlying OrderBookSnapshot instance.
764
+ """
765
+
766
+ def __init__(self, ob_event: OrderBookSnapshot):
767
+ """Initialize the adapter with an OrderBookSnapshot.
768
+
769
+ Args:
770
+ ob_event: The OrderBookSnapshot instance to wrap.
771
+ """
772
+ self.event = "OrderBookEvent"
773
+ self._ob = ob_event
774
+
775
+ def get_event(self):
776
+ """Return the event type identifier.
777
+
778
+ Returns:
779
+ str: The event type string "OrderBookEvent".
780
+ """
781
+ return self.event
782
+
783
+ def get_exchange_name(self):
784
+ """Return the exchange name from the order book event.
785
+
786
+ Returns:
787
+ str: The exchange name (e.g., 'binance').
788
+ """
789
+ return self._ob.exchange
790
+
791
+ def get_local_update_time(self):
792
+ """Return the local update timestamp.
793
+
794
+ Returns:
795
+ float: The local receive timestamp, or the server timestamp if
796
+ local_time is not set.
797
+ """
798
+ return self._ob.local_time or self._ob.timestamp
799
+
800
+ def get_symbol_name(self):
801
+ """Return the trading pair symbol.
802
+
803
+ Returns:
804
+ str: The symbol name (e.g., 'BTC/USDT').
805
+ """
806
+ return self._ob.symbol
807
+
808
+ def get_asset_type(self):
809
+ """Return the asset type.
810
+
811
+ Returns:
812
+ str: The asset type ('spot', 'swap', or 'futures').
813
+ """
814
+ return self._ob.asset_type
815
+
816
+ def get_server_time(self):
817
+ """Return the server timestamp from the order book event.
818
+
819
+ Returns:
820
+ float: The Unix timestamp in seconds.
821
+ """
822
+ return self._ob.timestamp
823
+
824
+ def get_bid_price_list(self):
825
+ """Return a list of bid prices.
826
+
827
+ Returns:
828
+ List[float]: List of bid prices in descending order.
829
+ """
830
+ return [b[0] for b in self._ob.bids]
831
+
832
+ def get_ask_price_list(self):
833
+ """Return a list of ask prices.
834
+
835
+ Returns:
836
+ List[float]: List of ask prices in ascending order.
837
+ """
838
+ return [a[0] for a in self._ob.asks]
839
+
840
+ def get_bid_volume_list(self):
841
+ """Return a list of bid volumes.
842
+
843
+ Returns:
844
+ List[float]: List of bid quantities corresponding to bid prices.
845
+ """
846
+ return [b[1] for b in self._ob.bids]
847
+
848
+ def get_ask_volume_list(self):
849
+ """Return a list of ask volumes.
850
+
851
+ Returns:
852
+ List[float]: List of ask quantities corresponding to ask prices.
853
+ """
854
+ return [a[1] for a in self._ob.asks]
855
+
856
+ def __str__(self):
857
+ """Return a string representation of the adapter.
858
+
859
+ Returns:
860
+ str: A descriptive string showing symbol, best bid, and best ask.
861
+ """
862
+ return f"OrderBookEventAdapter({self._ob.symbol} bid={self._ob.best_bid} ask={self._ob.best_ask})"
863
+
864
+ def __repr__(self):
865
+ """Return the string representation for debugging.
866
+
867
+ Returns:
868
+ str: Same as __str__().
869
+ """
870
+ return self.__str__()
871
+
872
+
873
+ class FundingEventAdapter:
874
+ """Adapter: FundingEvent -> FundingRateData interface.
875
+
876
+ Wraps a FundingEvent to provide the FundingRateData interface for
877
+ backward compatibility with existing code.
878
+
879
+ Attributes:
880
+ event: Event type identifier string.
881
+ _funding: The underlying FundingEvent instance.
882
+ """
883
+
884
+ def __init__(self, funding_event: FundingEvent):
885
+ """Initialize the adapter with a FundingEvent.
886
+
887
+ Args:
888
+ funding_event: The FundingEvent instance to wrap.
889
+ """
890
+ self.event = "FundingEvent"
891
+ self._funding = funding_event
892
+
893
+ def get_event_type(self):
894
+ """Return the event type identifier.
895
+
896
+ Returns:
897
+ str: The event type string "FundingEvent".
898
+ """
899
+ return self.event
900
+
901
+ def get_exchange_name(self):
902
+ """Return the exchange name from the funding event.
903
+
904
+ Returns:
905
+ str: The exchange name (e.g., 'binance').
906
+ """
907
+ return self._funding.exchange
908
+
909
+ def get_server_time(self):
910
+ """Return the server timestamp from the funding event.
911
+
912
+ Returns:
913
+ float: The Unix timestamp in seconds.
914
+ """
915
+ return self._funding.timestamp
916
+
917
+ def get_local_update_time(self):
918
+ """Return the local update timestamp.
919
+
920
+ Returns:
921
+ float: The local receive timestamp, or the server timestamp if
922
+ local_time is not set.
923
+ """
924
+ return self._funding.local_time or self._funding.timestamp
925
+
926
+ def get_asset_type(self):
927
+ """Return the asset type.
928
+
929
+ Returns:
930
+ str: The asset type ('spot', 'swap', or 'futures').
931
+ """
932
+ return self._funding.asset_type
933
+
934
+ def get_symbol_name(self):
935
+ """Return the trading pair symbol.
936
+
937
+ Returns:
938
+ str: The symbol name (e.g., 'BTC/USDT').
939
+ """
940
+ return self._funding.symbol
941
+
942
+ def get_current_funding_rate(self):
943
+ """Return the current funding rate.
944
+
945
+ Returns:
946
+ float: The current funding rate as a decimal (e.g., 0.0001 for 0.01%).
947
+ """
948
+ return self._funding.rate
949
+
950
+ def get_next_funding_time(self):
951
+ """Return the timestamp of the next funding settlement.
952
+
953
+ Returns:
954
+ float: The Unix timestamp of the next funding payment.
955
+ """
956
+ return self._funding.next_funding_time
957
+
958
+ def get_next_funding_rate(self):
959
+ """Return the predicted next funding rate.
960
+
961
+ Returns:
962
+ float: The predicted funding rate for the next period.
963
+ """
964
+ return self._funding.predicted_rate
965
+
966
+ def __str__(self):
967
+ """Return a string representation of the adapter.
968
+
969
+ Returns:
970
+ str: A descriptive string showing symbol and funding rate.
971
+ """
972
+ return f"FundingEventAdapter({self._funding.symbol} rate={self._funding.rate})"
973
+
974
+ def __repr__(self):
975
+ """Return the string representation for debugging.
976
+
977
+ Returns:
978
+ str: Same as __str__().
979
+ """
980
+ return self.__str__()