lumibot 4.0.19__tar.gz → 4.0.20__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.0.19/lumibot.egg-info → lumibot-4.0.20}/PKG-INFO +1 -1
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/backtesting/backtesting_broker.py +20 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/strategies/strategy_executor.py +21 -3
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/indicators.py +4 -2
- {lumibot-4.0.19 → lumibot-4.0.20/lumibot.egg-info}/PKG-INFO +1 -1
- {lumibot-4.0.19 → lumibot-4.0.20}/setup.py +1 -1
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/test_polygon.py +3 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/LICENSE +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/MANIFEST.in +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/README.md +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/__init__.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/backtesting/__init__.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/backtesting/alpaca_backtesting.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/backtesting/alpha_vantage_backtesting.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/backtesting/ccxt_backtesting.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/backtesting/databento_backtesting.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/backtesting/databento_backtesting_polars.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/backtesting/interactive_brokers_rest_backtesting.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/backtesting/pandas_backtesting.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/backtesting/polygon_backtesting.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/backtesting/thetadata_backtesting.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/backtesting/yahoo_backtesting.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/brokers/__init__.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/brokers/alpaca.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/brokers/bitunix.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/brokers/broker.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/brokers/ccxt.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/brokers/example_broker.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/brokers/interactive_brokers.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/brokers/interactive_brokers_rest.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/brokers/projectx.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/brokers/schwab.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/brokers/tradier.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/brokers/tradovate.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/components/__init__.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/components/configs_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/components/drift_rebalancer_logic.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/components/grok_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/components/options_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/components/perplexity_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/components/quiver_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/components/vix_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/constants.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/credentials.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/__init__.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/alpaca_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/alpha_vantage_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/bitunix_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/ccxt_backtesting_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/ccxt_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/data_source.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/data_source_backtesting.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/databento_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/databento_data_polars.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/example_broker_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/exceptions.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/interactive_brokers_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/interactive_brokers_rest_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/pandas_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/polars_mixin.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/polygon_data_polars.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/projectx_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/schwab_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/tradier_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/tradovate_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/yahoo_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/data_sources/yahoo_data_polars.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/entities/__init__.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/entities/asset.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/entities/bar.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/entities/bars.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/entities/chains.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/entities/data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/entities/dataline.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/entities/order.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/entities/position.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/entities/quote.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/entities/trading_fee.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/__init__.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/bitunix_futures_example.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/ccxt_backtesting_example.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/classic_60_40.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/classic_60_40_config.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/crypto_50_50.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/crypto_50_50_config.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/crypto_important_functions.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/drift_rebalancer.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/forex_hold_to_expiry.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/futures_hold_to_expiry.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/lifecycle_logger.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/options_hold_to_expiry.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/schedule_function.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/simple_start_single_file.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/stock_bracket.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/stock_buy_and_hold.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/stock_diversified_leverage.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/stock_limit_and_trailing_stops.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/stock_momentum.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/stock_oco.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/strangle.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/example_strategies/test_broker_functions.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/resources/conf.yaml +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/strategies/__init__.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/strategies/_strategy.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/strategies/session_manager.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/strategies/strategy.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/__init__.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/alpaca_helpers.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/bitunix_helpers.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/black_scholes.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/ccxt_data_store.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/databento_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/databento_helper_polars.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/debugers.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/decorators.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/futures_symbols.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/helpers.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/lumibot_logger.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/lumibot_time.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/pandas.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/polygon_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/polygon_helper_async.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/polygon_helper_polars_optimized.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/projectx_helpers.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/schwab_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/thetadata_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/types.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/yahoo_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/tools/yahoo_helper_polars_optimized.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/traders/__init__.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/traders/debug_log_trader.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/traders/trader.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/trading_builtins/__init__.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/trading_builtins/custom_stream.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot/trading_builtins/safe_list.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot.egg-info/SOURCES.txt +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot.egg-info/dependency_links.txt +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot.egg-info/requires.txt +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/lumibot.egg-info/top_level.txt +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/pyproject.toml +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/setup.cfg +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/__init__.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/__init__.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/test_backtesting_broker_processing.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/test_buy_hold_quiet_logs_full_run.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/test_crypto_cash_regressions.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/test_dividends.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/test_example_strategies.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/test_failing_backtest.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/test_multileg_backtest.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/test_pandas_backtest.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/test_passing_trader_into_backtest.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/test_strategy_executor.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/test_thetadata.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/backtest/test_yahoo.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/conftest.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/fixtures.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_alpaca.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_alpaca_auth_fix.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_alpaca_backtesting.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_alpaca_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_alpaca_helpers.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_alpaca_multileg_fix.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_alpaca_oauth.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_apscheduler_warnings.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_asset.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_asset_auto_expiry.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_auto_market_inference.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_backtesting_broker.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_backtesting_broker_await_close.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_backtesting_broker_time_advance.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_backtesting_crypto_cash_unit.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_backtesting_flow_control.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_backtesting_multileg_unit.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_backtesting_quiet_logs_complete.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_bars_aggregate_frequency_normalization.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_bars_aggregation_timeunits.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_bars_frequency_flex.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_botspot_handler.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_botspot_logger.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_broker_bitunix.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_broker_cleanup.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_broker_initialization.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_brokers_handle_crypto.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_cash.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_ccxt.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_ccxt_store.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_configs_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_continuous_futures.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_continuous_futures_integration.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_continuous_futures_resolution.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_data_source.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_databento_asset_validation.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_databento_auto_expiry_integration.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_databento_backtesting.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_databento_backtesting_polars.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_databento_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_databento_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_databento_live.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_databento_timezone_fixes.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_drift_rebalancer.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_futures_integration.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_get_historical_prices.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_helpers.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_indicator_subplots.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_integration_tests.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_interactive_brokers.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_live_trading_resilience.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_logger_env_vars.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_logging.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_lumibot_logger.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_market_infinite_loop_bug.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_mes_symbols.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_momentum.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_options_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_order.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_order_serialization.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_pandas_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_polygon_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_position_serialization.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_projectx.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_projectx_bracket_helpers.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_projectx_bracket_lifecycle_unit.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_projectx_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_projectx_datetime_columns.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_projectx_datetime_index.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_projectx_helpers.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_projectx_lifecycle.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_projectx_lifecycle_unit.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_projectx_live_flow.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_projectx_timestep_alias.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_projectx_url_mappings.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_quiet_logs_buy_and_hold.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_quiet_logs_comprehensive.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_quiet_logs_functionality.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_quiet_logs_requirements.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_session_manager.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_strategy_methods.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_thetadata_helper.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_tradier.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_tradier_data.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_tradingfee.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_tradovate.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_unified_logger.py +0 -0
- {lumibot-4.0.19 → lumibot-4.0.20}/tests/test_vix_helper.py +0 -0
|
@@ -493,15 +493,35 @@ class BacktestingBroker(Broker):
|
|
|
493
493
|
|
|
494
494
|
in_stream_thread = threading.current_thread().name.startswith(f"broker_{self.name}")
|
|
495
495
|
|
|
496
|
+
# Track which orders have been canceled to avoid duplicate processing
|
|
497
|
+
canceled_identifiers = set()
|
|
498
|
+
|
|
496
499
|
def _cancel_inline(order: Order):
|
|
500
|
+
if order.identifier in canceled_identifiers:
|
|
501
|
+
return
|
|
502
|
+
canceled_identifiers.add(order.identifier)
|
|
497
503
|
self._process_trade_event(order, self.CANCELED_ORDER)
|
|
498
504
|
for child in order.child_orders:
|
|
499
505
|
_cancel_inline(child)
|
|
500
506
|
|
|
501
507
|
open_orders = self.get_tracked_orders(strategy=strategy_name)
|
|
508
|
+
|
|
509
|
+
# Build a set of all child order identifiers to skip them in the main loop
|
|
510
|
+
# (they will be handled by their parent orders)
|
|
511
|
+
child_order_identifiers = set()
|
|
512
|
+
for tracked_order in open_orders:
|
|
513
|
+
if tracked_order.child_orders:
|
|
514
|
+
for child in tracked_order.child_orders:
|
|
515
|
+
child_order_identifiers.add(child.identifier)
|
|
516
|
+
|
|
502
517
|
for tracked_order in open_orders:
|
|
503
518
|
if tracked_order.identifier in exclude_identifiers:
|
|
504
519
|
continue
|
|
520
|
+
if tracked_order.identifier in canceled_identifiers:
|
|
521
|
+
continue
|
|
522
|
+
# Skip child orders - they will be handled by their parent
|
|
523
|
+
if tracked_order.identifier in child_order_identifiers:
|
|
524
|
+
continue
|
|
505
525
|
if tracked_order.asset != asset:
|
|
506
526
|
continue
|
|
507
527
|
if not tracked_order.is_active():
|
|
@@ -1178,14 +1178,28 @@ class StrategyExecutor(Thread):
|
|
|
1178
1178
|
# Sleep until the market closes.
|
|
1179
1179
|
self.safe_sleep(time_to_close)
|
|
1180
1180
|
|
|
1181
|
-
# Remove the time to close from the strategy sleep time.
|
|
1182
|
-
strategy_sleeptime -= time_to_close
|
|
1183
|
-
|
|
1184
1181
|
# Check if the broker has a function to process expired option contracts.
|
|
1185
1182
|
if hasattr(self.broker, "process_expired_option_contracts"):
|
|
1186
1183
|
# Process expired option contracts.
|
|
1187
1184
|
self.broker.process_expired_option_contracts(self.strategy)
|
|
1188
1185
|
|
|
1186
|
+
# For backtesting with non-continuous markets, after reaching market close,
|
|
1187
|
+
# we should end the trading session for this day and return False to break out
|
|
1188
|
+
# of the backtesting loop. The main loop will then call _advance_to_next_trading_day()
|
|
1189
|
+
# to move to the next trading day.
|
|
1190
|
+
#
|
|
1191
|
+
# IMPORTANT: Skip this ONLY for pure PandasDataBacktesting sources (not Polygon
|
|
1192
|
+
# which inherits from PandasData) to maintain backward compatibility with existing
|
|
1193
|
+
# tests that expect pandas daily data to process multiple days in a single call.
|
|
1194
|
+
is_pure_pandas_data = (hasattr(self.broker, 'data_source') and
|
|
1195
|
+
type(self.broker.data_source).__name__ in ('PandasData', 'PandasDataBacktesting'))
|
|
1196
|
+
|
|
1197
|
+
if self.strategy.is_backtesting and not is_pure_pandas_data:
|
|
1198
|
+
return False
|
|
1199
|
+
|
|
1200
|
+
# For live trading or pandas data, continue with the remaining sleep time
|
|
1201
|
+
strategy_sleeptime -= time_to_close
|
|
1202
|
+
|
|
1189
1203
|
# TODO: next line speed implication: medium (371 microseconds)
|
|
1190
1204
|
self.safe_sleep(strategy_sleeptime)
|
|
1191
1205
|
|
|
@@ -1352,6 +1366,10 @@ class StrategyExecutor(Thread):
|
|
|
1352
1366
|
if not sleep_result:
|
|
1353
1367
|
break
|
|
1354
1368
|
|
|
1369
|
+
# Recalculate time_to_close for the next iteration
|
|
1370
|
+
if not is_continuous_market:
|
|
1371
|
+
time_to_close = self.broker.get_time_to_close()
|
|
1372
|
+
|
|
1355
1373
|
# Don't log this to avoid creating root handler
|
|
1356
1374
|
# self.strategy.log_message(f"Backtesting loop completed with {iteration_count} iterations")
|
|
1357
1375
|
|
|
@@ -665,7 +665,8 @@ def plot_returns(
|
|
|
665
665
|
# Buy ticks
|
|
666
666
|
buys = df_final.copy()
|
|
667
667
|
buys[strategy_name] = buys[strategy_name].bfill()
|
|
668
|
-
|
|
668
|
+
# Include all buy-type sides: buy, buy_to_open, buy_to_cover, buy_to_close
|
|
669
|
+
buys = buys.loc[df_final["side"].isin(["buy", "buy_to_open", "buy_to_cover", "buy_to_close"])]
|
|
669
670
|
|
|
670
671
|
def generate_buysell_plotly_text(row):
|
|
671
672
|
if row["status"] not in ("fill", "partial_fill"):
|
|
@@ -809,7 +810,8 @@ def plot_returns(
|
|
|
809
810
|
# Sell ticks
|
|
810
811
|
sells = df_final.copy()
|
|
811
812
|
sells[strategy_name] = sells[strategy_name].bfill()
|
|
812
|
-
|
|
813
|
+
# Include all sell-type sides: sell, sell_to_close, sell_short, sell_to_open
|
|
814
|
+
sells = sells.loc[df_final["side"].isin(["sell", "sell_to_close", "sell_short", "sell_to_open"])]
|
|
813
815
|
|
|
814
816
|
sells_ticks_df = sells.apply(generate_buysell_plotly_text, axis=1)
|
|
815
817
|
|
|
@@ -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.0.
|
|
8
|
+
version="4.0.20",
|
|
9
9
|
author="Robert Grzesik",
|
|
10
10
|
author_email="rob@lumiwealth.com",
|
|
11
11
|
description="Backtesting and Trading Library, Made by Lumiwealth",
|
|
@@ -206,6 +206,7 @@ class TestPolygonBacktestFull:
|
|
|
206
206
|
)
|
|
207
207
|
assert "fill" not in poly_strat_obj.order_time_tracker[stoploss_order_id]
|
|
208
208
|
|
|
209
|
+
@pytest.mark.apitest
|
|
209
210
|
@pytest.mark.skipif(
|
|
210
211
|
not POLYGON_API_KEY,
|
|
211
212
|
reason="This test requires a Polygon.io API key"
|
|
@@ -475,6 +476,7 @@ class TestPolygonDataSource:
|
|
|
475
476
|
assert call_strikes[-1] == expected_last, f"CALL strikes for {expected_expiry} expected last strike {expected_last}, got {call_strikes[-1]}"
|
|
476
477
|
assert put_strikes[-1] == expected_last, f"PUT strikes for {expected_expiry} expected last strike {expected_last}, got {put_strikes[-1]}"
|
|
477
478
|
|
|
479
|
+
@pytest.mark.apitest
|
|
478
480
|
@pytest.mark.skipif(not POLYGON_API_KEY or POLYGON_API_KEY == '<your key here>', reason="This test requires a Polygon.io API key")
|
|
479
481
|
def test_get_last_price_unchanged(self):
|
|
480
482
|
"""
|
|
@@ -497,6 +499,7 @@ class TestPolygonDataSource:
|
|
|
497
499
|
# Open: $129.11, Close: $128.85 at 10am Eastern -- Looked up on TradingView (DavidM)
|
|
498
500
|
assert 128.80 < last_price < 129.20, f"Expected AMZN price between 128 and 130 on 2023-08-02, got {last_price}"
|
|
499
501
|
|
|
502
|
+
@pytest.mark.apitest
|
|
500
503
|
@pytest.mark.skipif(not POLYGON_API_KEY or POLYGON_API_KEY == '<your key here>', reason="This test requires a Polygon.io API key")
|
|
501
504
|
def test_get_historical_prices_unchanged_for_amzn(self):
|
|
502
505
|
"""
|
|
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.0.19 → lumibot-4.0.20}/lumibot/backtesting/interactive_brokers_rest_backtesting.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
|
|
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.0.19 → lumibot-4.0.20}/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
|
|
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
|