Qubx 1.0.1.dev2__tar.gz → 1.0.4.dev1__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.
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/.gitignore +4 -1
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/PKG-INFO +32 -25
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/pyproject.toml +117 -90
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/_version.py +2 -2
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/cli/commands.py +13 -2
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/cli/deploy.py +55 -3
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/cli/release.py +457 -653
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/metrics.py +5 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/ta/indicators.pxd +70 -1
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/ta/indicators.pyi +36 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/ta/indicators.pyx +495 -19
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/configs.py +2 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/runner.py +11 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/time.py +1 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/LICENSE +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/README.md +0 -0
- /qubx-1.0.1.dev2/hatch_build.py → /qubx-1.0.4.dev1/scripts/build.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/_nb_magic.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/account.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/broker.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/data.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/iteratedstream.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/management.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/ome.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/optimization.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/runner.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/sentinels.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/simulated_data.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/simulated_exchange.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/simulator.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/transfers.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/backtester/utils.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/cli/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/cli/misc.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/cli/theme.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/cli/tui.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/config.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/account.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/adapters/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/adapters/polling_adapter.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/broker.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/connection_manager.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/data.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exceptions.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchange_manager.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/base.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/binance/broker.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/binance/exchange.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex_account.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/gateio/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/gateio/gateio.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/hyperliquid/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/hyperliquid/account.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/hyperliquid/broker.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/hyperliquid/hyperliquid.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/kraken/kraken.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/okx/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/okx/account.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/okx/broker.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/exchanges/okx/okx.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/factory.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/handlers/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/handlers/base.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/handlers/factory.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/handlers/funding_rate.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/handlers/liquidation.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/handlers/ohlc.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/handlers/open_interest.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/handlers/orderbook.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/handlers/quote.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/handlers/trade.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/subscription_config.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/subscription_manager.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/subscription_orchestrator.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/utils.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/ccxt/warmup_service.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/registry.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/tardis/data.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/connectors/tardis/utils.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/account.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/basics.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/context.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/detectors/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/detectors/delisting.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/detectors/stale.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/errors.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/exceptions.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/helpers.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/initializer.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/interfaces.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/loggers.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/lookups.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/mixins/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/mixins/market.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/mixins/processing.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/mixins/subscription.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/mixins/trading.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/mixins/universe.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/mixins/utils.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/series.pxd +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/series.pyi +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/series.pyx +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/utils.pyi +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/core/utils.pyx +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/cache.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/containers.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/guards.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/registry.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/storage.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/storages/ccxt.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/storages/csv.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/storages/handy.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/storages/multi.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/storages/questdb.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/storages/stub.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/storages/utils.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/data/transformers.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/emitters/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/emitters/base.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/emitters/composite.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/emitters/csv.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/emitters/indicator.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/emitters/inmemory.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/emitters/prometheus.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/emitters/questdb.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/exporters/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/exporters/composite.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/exporters/formatters/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/exporters/formatters/base.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/exporters/formatters/incremental.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/exporters/formatters/slack.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/exporters/formatters/target_position.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/exporters/redis_streams.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/exporters/slack.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/gathering/simplest.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/health/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/health/base.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/health/dummy.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/health/server.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/loggers/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/loggers/csv.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/loggers/factory.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/loggers/inmemory.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/loggers/mongo.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/notifications/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/notifications/composite.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/notifications/slack.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/notifications/throttler.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/pandaz/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/pandaz/stats.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/pandaz/ta.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/pandaz/utils.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/plugins/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/plugins/loader.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/resources/_build.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/resources/crypto-fees.ini +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/resources/instruments/hyperliquid-spot.json +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/resources/instruments/hyperliquid.f-perpetual.json +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/resources/instruments/symbols-binance-spot.json +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/resources/instruments/symbols-binance.cm-future.json +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/resources/instruments/symbols-binance.cm-perpetual.json +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/resources/instruments/symbols-binance.um-future.json +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/resources/instruments/symbols-binance.um-perpetual.json +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/resources/instruments/symbols-bitfinex.f-perpetual.json +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/resources/instruments/symbols-kraken-spot.json +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/resources/instruments/symbols-kraken.f-future.json +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/resources/instruments/symbols-kraken.f-perpetual.json +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/restarts/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/restarts/state_resolvers.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/restarts/time_finders.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/restorers/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/restorers/balance.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/restorers/factory.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/restorers/interfaces.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/restorers/position.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/restorers/signal.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/restorers/state.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/restorers/utils.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/state/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/state/dummy.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/state/redis.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/ta/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/base.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/project/accounts.toml.j2 +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/project/config.yml.j2 +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/project/jlive.sh.j2 +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/project/jpaper.sh.j2 +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/project/pyproject.toml.j2 +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/project/src/{{ strategy_name }}/__init__.py.j2 +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/project/src/{{ strategy_name }}/strategy.py.j2 +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/project/template.yml +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/simple/__init__.py.j2 +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/simple/accounts.toml.j2 +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/simple/config.yml.j2 +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/simple/jlive.sh.j2 +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/simple/jpaper.sh.j2 +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/simple/strategy.py.j2 +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/templates/simple/template.yml +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/trackers/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/trackers/advanced.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/trackers/composite.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/trackers/rebalancers.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/trackers/riskctrl.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/trackers/sizers.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/_pyxreloader.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/charting/lookinglass.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/charting/mpl_helpers.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/charting/orderbook.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/collections.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/hft/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/hft/numba_utils.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/hft/orderbook.pyi +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/hft/orderbook.pyx +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/marketdata/binance.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/marketdata/ccxt.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/marketdata/dukas.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/misc.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/nonce.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/ntp.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/numbers_utils.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/orderbook.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/plotting/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/plotting/dashboard.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/plotting/data.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/plotting/interfaces.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/plotting/renderers/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/plotting/renderers/plotly.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/questdb.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/rate_limiter.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/results.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/ringbuffer.pxd +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/ringbuffer.pyi +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/ringbuffer.pyx +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/_jupyter_runner.pyt +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/accounts.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/factory.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/kernel_service.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/textual/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/textual/app.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/textual/handlers.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/textual/init_code.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/textual/kernel.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/textual/styles.tcss +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/textual/widgets/__init__.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/textual/widgets/command_input.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/textual/widgets/debug_log.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/textual/widgets/orders_table.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/textual/widgets/positions_table.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/textual/widgets/quotes_table.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/runner/textual/widgets/repl_output.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/slack.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/throttler.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/src/qubx/utils/websocket_manager.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/tests/strategies/macd_crossover/src/macd_crossover/indicators/macd.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/tests/strategies/macd_crossover/src/macd_crossover/models/macd_crossover.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/tests/strategies/macd_crossover/src/macd_crossover/models/utils.py +0 -0
- {qubx-1.0.1.dev2 → qubx-1.0.4.dev1}/tests/strategies/obi_trader/src/obi_trader/models/obi_trader.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Qubx
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4.dev1
|
|
4
4
|
Summary: Qubx - Quantitative Trading Framework
|
|
5
5
|
Project-URL: homepage, https://xlydian.com
|
|
6
6
|
Project-URL: repository, https://github.com/xLydianSoftware/Qubx
|
|
@@ -9,57 +9,64 @@ Author-email: Dmitry Marienko <dmitry.marienko@xlydian.com>, Yuriy Arabskyy <yur
|
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Requires-Python: <4.0,>=3.12
|
|
11
11
|
Requires-Dist: aiohttp<3.11,>=3.10.11
|
|
12
|
-
Requires-Dist:
|
|
12
|
+
Requires-Dist: click<9,>=8.1.7
|
|
13
13
|
Requires-Dist: croniter<3,>=2.0.5
|
|
14
|
-
Requires-Dist: cython==3.0.8
|
|
15
|
-
Requires-Dist: dash-bootstrap-components<2,>=1.6.0
|
|
16
|
-
Requires-Dist: dash<3,>=2.18.2
|
|
17
14
|
Requires-Dist: gitpython<4,>=3.1.44
|
|
18
15
|
Requires-Dist: importlib-metadata
|
|
19
|
-
Requires-Dist: ipywidgets<9,>=8.1.5
|
|
20
16
|
Requires-Dist: jinja2<4,>=3.1.0
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist: jupyter<2,>=1.1.1
|
|
17
|
+
Requires-Dist: joblib<2,>=1.3.0
|
|
23
18
|
Requires-Dist: loguru<1,>=0.7.2
|
|
24
|
-
Requires-Dist: matplotlib<4,>=3.8.4
|
|
25
19
|
Requires-Dist: msgspec<1,>=0.18.6
|
|
26
20
|
Requires-Dist: ntplib<1,>=0.4.0
|
|
27
21
|
Requires-Dist: numba<1,>=0.59.1
|
|
28
22
|
Requires-Dist: numpy>=1.26.3
|
|
29
23
|
Requires-Dist: orjson<4,>=3.10.15
|
|
30
24
|
Requires-Dist: pandas<3,>=2.2.2
|
|
31
|
-
Requires-Dist: plotly<6,>=5.22.0
|
|
32
|
-
Requires-Dist: psycopg-binary<4,>=3.1.19
|
|
33
|
-
Requires-Dist: psycopg-pool<4,>=3.2.2
|
|
34
|
-
Requires-Dist: psycopg<4,>=3.1.18
|
|
35
25
|
Requires-Dist: pyarrow>=15.0.0
|
|
36
26
|
Requires-Dist: pydantic-settings<3,>=2.4.0
|
|
37
27
|
Requires-Dist: pydantic<3,>=2.9.2
|
|
38
|
-
Requires-Dist: pymongo<5,>=4.6.1
|
|
39
|
-
Requires-Dist: python-binance<2,>=1.0.19
|
|
40
28
|
Requires-Dist: python-dotenv<2,>=1.0.0
|
|
41
29
|
Requires-Dist: pyyaml<7,>=6.0.2
|
|
42
|
-
Requires-Dist: qubx-bitfinex-api<4,>=3.0.7
|
|
43
|
-
Requires-Dist: questdb<3,>=2.0.3
|
|
44
|
-
Requires-Dist: redis<6,>=5.2.1
|
|
45
30
|
Requires-Dist: rich<14,>=13.9.4
|
|
46
|
-
Requires-Dist: scikit-learn>=1.8.0
|
|
47
31
|
Requires-Dist: scipy<2,>=1.12.0
|
|
48
32
|
Requires-Dist: sortedcontainers<3,>=2.4.0
|
|
49
33
|
Requires-Dist: stackprinter<1,>=0.2.10
|
|
50
34
|
Requires-Dist: statsmodels<1,>=0.14.6
|
|
51
35
|
Requires-Dist: tabulate<1,>=0.9.0
|
|
52
|
-
Requires-Dist: textual-autocomplete<5,>=4.0.0
|
|
53
|
-
Requires-Dist: textual-serve<2,>=1.0.0
|
|
54
|
-
Requires-Dist: textual[syntax]<7,>=6.0.0
|
|
55
36
|
Requires-Dist: toml<1,>=0.10.2
|
|
56
|
-
Requires-Dist: tqdm
|
|
37
|
+
Requires-Dist: tqdm<5,>=4.66.0
|
|
57
38
|
Requires-Dist: uvloop<1,>=0.22.1; sys_platform != 'win32'
|
|
58
39
|
Requires-Dist: websockets==15.0.1
|
|
40
|
+
Provides-Extra: binance
|
|
41
|
+
Requires-Dist: python-binance<2,>=1.0.19; extra == 'binance'
|
|
42
|
+
Provides-Extra: bitfinex
|
|
43
|
+
Requires-Dist: qubx-bitfinex-api<4,>=3.0.7; extra == 'bitfinex'
|
|
44
|
+
Provides-Extra: connectors
|
|
45
|
+
Requires-Dist: ccxt<5,>=4.2.68; extra == 'connectors'
|
|
46
|
+
Provides-Extra: db
|
|
47
|
+
Requires-Dist: duckdb>=1.0.0; extra == 'db'
|
|
48
|
+
Requires-Dist: psycopg-binary<4,>=3.1.19; extra == 'db'
|
|
49
|
+
Requires-Dist: psycopg-pool<4,>=3.2.2; extra == 'db'
|
|
50
|
+
Requires-Dist: psycopg<4,>=3.1.18; extra == 'db'
|
|
51
|
+
Requires-Dist: pymongo<5,>=4.6.1; extra == 'db'
|
|
52
|
+
Requires-Dist: questdb<3,>=2.0.3; extra == 'db'
|
|
53
|
+
Requires-Dist: redis<6,>=5.2.1; extra == 'db'
|
|
54
|
+
Provides-Extra: jupyter
|
|
55
|
+
Requires-Dist: ipywidgets<9,>=8.1.5; extra == 'jupyter'
|
|
56
|
+
Requires-Dist: jupyter-console<7,>=6.6.3; extra == 'jupyter'
|
|
57
|
+
Requires-Dist: jupyter<2,>=1.1.1; extra == 'jupyter'
|
|
59
58
|
Provides-Extra: k8
|
|
59
|
+
Requires-Dist: boto3<2,>=1.34.0; extra == 'k8'
|
|
60
60
|
Requires-Dist: prometheus-client<1,>=0.21.1; extra == 'k8'
|
|
61
|
-
Provides-Extra:
|
|
62
|
-
Requires-Dist:
|
|
61
|
+
Provides-Extra: tui
|
|
62
|
+
Requires-Dist: textual-autocomplete<5,>=4.0.0; extra == 'tui'
|
|
63
|
+
Requires-Dist: textual-serve<2,>=1.0.0; extra == 'tui'
|
|
64
|
+
Requires-Dist: textual[syntax]<7,>=6.0.0; extra == 'tui'
|
|
65
|
+
Provides-Extra: viz
|
|
66
|
+
Requires-Dist: dash-bootstrap-components<2,>=1.6.0; extra == 'viz'
|
|
67
|
+
Requires-Dist: dash<3,>=2.18.2; extra == 'viz'
|
|
68
|
+
Requires-Dist: matplotlib<4,>=3.8.4; extra == 'viz'
|
|
69
|
+
Requires-Dist: plotly<6,>=5.22.0; extra == 'viz'
|
|
63
70
|
Description-Content-Type: text/markdown
|
|
64
71
|
|
|
65
72
|
# Qubx - Quantitative Trading Framework
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# PROJECT METADATA
|
|
3
|
+
# ============================================================
|
|
1
4
|
[project]
|
|
2
5
|
name = "Qubx"
|
|
3
6
|
dynamic = ["version"]
|
|
@@ -9,54 +12,40 @@ authors = [
|
|
|
9
12
|
readme = "README.md"
|
|
10
13
|
requires-python = ">=3.12,<4.0"
|
|
11
14
|
dependencies = [
|
|
15
|
+
# Data & numerics
|
|
12
16
|
"numpy>=1.26.3",
|
|
13
17
|
"pandas>=2.2.2,<3",
|
|
14
18
|
"pyarrow>=15.0.0",
|
|
15
19
|
"scipy>=1.12.0,<2",
|
|
16
|
-
"scikit-learn>=1.8.0",
|
|
17
|
-
"statsmodels>=0.14.6,<1",
|
|
18
20
|
"numba>=0.59.1,<1",
|
|
19
21
|
"sortedcontainers>=2.4.0,<3",
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
"ccxt>=4.2.68,<5",
|
|
23
|
-
"pymongo>=4.6.1,<5",
|
|
24
|
-
"redis>=5.2.1,<6",
|
|
25
|
-
"psycopg>=3.1.18,<4",
|
|
26
|
-
"psycopg-binary>=3.1.19,<4",
|
|
27
|
-
"psycopg-pool>=3.2.2,<4",
|
|
28
|
-
"matplotlib>=3.8.4,<4",
|
|
29
|
-
"plotly>=5.22.0,<6",
|
|
30
|
-
"dash>=2.18.2,<3",
|
|
31
|
-
"dash-bootstrap-components>=1.6.0,<2",
|
|
22
|
+
"joblib>=1.3.0,<2",
|
|
23
|
+
# Logging & diagnostics
|
|
32
24
|
"loguru>=0.7.2,<1",
|
|
33
|
-
"tqdm",
|
|
34
|
-
"importlib-metadata",
|
|
25
|
+
"tqdm>=4.66.0,<5",
|
|
35
26
|
"stackprinter>=0.2.10,<1",
|
|
27
|
+
# Config & serialization
|
|
36
28
|
"pydantic>=2.9.2,<3",
|
|
37
29
|
"pydantic-settings>=2.4.0,<3",
|
|
38
30
|
"python-dotenv>=1.0.0,<2",
|
|
39
|
-
"cython==3.0.8",
|
|
40
|
-
"croniter>=2.0.5,<3",
|
|
41
31
|
"msgspec>=0.18.6,<1",
|
|
42
32
|
"pyyaml>=6.0.2,<7",
|
|
43
|
-
"tabulate>=0.9.0,<1",
|
|
44
33
|
"toml>=0.10.2,<1",
|
|
45
|
-
"gitpython>=3.1.44,<4",
|
|
46
|
-
"jupyter>=1.1.1,<2",
|
|
47
|
-
"jupyter-console>=6.6.3,<7",
|
|
48
|
-
"ipywidgets>=8.1.5,<9",
|
|
49
|
-
"questdb>=2.0.3,<3",
|
|
50
34
|
"orjson>=3.10.15,<4",
|
|
35
|
+
# Networking & async
|
|
51
36
|
"aiohttp>=3.10.11,<3.11",
|
|
52
37
|
"websockets==15.0.1",
|
|
53
|
-
"qubx-bitfinex-api>=3.0.7,<4",
|
|
54
|
-
"textual-autocomplete>=4.0.0,<5",
|
|
55
|
-
"textual-serve>=1.0.0,<2",
|
|
56
|
-
"rich>=13.9.4,<14",
|
|
57
|
-
"jinja2>=3.1.0,<4",
|
|
58
38
|
"uvloop>=0.22.1,<1; sys_platform != 'win32'",
|
|
59
|
-
|
|
39
|
+
# Utilities
|
|
40
|
+
"importlib-metadata",
|
|
41
|
+
"croniter>=2.0.5,<3",
|
|
42
|
+
"tabulate>=0.9.0,<1",
|
|
43
|
+
"gitpython>=3.1.44,<4",
|
|
44
|
+
"ntplib>=0.4.0,<1",
|
|
45
|
+
"jinja2>=3.1.0,<4",
|
|
46
|
+
"rich>=13.9.4,<14",
|
|
47
|
+
"click>=8.1.7,<9",
|
|
48
|
+
"statsmodels>=0.14.6,<1",
|
|
60
49
|
]
|
|
61
50
|
|
|
62
51
|
[project.urls]
|
|
@@ -64,15 +53,57 @@ homepage = "https://xlydian.com"
|
|
|
64
53
|
repository = "https://github.com/xLydianSoftware/Qubx"
|
|
65
54
|
docs = "https://xlydiansoftware.github.io/Qubx"
|
|
66
55
|
|
|
67
|
-
[project.optional-dependencies]
|
|
68
|
-
# Runtime optional features only (shipped with package)
|
|
69
|
-
k8 = ["prometheus-client>=0.21.1,<1"]
|
|
70
|
-
# Parquet-based backtest storage with DuckDB search and cloud (S3/GCS/Azure) support
|
|
71
|
-
storage = ["duckdb>=1.0.0"]
|
|
72
|
-
|
|
73
56
|
[project.scripts]
|
|
74
57
|
qubx = "qubx.cli.commands:main"
|
|
75
58
|
|
|
59
|
+
# ============================================================
|
|
60
|
+
# OPTIONAL DEPENDENCIES (`pip install qubx[connectors,db,...]`)
|
|
61
|
+
# ============================================================
|
|
62
|
+
[project.optional-dependencies]
|
|
63
|
+
# Exchange connectors (ccxt-based)
|
|
64
|
+
connectors = ["ccxt>=4.2.68,<5"]
|
|
65
|
+
# Binance-specific (historical data utilities)
|
|
66
|
+
binance = ["python-binance>=1.0.19,<2"]
|
|
67
|
+
# Bitfinex-specific (custom API client)
|
|
68
|
+
bitfinex = ["qubx-bitfinex-api>=3.0.7,<4"]
|
|
69
|
+
# Database backends (MongoDB, Redis, PostgreSQL/QuestDB, DuckDB)
|
|
70
|
+
db = [
|
|
71
|
+
"pymongo>=4.6.1,<5",
|
|
72
|
+
"redis>=5.2.1,<6",
|
|
73
|
+
"psycopg>=3.1.18,<4",
|
|
74
|
+
"psycopg-binary>=3.1.19,<4",
|
|
75
|
+
"psycopg-pool>=3.2.2,<4",
|
|
76
|
+
"questdb>=2.0.3,<3",
|
|
77
|
+
"duckdb>=1.0.0",
|
|
78
|
+
]
|
|
79
|
+
# Visualization & charting
|
|
80
|
+
viz = [
|
|
81
|
+
"matplotlib>=3.8.4,<4",
|
|
82
|
+
"plotly>=5.22.0,<6",
|
|
83
|
+
"dash>=2.18.2,<3",
|
|
84
|
+
"dash-bootstrap-components>=1.6.0,<2",
|
|
85
|
+
]
|
|
86
|
+
# Terminal UI (textual TUI, browse command)
|
|
87
|
+
tui = [
|
|
88
|
+
"textual[syntax]>=6.0.0,<7",
|
|
89
|
+
"textual-autocomplete>=4.0.0,<5",
|
|
90
|
+
"textual-serve>=1.0.0,<2",
|
|
91
|
+
]
|
|
92
|
+
# Jupyter integration
|
|
93
|
+
jupyter = [
|
|
94
|
+
"jupyter>=1.1.1,<2",
|
|
95
|
+
"jupyter-console>=6.6.3,<7",
|
|
96
|
+
"ipywidgets>=8.1.5,<9",
|
|
97
|
+
]
|
|
98
|
+
# Kubernetes / production monitoring
|
|
99
|
+
k8 = [
|
|
100
|
+
"prometheus-client>=0.21.1,<1",
|
|
101
|
+
"boto3>=1.34.0,<2",
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
# ============================================================
|
|
105
|
+
# BUILD SYSTEM
|
|
106
|
+
# ============================================================
|
|
76
107
|
[build-system]
|
|
77
108
|
requires = [
|
|
78
109
|
"hatchling>=1.21.0",
|
|
@@ -84,7 +115,6 @@ requires = [
|
|
|
84
115
|
]
|
|
85
116
|
build-backend = "hatchling.build"
|
|
86
117
|
|
|
87
|
-
# Hatch version configuration - tag-driven via VCS
|
|
88
118
|
[tool.hatch.version]
|
|
89
119
|
source = "vcs"
|
|
90
120
|
|
|
@@ -95,36 +125,67 @@ local_scheme = "no-local-version"
|
|
|
95
125
|
[tool.hatch.build.hooks.vcs]
|
|
96
126
|
version-file = "src/qubx/_version.py"
|
|
97
127
|
|
|
98
|
-
# Hatch build configuration
|
|
99
128
|
[tool.hatch.build]
|
|
100
129
|
packages = ["src/qubx"]
|
|
101
|
-
|
|
102
|
-
artifacts = [
|
|
103
|
-
"src/qubx/**/*.so",
|
|
104
|
-
"src/qubx/**/*.pyd",
|
|
105
|
-
]
|
|
130
|
+
artifacts = ["src/qubx/**/*.so", "src/qubx/**/*.pyd"]
|
|
106
131
|
|
|
107
132
|
[tool.hatch.build.targets.sdist]
|
|
108
|
-
include = [
|
|
109
|
-
"src/",
|
|
110
|
-
"hatch_build.py",
|
|
111
|
-
]
|
|
133
|
+
include = ["src/", "scripts/build.py"]
|
|
112
134
|
exclude = ["**/__pycache__", "**/*.so", "**/*.pyd", "**/*.c"]
|
|
113
|
-
# Don't relocate - keep src/ layout in sdist
|
|
114
135
|
packages = []
|
|
115
136
|
|
|
116
137
|
[tool.hatch.build.targets.wheel]
|
|
117
138
|
packages = ["src/qubx"]
|
|
118
|
-
|
|
119
|
-
artifacts = [
|
|
120
|
-
"src/qubx/**/*.so",
|
|
121
|
-
"src/qubx/**/*.pyd",
|
|
122
|
-
]
|
|
139
|
+
artifacts = ["src/qubx/**/*.so", "src/qubx/**/*.pyd"]
|
|
123
140
|
|
|
124
|
-
# Custom build hook for Cython compilation and platform-specific wheel tags
|
|
125
141
|
[tool.hatch.build.targets.wheel.hooks.custom]
|
|
126
|
-
path = "
|
|
142
|
+
path = "scripts/build.py"
|
|
127
143
|
|
|
144
|
+
# ============================================================
|
|
145
|
+
# DEV DEPENDENCIES (installed with `uv sync`, not shipped)
|
|
146
|
+
# Use `uv sync --all-extras` or `just install` for full dev setup
|
|
147
|
+
# ============================================================
|
|
148
|
+
[dependency-groups]
|
|
149
|
+
dev = [
|
|
150
|
+
# Testing
|
|
151
|
+
"pytest>=8.2.0,<9",
|
|
152
|
+
"pytest-asyncio>=0.24.0,<1",
|
|
153
|
+
"pytest-mock>=3.12.0,<4",
|
|
154
|
+
"pytest-lazy-fixture>=0.6.3,<1",
|
|
155
|
+
"pytest-cov>=4.1.0,<5",
|
|
156
|
+
"pytest-xdist>=3.6.1,<4",
|
|
157
|
+
"pytest-textual-snapshot>=1.1.0,<2",
|
|
158
|
+
"mongomock>=4.3.0,<5",
|
|
159
|
+
# Linting & formatting
|
|
160
|
+
"ruff>=0.9.7,<1",
|
|
161
|
+
"pre-commit>=2.20.0,<3",
|
|
162
|
+
# Debugging & profiling
|
|
163
|
+
"debugpy>=1.8.12,<2",
|
|
164
|
+
"py-spy>=0.4.1,<1",
|
|
165
|
+
# Jupyter / notebooks
|
|
166
|
+
"ipykernel>=6.29.4,<7",
|
|
167
|
+
"iprogress>=0.4,<1",
|
|
168
|
+
"nbformat>=5.10.4,<6",
|
|
169
|
+
# Documentation
|
|
170
|
+
"markdown==3.7",
|
|
171
|
+
"mkdocs==1.6.1",
|
|
172
|
+
"mkdocs-material==9.6.5",
|
|
173
|
+
"mdx-truly-sane-lists==1.3",
|
|
174
|
+
"pymdown-extensions==10.14.3",
|
|
175
|
+
"jinja2==3.1.5",
|
|
176
|
+
"mike==2.1.3",
|
|
177
|
+
"mkdocs-jupyter==0.25.1",
|
|
178
|
+
# Build tooling
|
|
179
|
+
"cython==3.0.8",
|
|
180
|
+
# Release tooling
|
|
181
|
+
"rust-just>=1.36.0,<2",
|
|
182
|
+
"twine>=5.1.1,<6",
|
|
183
|
+
"git-cliff>=2.0.0",
|
|
184
|
+
]
|
|
185
|
+
|
|
186
|
+
# ============================================================
|
|
187
|
+
# TOOL CONFIGURATION
|
|
188
|
+
# ============================================================
|
|
128
189
|
[tool.ruff]
|
|
129
190
|
line-length = 120
|
|
130
191
|
|
|
@@ -133,7 +194,7 @@ extend-select = ["I"]
|
|
|
133
194
|
ignore = ["E731", "E722", "E741"]
|
|
134
195
|
|
|
135
196
|
[tool.ruff.lint.extend-per-file-ignores]
|
|
136
|
-
"*.ipynb" = [
|
|
197
|
+
"*.ipynb" = ["F405", "F401", "E701", "E402", "F403", "E401", "E702", "F821", "E731", "I001"]
|
|
137
198
|
|
|
138
199
|
[tool.pytest.ini_options]
|
|
139
200
|
asyncio_mode = "auto"
|
|
@@ -148,37 +209,3 @@ filterwarnings = [
|
|
|
148
209
|
"ignore:.*Jupyter is migrating.*:DeprecationWarning",
|
|
149
210
|
"ignore:coroutine.*AsyncMockMixin._execute_mock_call.*was never awaited:RuntimeWarning",
|
|
150
211
|
]
|
|
151
|
-
|
|
152
|
-
[dependency-groups]
|
|
153
|
-
# Dev/test tools (not shipped with package, only for local development)
|
|
154
|
-
dev = [
|
|
155
|
-
"pre-commit>=2.20.0,<3",
|
|
156
|
-
"rust-just>=1.36.0,<2",
|
|
157
|
-
"twine>=5.1.1,<6",
|
|
158
|
-
"ipykernel>=6.29.4,<7",
|
|
159
|
-
"iprogress>=0.4,<1",
|
|
160
|
-
"click>=8.1.7,<9",
|
|
161
|
-
"ipywidgets>=8.1.5,<9",
|
|
162
|
-
"ruff>=0.9.7,<1",
|
|
163
|
-
"pytest-xdist>=3.6.1,<4",
|
|
164
|
-
"nbformat>=5.10.4,<6",
|
|
165
|
-
"markdown==3.7",
|
|
166
|
-
"mkdocs==1.6.1",
|
|
167
|
-
"mkdocs-material==9.6.5",
|
|
168
|
-
"mdx-truly-sane-lists==1.3",
|
|
169
|
-
"pymdown-extensions==10.14.3",
|
|
170
|
-
"jinja2==3.1.5",
|
|
171
|
-
"mike==2.1.3",
|
|
172
|
-
"mkdocs-jupyter==0.25.1",
|
|
173
|
-
"debugpy>=1.8.12,<2",
|
|
174
|
-
"py-spy>=0.4.1,<1",
|
|
175
|
-
"pytest>=8.2.0,<9",
|
|
176
|
-
"pytest-asyncio>=0.24.0,<1",
|
|
177
|
-
"pytest-mock>=3.12.0,<4",
|
|
178
|
-
"pytest-lazy-fixture>=0.6.3,<1",
|
|
179
|
-
"pytest-cov>=4.1.0,<5",
|
|
180
|
-
"mongomock>=4.3.0,<5",
|
|
181
|
-
"pytest-textual-snapshot>=1.1.0,<2",
|
|
182
|
-
"git-cliff>=2.0.0",
|
|
183
|
-
"duckdb>=1.0.0",
|
|
184
|
-
]
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.0.
|
|
32
|
-
__version_tuple__ = version_tuple = (1, 0,
|
|
31
|
+
__version__ = version = '1.0.4.dev1'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 0, 4, 'dev1')
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -433,7 +433,14 @@ def release(
|
|
|
433
433
|
help="Force overwrite if the output directory already exists.",
|
|
434
434
|
show_default=True,
|
|
435
435
|
)
|
|
436
|
-
|
|
436
|
+
@click.option(
|
|
437
|
+
"--system",
|
|
438
|
+
is_flag=True,
|
|
439
|
+
default=False,
|
|
440
|
+
help="Install wheels into system site-packages (Docker mode, no venv/uv needed).",
|
|
441
|
+
show_default=True,
|
|
442
|
+
)
|
|
443
|
+
def deploy(zip_file: str, output_dir: str | None, force: bool, system: bool):
|
|
437
444
|
"""
|
|
438
445
|
Deploys a strategy from a zip file created by the release command.
|
|
439
446
|
|
|
@@ -442,6 +449,10 @@ def deploy(zip_file: str, output_dir: str | None, force: bool):
|
|
|
442
449
|
2. Auto-detects the package manager (uv or legacy poetry) from the lock file
|
|
443
450
|
3. Creates a virtual environment and installs dependencies
|
|
444
451
|
|
|
452
|
+
With --system flag (Docker mode):
|
|
453
|
+
- Installs wheels directly into system site-packages via pip
|
|
454
|
+
- No virtual environment or uv needed
|
|
455
|
+
|
|
445
456
|
Supports both uv-based releases (uv.lock) and legacy Poetry-based releases (poetry.lock).
|
|
446
457
|
|
|
447
458
|
If no output directory is specified, the zip file is unpacked in the same directory
|
|
@@ -449,7 +460,7 @@ def deploy(zip_file: str, output_dir: str | None, force: bool):
|
|
|
449
460
|
"""
|
|
450
461
|
from .deploy import deploy_strategy
|
|
451
462
|
|
|
452
|
-
deploy_strategy(zip_file, output_dir, force)
|
|
463
|
+
deploy_strategy(zip_file, output_dir, force, system=system)
|
|
453
464
|
|
|
454
465
|
|
|
455
466
|
@main.command()
|
|
@@ -275,21 +275,65 @@ def create_strategy_runners(output_dir: str, pkg_manager: str = "uv"):
|
|
|
275
275
|
logger.error(f"Failed to create strategy paper runner script: {e}")
|
|
276
276
|
|
|
277
277
|
|
|
278
|
-
def
|
|
278
|
+
def install_system_wheels(output_dir: str) -> bool:
|
|
279
|
+
"""
|
|
280
|
+
Install all wheels from wheels/ directory into system site-packages.
|
|
281
|
+
|
|
282
|
+
This is the Docker deployment path: no venv, no uv, just pip install.
|
|
283
|
+
|
|
284
|
+
Args:
|
|
285
|
+
output_dir: Directory containing the extracted release (with wheels/ subdirectory)
|
|
286
|
+
|
|
287
|
+
Returns:
|
|
288
|
+
bool: True if successful, False otherwise
|
|
289
|
+
"""
|
|
290
|
+
wheels_dir = os.path.join(output_dir, "wheels")
|
|
291
|
+
if not os.path.isdir(wheels_dir):
|
|
292
|
+
logger.warning("No wheels/ directory found — skipping system wheel install")
|
|
293
|
+
return True
|
|
294
|
+
|
|
295
|
+
wheel_files = [os.path.join(wheels_dir, f) for f in os.listdir(wheels_dir) if f.endswith(".whl")]
|
|
296
|
+
if not wheel_files:
|
|
297
|
+
logger.warning("No .whl files found in wheels/ — skipping system wheel install")
|
|
298
|
+
return True
|
|
299
|
+
|
|
300
|
+
logger.info(f"Installing {len(wheel_files)} wheel(s) into system site-packages...")
|
|
301
|
+
pip_exe = shutil.which("pip") or shutil.which("pip3")
|
|
302
|
+
if not pip_exe:
|
|
303
|
+
logger.error("pip not found — cannot install wheels into system site-packages")
|
|
304
|
+
return False
|
|
305
|
+
|
|
306
|
+
try:
|
|
307
|
+
subprocess.run(
|
|
308
|
+
[pip_exe, "install", *wheel_files],
|
|
309
|
+
check=True,
|
|
310
|
+
capture_output=False,
|
|
311
|
+
text=True,
|
|
312
|
+
)
|
|
313
|
+
logger.info("System wheel install complete")
|
|
314
|
+
return True
|
|
315
|
+
except subprocess.CalledProcessError as e:
|
|
316
|
+
logger.error(f"Failed to install wheels: {e}")
|
|
317
|
+
return False
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def deploy_strategy(zip_file: str, output_dir: str | None, force: bool, system: bool = False) -> bool:
|
|
279
321
|
"""
|
|
280
322
|
Deploys a strategy from a zip file created by the release command.
|
|
281
323
|
|
|
282
324
|
This function:
|
|
283
325
|
1. Unpacks the zip file to the specified output directory
|
|
284
326
|
2. Auto-detects the package manager (uv or poetry) based on the lock file
|
|
285
|
-
3. Creates a virtual environment and installs dependencies
|
|
327
|
+
3. Creates a virtual environment and installs dependencies (default)
|
|
328
|
+
OR installs wheels into system site-packages (--system mode for Docker)
|
|
286
329
|
|
|
287
|
-
Supports both
|
|
330
|
+
Supports both uv-based releases, legacy Poetry-based releases, and system mode.
|
|
288
331
|
|
|
289
332
|
Args:
|
|
290
333
|
zip_file: Path to the zip file to deploy
|
|
291
334
|
output_dir: Output directory to unpack the zip file. If None, uses the directory containing the zip file.
|
|
292
335
|
force: Whether to force overwrite if the output directory already exists
|
|
336
|
+
system: If True, install wheels directly into system site-packages (Docker mode)
|
|
293
337
|
|
|
294
338
|
Returns:
|
|
295
339
|
bool: True if deployment was successful, False otherwise
|
|
@@ -309,6 +353,14 @@ def deploy_strategy(zip_file: str, output_dir: str | None, force: bool) -> bool:
|
|
|
309
353
|
if not extract_zip_file(zip_file, resolved_output_dir):
|
|
310
354
|
return False
|
|
311
355
|
|
|
356
|
+
if system:
|
|
357
|
+
# Docker path: pip install wheels directly into system site-packages
|
|
358
|
+
if not install_system_wheels(resolved_output_dir):
|
|
359
|
+
return False
|
|
360
|
+
logger.info(f"Strategy deployed (system mode) to {resolved_output_dir}")
|
|
361
|
+
return True
|
|
362
|
+
|
|
363
|
+
# Default path: venv-based install
|
|
312
364
|
# Detect package manager
|
|
313
365
|
pkg_manager = _detect_package_manager(resolved_output_dir)
|
|
314
366
|
logger.info(f"Detected package manager: {pkg_manager}")
|