lumibot 4.1.0__tar.gz → 4.1.2__tar.gz

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.

Potentially problematic release.


This version of lumibot might be problematic. Click here for more details.

Files changed (269) hide show
  1. {lumibot-4.1.0 → lumibot-4.1.2}/MANIFEST.in +0 -1
  2. {lumibot-4.1.0/lumibot.egg-info → lumibot-4.1.2}/PKG-INFO +13 -2
  3. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/backtesting/databento_backtesting.py +4 -0
  4. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/thetadata_helper.py +15 -10
  5. {lumibot-4.1.0 → lumibot-4.1.2/lumibot.egg-info}/PKG-INFO +13 -2
  6. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot.egg-info/SOURCES.txt +2 -1
  7. {lumibot-4.1.0 → lumibot-4.1.2}/setup.py +5 -2
  8. lumibot-4.1.2/tests/backtest/test_databento_parity.py +81 -0
  9. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_databento_backtesting.py +44 -0
  10. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_databento_helper.py +3 -4
  11. {lumibot-4.1.0 → lumibot-4.1.2}/LICENSE +0 -0
  12. {lumibot-4.1.0 → lumibot-4.1.2}/README.md +0 -0
  13. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/__init__.py +0 -0
  14. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/backtesting/__init__.py +0 -0
  15. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/backtesting/alpaca_backtesting.py +0 -0
  16. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/backtesting/alpha_vantage_backtesting.py +0 -0
  17. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/backtesting/backtesting_broker.py +0 -0
  18. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/backtesting/ccxt_backtesting.py +0 -0
  19. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/backtesting/interactive_brokers_rest_backtesting.py +0 -0
  20. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/backtesting/pandas_backtesting.py +0 -0
  21. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/backtesting/polygon_backtesting.py +0 -0
  22. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/backtesting/thetadata_backtesting.py +0 -0
  23. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/backtesting/yahoo_backtesting.py +0 -0
  24. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/brokers/__init__.py +0 -0
  25. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/brokers/alpaca.py +0 -0
  26. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/brokers/bitunix.py +0 -0
  27. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/brokers/broker.py +0 -0
  28. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/brokers/ccxt.py +0 -0
  29. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/brokers/example_broker.py +0 -0
  30. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/brokers/interactive_brokers.py +0 -0
  31. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/brokers/interactive_brokers_rest.py +0 -0
  32. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/brokers/projectx.py +0 -0
  33. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/brokers/schwab.py +0 -0
  34. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/brokers/tradier.py +0 -0
  35. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/brokers/tradovate.py +0 -0
  36. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/components/__init__.py +0 -0
  37. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/components/configs_helper.py +0 -0
  38. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/components/drift_rebalancer_logic.py +0 -0
  39. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/components/grok_helper.py +0 -0
  40. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/components/options_helper.py +0 -0
  41. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/components/perplexity_helper.py +0 -0
  42. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/components/quiver_helper.py +0 -0
  43. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/components/vix_helper.py +0 -0
  44. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/constants.py +0 -0
  45. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/credentials.py +0 -0
  46. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/__init__.py +0 -0
  47. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/alpaca_data.py +0 -0
  48. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/alpha_vantage_data.py +0 -0
  49. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/bitunix_data.py +0 -0
  50. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/ccxt_backtesting_data.py +0 -0
  51. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/ccxt_data.py +0 -0
  52. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/data_source.py +0 -0
  53. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/data_source_backtesting.py +0 -0
  54. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/databento_data.py +0 -0
  55. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/databento_data_polars_backtesting.py +0 -0
  56. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/databento_data_polars_live.py +0 -0
  57. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/example_broker_data.py +0 -0
  58. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/exceptions.py +0 -0
  59. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/interactive_brokers_data.py +0 -0
  60. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/interactive_brokers_rest_data.py +0 -0
  61. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/pandas_data.py +0 -0
  62. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/polars_mixin.py +0 -0
  63. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/polygon_data_polars.py +0 -0
  64. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/projectx_data.py +0 -0
  65. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/schwab_data.py +0 -0
  66. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/tradier_data.py +0 -0
  67. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/tradovate_data.py +0 -0
  68. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/yahoo_data.py +0 -0
  69. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/data_sources/yahoo_data_polars.py +0 -0
  70. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/entities/__init__.py +0 -0
  71. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/entities/asset.py +0 -0
  72. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/entities/bar.py +0 -0
  73. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/entities/bars.py +0 -0
  74. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/entities/chains.py +0 -0
  75. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/entities/data.py +0 -0
  76. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/entities/dataline.py +0 -0
  77. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/entities/order.py +0 -0
  78. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/entities/position.py +0 -0
  79. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/entities/quote.py +0 -0
  80. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/entities/trading_fee.py +0 -0
  81. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/__init__.py +0 -0
  82. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/bitunix_futures_example.py +0 -0
  83. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/ccxt_backtesting_example.py +0 -0
  84. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/classic_60_40.py +0 -0
  85. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/classic_60_40_config.py +0 -0
  86. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/crypto_50_50.py +0 -0
  87. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/crypto_50_50_config.py +0 -0
  88. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/crypto_important_functions.py +0 -0
  89. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/drift_rebalancer.py +0 -0
  90. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/forex_hold_to_expiry.py +0 -0
  91. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/futures_hold_to_expiry.py +0 -0
  92. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/lifecycle_logger.py +0 -0
  93. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/options_hold_to_expiry.py +0 -0
  94. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/schedule_function.py +0 -0
  95. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/simple_start_single_file.py +0 -0
  96. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/stock_bracket.py +0 -0
  97. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/stock_buy_and_hold.py +0 -0
  98. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/stock_diversified_leverage.py +0 -0
  99. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/stock_limit_and_trailing_stops.py +0 -0
  100. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/stock_momentum.py +0 -0
  101. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/stock_oco.py +0 -0
  102. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/strangle.py +0 -0
  103. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/example_strategies/test_broker_functions.py +0 -0
  104. {lumibot-4.1.0 → lumibot-4.1.2/lumibot/resources}/ThetaTerminal.jar +0 -0
  105. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/resources/conf.yaml +0 -0
  106. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/strategies/__init__.py +0 -0
  107. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/strategies/_strategy.py +0 -0
  108. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/strategies/session_manager.py +0 -0
  109. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/strategies/strategy.py +0 -0
  110. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/strategies/strategy_executor.py +0 -0
  111. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/__init__.py +0 -0
  112. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/alpaca_helpers.py +0 -0
  113. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/bitunix_helpers.py +0 -0
  114. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/black_scholes.py +0 -0
  115. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/ccxt_data_store.py +0 -0
  116. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/databento_helper.py +0 -0
  117. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/databento_helper_polars.py +0 -0
  118. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/databento_roll.py +0 -0
  119. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/debugers.py +0 -0
  120. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/decorators.py +0 -0
  121. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/futures_symbols.py +0 -0
  122. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/helpers.py +0 -0
  123. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/indicators.py +0 -0
  124. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/lumibot_logger.py +0 -0
  125. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/lumibot_time.py +0 -0
  126. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/pandas.py +0 -0
  127. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/polygon_helper.py +0 -0
  128. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/polygon_helper_async.py +0 -0
  129. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/polygon_helper_polars_optimized.py +0 -0
  130. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/projectx_helpers.py +0 -0
  131. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/schwab_helper.py +0 -0
  132. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/types.py +0 -0
  133. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/yahoo_helper.py +0 -0
  134. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/tools/yahoo_helper_polars_optimized.py +0 -0
  135. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/traders/__init__.py +0 -0
  136. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/traders/debug_log_trader.py +0 -0
  137. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/traders/trader.py +0 -0
  138. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/trading_builtins/__init__.py +0 -0
  139. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/trading_builtins/custom_stream.py +0 -0
  140. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot/trading_builtins/safe_list.py +0 -0
  141. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot.egg-info/dependency_links.txt +0 -0
  142. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot.egg-info/requires.txt +0 -0
  143. {lumibot-4.1.0 → lumibot-4.1.2}/lumibot.egg-info/top_level.txt +0 -0
  144. {lumibot-4.1.0 → lumibot-4.1.2}/pyproject.toml +0 -0
  145. {lumibot-4.1.0 → lumibot-4.1.2}/setup.cfg +0 -0
  146. {lumibot-4.1.0 → lumibot-4.1.2}/tests/__init__.py +0 -0
  147. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/__init__.py +0 -0
  148. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/check_timing_offset.py +0 -0
  149. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/check_volume_spike.py +0 -0
  150. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/comprehensive_comparison.py +0 -0
  151. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/conftest.py +0 -0
  152. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/debug_comparison.py +0 -0
  153. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/diagnose_price_difference.py +0 -0
  154. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/direct_api_comparison.py +0 -0
  155. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/performance_tracker.py +0 -0
  156. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/profile_thetadata_vs_polygon.py +0 -0
  157. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/root_cause_analysis.py +0 -0
  158. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_accuracy_verification.py +0 -0
  159. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_backtesting_broker_processing.py +0 -0
  160. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_buy_hold_quiet_logs_full_run.py +0 -0
  161. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_crypto_cash_regressions.py +0 -0
  162. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_daily_data_timestamp_comparison.py +0 -0
  163. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_databento.py +0 -0
  164. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_databento_comprehensive_trading.py +0 -0
  165. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_debug_avg_fill_price.py +0 -0
  166. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_dividends.py +0 -0
  167. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_example_strategies.py +0 -0
  168. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_failing_backtest.py +0 -0
  169. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_futures_edge_cases.py +0 -0
  170. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_futures_single_trade.py +0 -0
  171. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_futures_ultra_simple.py +0 -0
  172. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_index_data_verification.py +0 -0
  173. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_multileg_backtest.py +0 -0
  174. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_pandas_backtest.py +0 -0
  175. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_passing_trader_into_backtest.py +0 -0
  176. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_polygon.py +0 -0
  177. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_strategy_executor.py +0 -0
  178. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_thetadata.py +0 -0
  179. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_thetadata_comprehensive.py +0 -0
  180. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_thetadata_vs_polygon.py +0 -0
  181. {lumibot-4.1.0 → lumibot-4.1.2}/tests/backtest/test_yahoo.py +0 -0
  182. {lumibot-4.1.0 → lumibot-4.1.2}/tests/conftest.py +0 -0
  183. {lumibot-4.1.0 → lumibot-4.1.2}/tests/fixtures.py +0 -0
  184. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_alpaca.py +0 -0
  185. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_alpaca_auth_fix.py +0 -0
  186. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_alpaca_backtesting.py +0 -0
  187. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_alpaca_data.py +0 -0
  188. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_alpaca_helpers.py +0 -0
  189. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_alpaca_multileg_fix.py +0 -0
  190. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_alpaca_oauth.py +0 -0
  191. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_apscheduler_warnings.py +0 -0
  192. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_asset.py +0 -0
  193. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_asset_auto_expiry.py +0 -0
  194. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_auto_market_inference.py +0 -0
  195. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_backtesting_broker.py +0 -0
  196. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_backtesting_broker_await_close.py +0 -0
  197. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_backtesting_broker_time_advance.py +0 -0
  198. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_backtesting_crypto_cash_unit.py +0 -0
  199. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_backtesting_data_source_env.py +0 -0
  200. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_backtesting_flow_control.py +0 -0
  201. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_backtesting_multileg_unit.py +0 -0
  202. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_backtesting_quiet_logs_complete.py +0 -0
  203. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_bars_aggregate_frequency_normalization.py +0 -0
  204. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_bars_aggregation_timeunits.py +0 -0
  205. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_bars_frequency_flex.py +0 -0
  206. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_botspot_handler.py +0 -0
  207. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_botspot_logger.py +0 -0
  208. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_broker_bitunix.py +0 -0
  209. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_broker_cleanup.py +0 -0
  210. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_broker_initialization.py +0 -0
  211. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_brokers_handle_crypto.py +0 -0
  212. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_cash.py +0 -0
  213. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_ccxt.py +0 -0
  214. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_ccxt_store.py +0 -0
  215. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_configs_helper.py +0 -0
  216. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_continuous_futures.py +0 -0
  217. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_continuous_futures_integration.py +0 -0
  218. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_continuous_futures_resolution.py +0 -0
  219. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_data_source.py +0 -0
  220. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_databento_asset_validation.py +0 -0
  221. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_databento_auto_expiry_integration.py +0 -0
  222. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_databento_data.py +0 -0
  223. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_databento_live.py +0 -0
  224. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_databento_timezone_fixes.py +0 -0
  225. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_drift_rebalancer.py +0 -0
  226. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_futures_integration.py +0 -0
  227. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_get_historical_prices.py +0 -0
  228. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_helpers.py +0 -0
  229. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_indicator_subplots.py +0 -0
  230. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_integration_tests.py +0 -0
  231. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_interactive_brokers.py +0 -0
  232. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_live_trading_resilience.py +0 -0
  233. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_logger_env_vars.py +0 -0
  234. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_logging.py +0 -0
  235. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_lumibot_logger.py +0 -0
  236. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_market_infinite_loop_bug.py +0 -0
  237. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_mes_symbols.py +0 -0
  238. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_momentum.py +0 -0
  239. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_options_helper.py +0 -0
  240. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_order.py +0 -0
  241. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_order_serialization.py +0 -0
  242. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_pandas_data.py +0 -0
  243. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_polygon_helper.py +0 -0
  244. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_position_serialization.py +0 -0
  245. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_projectx.py +0 -0
  246. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_projectx_bracket_helpers.py +0 -0
  247. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_projectx_bracket_lifecycle_unit.py +0 -0
  248. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_projectx_data.py +0 -0
  249. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_projectx_datetime_columns.py +0 -0
  250. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_projectx_datetime_index.py +0 -0
  251. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_projectx_helpers.py +0 -0
  252. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_projectx_lifecycle.py +0 -0
  253. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_projectx_lifecycle_unit.py +0 -0
  254. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_projectx_live_flow.py +0 -0
  255. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_projectx_timestep_alias.py +0 -0
  256. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_projectx_url_mappings.py +0 -0
  257. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_quiet_logs_buy_and_hold.py +0 -0
  258. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_quiet_logs_comprehensive.py +0 -0
  259. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_quiet_logs_functionality.py +0 -0
  260. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_quiet_logs_requirements.py +0 -0
  261. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_session_manager.py +0 -0
  262. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_strategy_methods.py +0 -0
  263. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_thetadata_helper.py +0 -0
  264. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_tradier.py +0 -0
  265. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_tradier_data.py +0 -0
  266. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_tradingfee.py +0 -0
  267. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_tradovate.py +0 -0
  268. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_unified_logger.py +0 -0
  269. {lumibot-4.1.0 → lumibot-4.1.2}/tests/test_vix_helper.py +0 -0
