lumibot 4.2.1__tar.gz → 4.2.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.
- {lumibot-4.2.1/lumibot.egg-info → lumibot-4.2.2}/PKG-INFO +1 -1
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/thetadata_helper.py +19 -4
- {lumibot-4.2.1 → lumibot-4.2.2/lumibot.egg-info}/PKG-INFO +1 -1
- {lumibot-4.2.1 → lumibot-4.2.2}/setup.py +1 -1
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_backtest_cache_manager.py +7 -7
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_thetadata_helper.py +10 -9
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_thetadata_pandas_verification.py +1 -1
- {lumibot-4.2.1 → lumibot-4.2.2}/LICENSE +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/MANIFEST.in +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/README.md +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/__init__.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/__init__.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/alpaca_backtesting.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/alpha_vantage_backtesting.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/backtesting_broker.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/ccxt_backtesting.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/databento_backtesting.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/databento_backtesting_pandas.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/databento_backtesting_polars.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/fix_debug.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/interactive_brokers_rest_backtesting.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/pandas_backtesting.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/polygon_backtesting.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/thetadata_backtesting.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/thetadata_backtesting_pandas.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/backtesting/yahoo_backtesting.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/brokers/__init__.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/brokers/alpaca.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/brokers/bitunix.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/brokers/broker.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/brokers/ccxt.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/brokers/example_broker.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/brokers/interactive_brokers.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/brokers/interactive_brokers_rest.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/brokers/projectx.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/brokers/schwab.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/brokers/tradier.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/brokers/tradovate.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/components/__init__.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/components/configs_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/components/drift_rebalancer_logic.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/components/grok_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/components/options_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/components/perplexity_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/components/quiver_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/components/vix_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/constants.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/credentials.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/__init__.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/alpaca_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/alpha_vantage_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/bitunix_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/ccxt_backtesting_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/ccxt_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/data_source.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/data_source_backtesting.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/databento_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/databento_data_pandas.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/databento_data_polars.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/example_broker_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/exceptions.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/interactive_brokers_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/interactive_brokers_rest_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/pandas_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/polars_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/polars_mixin.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/polygon_data_polars.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/projectx_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/schwab_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/tradier_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/tradovate_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/yahoo_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/data_sources/yahoo_data_polars.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/entities/__init__.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/entities/asset.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/entities/bar.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/entities/bars.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/entities/chains.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/entities/data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/entities/data_polars.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/entities/dataline.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/entities/order.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/entities/position.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/entities/quote.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/entities/trading_fee.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/__init__.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/bitunix_futures_example.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/ccxt_backtesting_example.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/classic_60_40.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/classic_60_40_config.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/crypto_50_50.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/crypto_50_50_config.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/crypto_important_functions.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/drift_rebalancer.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/forex_hold_to_expiry.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/futures_hold_to_expiry.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/lifecycle_logger.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/options_hold_to_expiry.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/schedule_function.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/simple_start_single_file.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/stock_bracket.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/stock_buy_and_hold.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/stock_diversified_leverage.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/stock_limit_and_trailing_stops.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/stock_momentum.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/stock_oco.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/strangle.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/test_broker_functions.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/resources/ThetaTerminal.jar +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/resources/conf.yaml +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/strategies/__init__.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/strategies/_strategy.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/strategies/session_manager.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/strategies/strategy.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/strategies/strategy_executor.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/__init__.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/alpaca_helpers.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/backtest_cache.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/bitunix_helpers.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/black_scholes.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/ccxt_data_store.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/databento_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/databento_helper_polars.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/debugers.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/decorators.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/futures_roll.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/futures_symbols.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/helpers.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/indicators.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/lumibot_logger.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/lumibot_time.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/pandas.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/polars_utils.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/polygon_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/polygon_helper_async.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/polygon_helper_polars_optimized.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/projectx_helpers.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/schwab_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/types.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/yahoo_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/tools/yahoo_helper_polars_optimized.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/traders/__init__.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/traders/debug_log_trader.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/traders/trader.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/trading_builtins/__init__.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/trading_builtins/custom_stream.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot/trading_builtins/safe_list.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot.egg-info/SOURCES.txt +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot.egg-info/dependency_links.txt +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot.egg-info/requires.txt +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/lumibot.egg-info/top_level.txt +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/pyproject.toml +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/setup.cfg +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/__init__.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/__init__.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/conftest.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/performance_tracker.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/profile_thetadata_vs_polygon.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_accuracy_verification.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_backtesting_broker_processing.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_buy_hold_quiet_logs_full_run.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_crypto_cash_regressions.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_daily_data_timestamp_comparison.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_databento.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_databento_comprehensive_trading.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_databento_parity.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_debug_avg_fill_price.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_dividends.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_example_strategies.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_failing_backtest.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_futures_edge_cases.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_futures_single_trade.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_futures_ultra_simple.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_index_data_verification.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_multileg_backtest.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_pandas_backtest.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_passing_trader_into_backtest.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_polars_lru_eviction.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_polygon.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_strategy_executor.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_thetadata.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_thetadata_comprehensive.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_thetadata_vs_polygon.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/backtest/test_yahoo.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/conftest.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/fixtures.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_alpaca.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_alpaca_auth_fix.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_alpaca_backtesting.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_alpaca_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_alpaca_helpers.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_alpaca_multileg_fix.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_alpaca_oauth.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_apscheduler_warnings.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_asset.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_asset_auto_expiry.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_auto_market_inference.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_backtesting_broker.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_backtesting_broker_await_close.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_backtesting_broker_time_advance.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_backtesting_crypto_cash_unit.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_backtesting_data_source_env.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_backtesting_flow_control.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_backtesting_multileg_unit.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_backtesting_quiet_logs_complete.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_bars_aggregate_frequency_normalization.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_bars_aggregation_timeunits.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_bars_frequency_flex.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_botspot_handler.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_botspot_logger.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_broker_bitunix.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_broker_cleanup.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_broker_initialization.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_brokers_handle_crypto.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_cash.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_ccxt.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_ccxt_store.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_configs_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_continuous_futures.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_continuous_futures_integration.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_continuous_futures_resolution.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_data_polars_parity.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_data_source.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_databento_asset_validation.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_databento_auto_expiry_integration.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_databento_backtesting.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_databento_backtesting_polars.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_databento_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_databento_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_databento_live.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_databento_timezone_fixes.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_drift_rebalancer.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_futures_integration.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_futures_roll.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_get_historical_prices.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_helpers.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_indicator_subplots.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_integration_tests.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_interactive_brokers.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_live_trading_resilience.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_logger_env_vars.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_logging.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_lumibot_logger.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_market_infinite_loop_bug.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_mes_symbols.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_momentum.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_options_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_order.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_order_serialization.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_pandas_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_polars_resample.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_polygon_helper.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_position_serialization.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_projectx.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_projectx_bracket_helpers.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_projectx_bracket_lifecycle_unit.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_projectx_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_projectx_datetime_columns.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_projectx_datetime_index.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_projectx_helpers.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_projectx_lifecycle.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_projectx_lifecycle_unit.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_projectx_live_flow.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_projectx_timestep_alias.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_projectx_url_mappings.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_quiet_logs_buy_and_hold.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_quiet_logs_comprehensive.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_quiet_logs_functionality.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_quiet_logs_requirements.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_session_manager.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_strategy_methods.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_thetadata_backwards_compat.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_tradier.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_tradier_data.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_tradingfee.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_tradovate.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_unified_logger.py +0 -0
- {lumibot-4.2.1 → lumibot-4.2.2}/tests/test_vix_helper.py +0 -0
|
@@ -26,6 +26,17 @@ CONNECTION_MAX_RETRIES = 60
|
|
|
26
26
|
BOOT_GRACE_PERIOD = 5.0
|
|
27
27
|
MAX_RESTART_ATTEMPTS = 3
|
|
28
28
|
|
|
29
|
+
|
|
30
|
+
def _resolve_asset_folder(asset_obj: Asset) -> str:
|
|
31
|
+
asset_type = getattr(asset_obj, "asset_type", None) or "stock"
|
|
32
|
+
asset_key = str(asset_type).strip().lower()
|
|
33
|
+
return asset_key
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _normalize_folder_component(value: str, fallback: str) -> str:
|
|
37
|
+
normalized = str(value or "").strip().lower().replace(" ", "_")
|
|
38
|
+
return normalized or fallback
|
|
39
|
+
|
|
29
40
|
# Global process tracking for ThetaTerminal
|
|
30
41
|
THETA_DATA_PROCESS = None
|
|
31
42
|
THETA_DATA_PID = None
|
|
@@ -785,7 +796,11 @@ def get_trading_dates(asset: Asset, start: datetime, end: datetime):
|
|
|
785
796
|
def build_cache_filename(asset: Asset, timespan: str, datastyle: str = "ohlc"):
|
|
786
797
|
"""Helper function to create the cache filename for a given asset and timespan"""
|
|
787
798
|
|
|
788
|
-
|
|
799
|
+
provider_root = Path(LUMIBOT_CACHE_FOLDER) / CACHE_SUBFOLDER
|
|
800
|
+
asset_folder = _resolve_asset_folder(asset)
|
|
801
|
+
timespan_folder = _normalize_folder_component(timespan, "unknown")
|
|
802
|
+
datastyle_folder = _normalize_folder_component(datastyle, "default")
|
|
803
|
+
base_folder = provider_root / asset_folder / timespan_folder / datastyle_folder
|
|
789
804
|
|
|
790
805
|
# If It's an option then also add the expiration date, strike price and right to the filename
|
|
791
806
|
if asset.asset_type == "option":
|
|
@@ -799,7 +814,7 @@ def build_cache_filename(asset: Asset, timespan: str, datastyle: str = "ohlc"):
|
|
|
799
814
|
uniq_str = asset.symbol
|
|
800
815
|
|
|
801
816
|
cache_filename = f"{asset.asset_type}_{uniq_str}_{timespan}_{datastyle}.parquet"
|
|
802
|
-
cache_file =
|
|
817
|
+
cache_file = base_folder / cache_filename
|
|
803
818
|
return cache_file
|
|
804
819
|
|
|
805
820
|
|
|
@@ -1969,7 +1984,7 @@ def get_chains_cached(
|
|
|
1969
1984
|
Retrieve option chain with caching (MATCHES POLYGON PATTERN).
|
|
1970
1985
|
|
|
1971
1986
|
This function follows the EXACT same caching strategy as Polygon:
|
|
1972
|
-
1. Check cache: LUMIBOT_CACHE_FOLDER/thetadata
|
|
1987
|
+
1. Check cache: LUMIBOT_CACHE_FOLDER/thetadata/<asset-type>/option_chains/{symbol}_{date}.parquet
|
|
1973
1988
|
2. Reuse files within RECENT_FILE_TOLERANCE_DAYS (default 7 days)
|
|
1974
1989
|
3. If not found, fetch from ThetaData and save to cache
|
|
1975
1990
|
4. Use pyarrow engine with snappy compression
|
|
@@ -2006,7 +2021,7 @@ def get_chains_cached(
|
|
|
2006
2021
|
return None
|
|
2007
2022
|
|
|
2008
2023
|
# 2) Build cache folder path
|
|
2009
|
-
chain_folder = Path(LUMIBOT_CACHE_FOLDER) / "thetadata" / "option_chains"
|
|
2024
|
+
chain_folder = Path(LUMIBOT_CACHE_FOLDER) / "thetadata" / _resolve_asset_folder(asset) / "option_chains"
|
|
2010
2025
|
chain_folder.mkdir(parents=True, exist_ok=True)
|
|
2011
2026
|
|
|
2012
2027
|
# 3) Check for recent cached file (within RECENT_FILE_TOLERANCE_DAYS)
|
|
@@ -67,7 +67,7 @@ def _build_settings(prefix: str = "prod/cache") -> BacktestCacheSettings:
|
|
|
67
67
|
def test_remote_key_uses_relative_cache_path(tmp_path, monkeypatch):
|
|
68
68
|
cache_root = tmp_path / "cache"
|
|
69
69
|
cache_root.mkdir()
|
|
70
|
-
local_file = cache_root / "thetadata" / "
|
|
70
|
+
local_file = cache_root / "thetadata" / "stock" / "minute" / "ohlc" / "stock_SPY_minute_ohlc.parquet"
|
|
71
71
|
local_file.parent.mkdir(parents=True, exist_ok=True)
|
|
72
72
|
|
|
73
73
|
monkeypatch.setattr(backtest_cache, "LUMIBOT_CACHE_FOLDER", cache_root)
|
|
@@ -76,17 +76,17 @@ def test_remote_key_uses_relative_cache_path(tmp_path, monkeypatch):
|
|
|
76
76
|
manager = BacktestCacheManager(settings, client_factory=lambda settings: StubS3Client())
|
|
77
77
|
|
|
78
78
|
remote_key = manager.remote_key_for(local_file)
|
|
79
|
-
assert remote_key == "stage/cache/v3/thetadata/
|
|
79
|
+
assert remote_key == "stage/cache/v3/thetadata/stock/minute/ohlc/stock_SPY_minute_ohlc.parquet"
|
|
80
80
|
|
|
81
81
|
|
|
82
82
|
def test_ensure_local_file_downloads_from_s3(tmp_path, monkeypatch):
|
|
83
83
|
cache_root = tmp_path / "cache"
|
|
84
84
|
cache_root.mkdir()
|
|
85
|
-
local_file = cache_root / "thetadata" / "
|
|
85
|
+
local_file = cache_root / "thetadata" / "stock" / "minute" / "ohlc" / "stock_SPY_minute_ohlc.parquet"
|
|
86
86
|
|
|
87
87
|
monkeypatch.setattr(backtest_cache, "LUMIBOT_CACHE_FOLDER", cache_root)
|
|
88
88
|
|
|
89
|
-
remote_key = "stage/cache/v3/thetadata/
|
|
89
|
+
remote_key = "stage/cache/v3/thetadata/stock/minute/ohlc/stock_SPY_minute_ohlc.parquet"
|
|
90
90
|
objects = {("test-bucket", remote_key): b"cached-data"}
|
|
91
91
|
|
|
92
92
|
stub = StubS3Client(objects)
|
|
@@ -101,7 +101,7 @@ def test_ensure_local_file_downloads_from_s3(tmp_path, monkeypatch):
|
|
|
101
101
|
def test_ensure_local_file_handles_missing_remote(tmp_path, monkeypatch):
|
|
102
102
|
cache_root = tmp_path / "cache"
|
|
103
103
|
cache_root.mkdir()
|
|
104
|
-
local_file = cache_root / "thetadata" / "
|
|
104
|
+
local_file = cache_root / "thetadata" / "stock" / "minute" / "ohlc" / "stock_SPY_minute_ohlc.parquet"
|
|
105
105
|
|
|
106
106
|
monkeypatch.setattr(backtest_cache, "LUMIBOT_CACHE_FOLDER", cache_root)
|
|
107
107
|
|
|
@@ -116,13 +116,13 @@ def test_ensure_local_file_handles_missing_remote(tmp_path, monkeypatch):
|
|
|
116
116
|
def test_on_local_update_uploads_file(tmp_path, monkeypatch):
|
|
117
117
|
cache_root = tmp_path / "cache"
|
|
118
118
|
cache_root.mkdir()
|
|
119
|
-
local_file = cache_root / "thetadata" / "
|
|
119
|
+
local_file = cache_root / "thetadata" / "stock" / "minute" / "ohlc" / "stock_SPY_minute_ohlc.parquet"
|
|
120
120
|
local_file.parent.mkdir(parents=True, exist_ok=True)
|
|
121
121
|
local_file.write_bytes(b"new-data")
|
|
122
122
|
|
|
123
123
|
monkeypatch.setattr(backtest_cache, "LUMIBOT_CACHE_FOLDER", cache_root)
|
|
124
124
|
|
|
125
|
-
remote_key = "stage/cache/v3/thetadata/
|
|
125
|
+
remote_key = "stage/cache/v3/thetadata/stock/minute/ohlc/stock_SPY_minute_ohlc.parquet"
|
|
126
126
|
stub = StubS3Client({("test-bucket", remote_key): b"old"})
|
|
127
127
|
manager = BacktestCacheManager(_build_settings(prefix="stage/cache"), client_factory=lambda s: stub)
|
|
128
128
|
|
|
@@ -324,13 +324,13 @@ def test_get_trading_dates():
|
|
|
324
324
|
def test_build_cache_filename(mocker, tmpdir, datastyle):
|
|
325
325
|
asset = Asset("SPY")
|
|
326
326
|
timespan = "1D"
|
|
327
|
-
mocker.patch.object(thetadata_helper, "LUMIBOT_CACHE_FOLDER", tmpdir)
|
|
328
|
-
expected = tmpdir / "thetadata" / f"stock_SPY_1D_{datastyle}.parquet"
|
|
327
|
+
mocker.patch.object(thetadata_helper, "LUMIBOT_CACHE_FOLDER", str(tmpdir))
|
|
328
|
+
expected = tmpdir / "thetadata" / "stock" / "1d" / datastyle / f"stock_SPY_1D_{datastyle}.parquet"
|
|
329
329
|
assert thetadata_helper.build_cache_filename(asset, timespan, datastyle) == expected
|
|
330
330
|
|
|
331
331
|
expire_date = datetime.date(2023, 8, 1)
|
|
332
332
|
option_asset = Asset("SPY", asset_type="option", expiration=expire_date, strike=100, right="CALL")
|
|
333
|
-
expected = tmpdir / "thetadata" / f"option_SPY_230801_100_CALL_1D_{datastyle}.parquet"
|
|
333
|
+
expected = tmpdir / "thetadata" / "option" / "1d" / datastyle / f"option_SPY_230801_100_CALL_1D_{datastyle}.parquet"
|
|
334
334
|
assert thetadata_helper.build_cache_filename(option_asset, timespan, datastyle) == expected
|
|
335
335
|
|
|
336
336
|
# Bad option asset with no expiration
|
|
@@ -427,8 +427,8 @@ def test_missing_dates():
|
|
|
427
427
|
],
|
|
428
428
|
)
|
|
429
429
|
def test_update_cache(mocker, tmpdir, df_all, df_cached, datastyle):
|
|
430
|
-
mocker.patch.object(thetadata_helper, "LUMIBOT_CACHE_FOLDER", tmpdir)
|
|
431
|
-
cache_file =
|
|
430
|
+
mocker.patch.object(thetadata_helper, "LUMIBOT_CACHE_FOLDER", str(tmpdir))
|
|
431
|
+
cache_file = thetadata_helper.build_cache_filename(Asset("SPY"), "1D", datastyle)
|
|
432
432
|
|
|
433
433
|
# Empty DataFrame of df_all, don't write cache file
|
|
434
434
|
thetadata_helper.update_cache(cache_file, df_all, df_cached)
|
|
@@ -550,8 +550,9 @@ def test_get_price_data_invokes_remote_cache_manager(tmp_path, monkeypatch):
|
|
|
550
550
|
)
|
|
551
551
|
def test_load_data_from_cache(mocker, tmpdir, df_cached, datastyle):
|
|
552
552
|
# Setup some basics
|
|
553
|
-
mocker.patch.object(thetadata_helper, "LUMIBOT_CACHE_FOLDER", tmpdir)
|
|
554
|
-
|
|
553
|
+
mocker.patch.object(thetadata_helper, "LUMIBOT_CACHE_FOLDER", str(tmpdir))
|
|
554
|
+
asset = Asset("SPY")
|
|
555
|
+
cache_file = thetadata_helper.build_cache_filename(asset, "1D", datastyle)
|
|
555
556
|
|
|
556
557
|
# No cache file should return None (not raise)
|
|
557
558
|
assert thetadata_helper.load_cache(cache_file) is None
|
|
@@ -1371,8 +1372,8 @@ class TestThetaDataChainsCaching:
|
|
|
1371
1372
|
|
|
1372
1373
|
# CLEAR CACHE to ensure first call downloads fresh data
|
|
1373
1374
|
# This prevents cache pollution from previous tests in the suite
|
|
1374
|
-
# Chains are stored in: LUMIBOT_CACHE_FOLDER / "thetadata" / "option_chains"
|
|
1375
|
-
chain_folder = Path(LUMIBOT_CACHE_FOLDER) / "thetadata" / "option_chains"
|
|
1375
|
+
# Chains are stored in: LUMIBOT_CACHE_FOLDER / "thetadata" / "option" / "option_chains"
|
|
1376
|
+
chain_folder = Path(LUMIBOT_CACHE_FOLDER) / "thetadata" / "option" / "option_chains"
|
|
1376
1377
|
if chain_folder.exists():
|
|
1377
1378
|
# Delete all AAPL chain cache files
|
|
1378
1379
|
for cache_file in chain_folder.glob("AAPL_*.parquet"):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lumibot-4.2.1 → lumibot-4.2.2}/lumibot/example_strategies/stock_limit_and_trailing_stops.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|