@@ -1,2 +1 @@
1
1
  recursive-include lumibot/resources *
2
- include ThetaTerminal.jar
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: lumibot
3
- Version: 4.1.0
3
+ Version: 4.1.2
4
4
  Summary: Backtesting and Trading Library, Made by Lumiwealth
5
5
  Home-page: https://github.com/Lumiwealth/lumibot
6
6
  Author: Robert Grzesik
@@ -51,6 +51,17 @@ Requires-Dist: schwab-py>=1.5.0
51
51
  Requires-Dist: Flask>=2.3
52
52
  Requires-Dist: free-proxy
53
53
  Requires-Dist: requests-oauthlib
54
+ Dynamic: author
55
+ Dynamic: author-email
56
+ Dynamic: classifier
57
+ Dynamic: description
58
+ Dynamic: description-content-type
59
+ Dynamic: home-page
60
+ Dynamic: license
61
+ Dynamic: license-file
62
+ Dynamic: requires-dist
63
+ Dynamic: requires-python
64
+ Dynamic: summary
54
65
 
55
66
  [![CI Status](https://github.com/Lumiwealth/lumibot/actions/workflows/cicd.yaml/badge.svg?branch=dev)](https://github.com/Lumiwealth/lumibot/actions/workflows/cicd.yaml)
56
67
  [![Coverage](https://raw.githubusercontent.com/Lumiwealth/lumibot/badge/coverage.svg)](https://github.com/Lumiwealth/lumibot/actions/workflows/cicd.yaml)
@@ -438,6 +438,10 @@ class DataBentoDataBacktesting(PandasData):
438
438
  # Filter to data up to current backtest time (exclude current bar unless broker overrides)
439
439
  filtered_df = df[df.index <= cutoff_dt]
440
440
 
441
+ # If we have no prior bar (e.g., first iteration), allow the current timestamp
442
+ if filtered_df.empty:
443
+ filtered_df = df[df.index <= current_dt_aware]
444
+
441
445
  if not filtered_df.empty:
442
446
  last_price = filtered_df['close'].iloc[-1]
443
447
  if not pd.isna(last_price):
@@ -498,20 +498,25 @@ def start_theta_data_client(username: str, password: str):
498
498
  logger.info("ThetaTerminal.jar not found, copying from lumibot package...")
499
499
  import shutil as shutil_copy
500
500
 
501
- # Find the bundled jar file in the lumibot package
502
- lumibot_jar = Path(__file__).parent.parent.parent / "ThetaTerminal.jar"
501
+ package_root = Path(__file__).resolve().parent.parent
502
+ candidate_paths = [
503
+ package_root / "resources" / "ThetaTerminal.jar",
504
+ package_root.parent / "ThetaTerminal.jar", # legacy location fallback
505
+ ]
503
506
 
504
- if lumibot_jar.exists():
505
- logger.info(f"Copying ThetaTerminal.jar from {lumibot_jar} to {jar_file}")
506
- shutil_copy.copy2(lumibot_jar, jar_file)
507
- logger.info(f"Successfully copied ThetaTerminal.jar to {jar_file}")
508
- else:
507
+ lumibot_jar = next((path for path in candidate_paths if path.exists()), None)
508
+
509
+ if lumibot_jar is None:
509
510
  raise FileNotFoundError(
510
- f"ThetaTerminal.jar not found at {lumibot_jar}. "
511
- f"Please ensure ThetaTerminal.jar is included in the lumibot package, "
512
- f"or manually place it at {jar_file}"
511
+ "ThetaTerminal.jar not bundled with lumibot installation. "
512
+ f"Searched: {', '.join(str(path) for path in candidate_paths)}. "
513
+ f"Please reinstall lumibot or manually place the jar at {jar_file}"
513
514
  )
514
515
 
516
+ logger.info(f"Copying ThetaTerminal.jar from {lumibot_jar} to {jar_file}")
517
+ shutil_copy.copy2(lumibot_jar, jar_file)
518
+ logger.info(f"Successfully copied ThetaTerminal.jar to {jar_file}")
519
+
515
520
  if not jar_file.exists():
516
521
  raise FileNotFoundError(f"ThetaTerminal.jar not found at {jar_file}")
517
522
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: lumibot
3
- Version: 4.1.0
3
+ Version: 4.1.2
4
4
  Summary: Backtesting and Trading Library, Made by Lumiwealth
5
5
  Home-page: https://github.com/Lumiwealth/lumibot
6
6
  Author: Robert Grzesik
@@ -51,6 +51,17 @@ Requires-Dist: schwab-py>=1.5.0
51
51
  Requires-Dist: Flask>=2.3
52
52
  Requires-Dist: free-proxy
53
53
  Requires-Dist: requests-oauthlib
54
+ Dynamic: author
55
+ Dynamic: author-email
56
+ Dynamic: classifier
57
+ Dynamic: description
58
+ Dynamic: description-content-type
59
+ Dynamic: home-page
60
+ Dynamic: license
61
+ Dynamic: license-file
62
+ Dynamic: requires-dist
63
+ Dynamic: requires-python
64
+ Dynamic: summary
54
65
 
55
66
  [![CI Status](https://github.com/Lumiwealth/lumibot/actions/workflows/cicd.yaml/badge.svg?branch=dev)](https://github.com/Lumiwealth/lumibot/actions/workflows/cicd.yaml)
56
67
  [![Coverage](https://raw.githubusercontent.com/Lumiwealth/lumibot/badge/coverage.svg)](https://github.com/Lumiwealth/lumibot/actions/workflows/cicd.yaml)
@@ -1,7 +1,6 @@
1
1
  LICENSE
2
2
  MANIFEST.in
3
3
  README.md
4
- ThetaTerminal.jar
5
4
  pyproject.toml
6
5
  setup.cfg
7
6
  setup.py
@@ -102,6 +101,7 @@ lumibot/example_strategies/stock_momentum.py
102
101
  lumibot/example_strategies/stock_oco.py
103
102
  lumibot/example_strategies/strangle.py
104
103
  lumibot/example_strategies/test_broker_functions.py
104
+ lumibot/resources/ThetaTerminal.jar
105
105
  lumibot/resources/conf.yaml
106
106
  lumibot/strategies/__init__.py
107
107
  lumibot/strategies/_strategy.py
@@ -248,6 +248,7 @@ tests/backtest/test_crypto_cash_regressions.py
248
248
  tests/backtest/test_daily_data_timestamp_comparison.py
249
249
  tests/backtest/test_databento.py
250
250
  tests/backtest/test_databento_comprehensive_trading.py
251
+ tests/backtest/test_databento_parity.py
251
252
  tests/backtest/test_debug_avg_fill_price.py
252
253
  tests/backtest/test_dividends.py
253
254
  tests/backtest/test_example_strategies.py
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="lumibot",
8
- version="4.1.0",
8
+ version="4.1.2",
9
9
  author="Robert Grzesik",
10
10
  author_email="rob@lumiwealth.com",
11
11
  description="Backtesting and Trading Library, Made by Lumiwealth",
@@ -14,7 +14,7 @@ setuptools.setup(
14
14
  url="https://github.com/Lumiwealth/lumibot",
15
15
  packages=setuptools.find_packages(),
16
16
  license="MIT", # Add license argument
17
- include_package_data=True,
17
+ include_package_data=True,
18
18
  install_requires=[
19
19
  "polygon-api-client>=1.13.3",
20
20
  "alpaca-py>=0.42.0",
@@ -61,6 +61,9 @@ setuptools.setup(
61
61
  "free-proxy",
62
62
  "requests-oauthlib",
63
63
  ],
64
+ package_data={
65
+ "lumibot": ["resources/ThetaTerminal.jar"],
66
+ },
64
67
  classifiers=[
65
68
  "Programming Language :: Python :: 3",
66
69
  "Operating System :: OS Independent",
@@ -0,0 +1,81 @@
1
+ """Parity checks between DataBento pandas and polars backends."""
2
+
3
+ import shutil
4
+ from pathlib import Path
5
+ from datetime import datetime
6
+
7
+ import pandas as pd
8
+ import pytest
9
+ import pytz
10
+
11
+ from lumibot.backtesting.databento_backtesting import DataBentoDataBacktesting as DataBentoPandas
12
+ from lumibot.data_sources.databento_data_polars_backtesting import DataBentoDataPolarsBacktesting
13
+ from lumibot.entities import Asset
14
+ from lumibot.credentials import DATABENTO_CONFIG
15
+ from lumibot.tools import databento_helper, databento_helper_polars
16
+
17
+ DATABENTO_API_KEY = DATABENTO_CONFIG.get("API_KEY")
18
+
19
+
20
+ def _clear_databento_caches():
21
+ for cache_dir in (
22
+ databento_helper.LUMIBOT_DATABENTO_CACHE_FOLDER,
23
+ databento_helper_polars.LUMIBOT_DATABENTO_CACHE_FOLDER,
24
+ ):
25
+ path = Path(cache_dir)
26
+ if path.exists():
27
+ shutil.rmtree(path)
28
+
29
+
30
+ @pytest.mark.apitest
31
+ @pytest.mark.skipif(
32
+ not DATABENTO_API_KEY or DATABENTO_API_KEY == '<your key here>',
33
+ reason="This test requires a Databento API key",
34
+ )
35
+ def test_databento_price_parity():
36
+ """Ensure pandas and polars backends deliver identical prices."""
37
+
38
+ _clear_databento_caches()
39
+
40
+ tz = pytz.timezone("America/New_York")
41
+ start = tz.localize(datetime(2025, 9, 15, 0, 0))
42
+ end = tz.localize(datetime(2025, 9, 29, 23, 59))
43
+ asset = Asset("MES", asset_type=Asset.AssetType.CONT_FUTURE)
44
+
45
+ pandas_ds = DataBentoPandas(
46
+ datetime_start=start,
47
+ datetime_end=end,
48
+ api_key=DATABENTO_API_KEY,
49
+ show_progress_bar=False,
50
+ )
51
+ polars_ds = DataBentoDataPolarsBacktesting(
52
+ datetime_start=start,
53
+ datetime_end=end,
54
+ api_key=DATABENTO_API_KEY,
55
+ show_progress_bar=False,
56
+ )
57
+
58
+ # Prime caches
59
+ pandas_bars = pandas_ds.get_historical_prices(asset, 500, timestep="minute").df
60
+ polars_bars = polars_ds.get_historical_prices(asset, 500, timestep="minute").df
61
+
62
+ pd.testing.assert_frame_equal(polars_bars, pandas_bars)
63
+
64
+ checkpoints = [
65
+ (0, 0),
66
+ (3, 40),
67
+ (4, 0),
68
+ (7, 35),
69
+ (11, 5),
70
+ (14, 5),
71
+ ]
72
+
73
+ for hour, minute in checkpoints:
74
+ current_dt = tz.localize(datetime(2025, 9, 15, hour, minute))
75
+ pandas_ds._datetime = current_dt
76
+ polars_ds._datetime = current_dt
77
+ pandas_price = pandas_ds.get_last_price(asset)
78
+ polars_price = polars_ds.get_last_price(asset)
79
+ assert pandas_price == pytest.approx(polars_price), (
80
+ f"Mismatch at {current_dt}: pandas={pandas_price}, polars={polars_price}"
81
+ )
@@ -2,6 +2,7 @@ import unittest
2
2
  from unittest.mock import Mock, patch, MagicMock
3
3
  from datetime import datetime, timedelta
4
4
  import pandas as pd
5
+ import pytz
5
6
 
6
7
  from lumibot.backtesting.databento_backtesting import DataBentoDataBacktesting
7
8
  from lumibot.entities import Asset, Data
@@ -224,6 +225,49 @@ class TestDataBentoDataBacktesting(unittest.TestCase):
224
225
  self.assertEqual(result, 4250.75)
225
226
  mock_get_last_price.assert_called_once()
226
227
 
228
+ @patch('lumibot.tools.databento_helper.DATABENTO_AVAILABLE', True)
229
+ @patch('lumibot.tools.databento_helper.get_last_price_from_databento')
230
+ def test_get_last_price_uses_current_bar_when_available(self, mock_get_last_price):
231
+ """
232
+ Ensure we reuse the latest completed bar from cache (rather than hitting the API)
233
+ when no earlier bar exists in the window.
234
+ """
235
+ ny = pytz.timezone("America/New_York")
236
+ current_dt = ny.localize(datetime(2025, 1, 1, 9, 30))
237
+
238
+ backtester = DataBentoDataBacktesting(
239
+ datetime_start=self.start_date,
240
+ datetime_end=self.end_date,
241
+ api_key=self.api_key
242
+ )
243
+ backtester._datetime = current_dt
244
+
245
+ # Seed cached data with a single bar at the current timestamp
246
+ test_df = pd.DataFrame(
247
+ {
248
+ "open": [100.0],
249
+ "high": [101.0],
250
+ "low": [99.5],
251
+ "close": [100.5],
252
+ "volume": [1000],
253
+ },
254
+ index=pd.DatetimeIndex([current_dt]),
255
+ )
256
+
257
+ data = Data(
258
+ self.test_asset,
259
+ df=test_df,
260
+ timestep="minute",
261
+ quote=Asset("USD", "forex"),
262
+ )
263
+ search_asset = (self.test_asset, Asset("USD", "forex"))
264
+ backtester.pandas_data[search_asset] = data
265
+
266
+ price = backtester.get_last_price(asset=self.test_asset)
267
+
268
+ self.assertEqual(price, 100.5)
269
+ mock_get_last_price.assert_not_called()
270
+
227
271
  @patch('lumibot.tools.databento_helper.DATABENTO_AVAILABLE', True)
228
272
  def test_get_chains(self):
229
273
  """Test options chains retrieval (should return empty dict)"""
@@ -16,8 +16,7 @@ class TestDataBentoHelper(unittest.TestCase):
16
16
  self.api_key = "test_api_key"
17
17
  self.test_asset_future = Asset(
18
18
  symbol="ES",
19
- asset_type="future",
20
- expiration=datetime(2025, 3, 15).date()
19
+ asset_type="CONT_FUTURE"
21
20
  )
22
21
  self.test_asset_stock = Asset(
23
22
  symbol="AAPL",
@@ -217,8 +216,8 @@ class TestDataBentoHelper(unittest.TestCase):
217
216
  self.end_date,
218
217
  "minute"
219
218
  )
220
-
221
- expected_name = "ES_20250315_minute_20250101_20250131.parquet"
219
+
220
+ expected_name = "ES_minute_202501010000_202501310000.parquet"
222
221
  self.assertEqual(filename.name, expected_name)
223
222
 
224
223
  def test_no_retry_logic_for_correct_symbol(self):
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes