Qubx 1.1.3.dev23__tar.gz → 1.1.3.dev24__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.1.3.dev23 → qubx-1.1.3.dev24}/PKG-INFO +1 -1
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/_version.py +2 -2
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/cli/commands.py +118 -42
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/cli/release.py +100 -61
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/.gitignore +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/LICENSE +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/README.md +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/pyproject.toml +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/scripts/build.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/_nb_magic.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/account.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/broker.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/data.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/iteratedstream.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/management.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/ome.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/optimization.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/runner.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/sentinels.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/simulated_data.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/simulated_exchange.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/simulator.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/transfers.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/backtester/utils.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/cli/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/cli/deploy.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/cli/misc.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/cli/resolver.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/cli/s3.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/cli/theme.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/cli/tui.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/cli/user_config.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/config.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/account.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/adapters/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/adapters/polling_adapter.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/broker.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/connection_manager.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/data.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exceptions.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchange_manager.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/base.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/binance/broker.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/binance/exchange.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex_account.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/gateio/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/gateio/gateio.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/hyperliquid/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/hyperliquid/account.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/hyperliquid/broker.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/hyperliquid/hyperliquid.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/kraken/kraken.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/okx/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/okx/account.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/okx/broker.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/okx/okx.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/factory.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/handlers/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/handlers/base.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/handlers/factory.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/handlers/funding_rate.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/handlers/liquidation.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/handlers/ohlc.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/handlers/open_interest.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/handlers/orderbook.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/handlers/quote.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/handlers/trade.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/rate_limits.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/subscription_config.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/subscription_manager.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/subscription_orchestrator.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/utils.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/warmup_service.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/registry.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/tardis/data.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/tardis/utils.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/control/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/control/builtin.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/control/decorator.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/control/executor.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/control/interfaces.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/control/server.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/control/types.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/account.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/basics.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/context.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/detectors/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/detectors/delisting.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/detectors/stale.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/errors.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/exceptions.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/helpers.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/initializer.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/interfaces.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/loggers.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/lookups.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/metrics.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/mixins/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/mixins/market.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/mixins/processing.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/mixins/subscription.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/mixins/trading.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/mixins/universe.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/mixins/utils.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/series.pxd +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/series.pyi +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/series.pyx +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/utils.pyi +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/core/utils.pyx +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/cache.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/containers.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/guards.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/registry.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/storage.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/storages/ccxt.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/storages/csv.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/storages/handy.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/storages/multi.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/storages/questdb.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/storages/stub.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/storages/utils.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/data/transformers.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/emitters/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/emitters/base.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/emitters/composite.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/emitters/csv.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/emitters/indicator.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/emitters/inmemory.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/emitters/prometheus.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/emitters/questdb.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/exporters/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/exporters/composite.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/exporters/formatters/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/exporters/formatters/base.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/exporters/formatters/incremental.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/exporters/formatters/slack.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/exporters/formatters/target_position.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/exporters/redis_streams.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/exporters/slack.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/gathering/simplest.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/health/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/health/base.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/health/dummy.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/loggers/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/loggers/csv.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/loggers/factory.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/loggers/inmemory.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/loggers/mongo.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/loggers/postgres.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/notifications/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/notifications/composite.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/notifications/slack.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/notifications/throttler.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/pandaz/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/pandaz/stats.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/pandaz/ta.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/pandaz/utils.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/plugins/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/plugins/loader.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/rate_limiting/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/rate_limiting/backend.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/rate_limiting/config.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/rate_limiting/engine.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/rate_limiting/ip_resolver.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/rate_limiting/manager.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/rate_limiting/redis_backend.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/resources/_build.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/resources/crypto-fees.ini +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/resources/instruments/hyperliquid-spot.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/resources/instruments/hyperliquid.f-perpetual.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/resources/instruments/symbols-binance-spot.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/resources/instruments/symbols-binance.cm-future.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/resources/instruments/symbols-binance.cm-perpetual.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/resources/instruments/symbols-binance.um-future.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/resources/instruments/symbols-binance.um-perpetual.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/resources/instruments/symbols-bitfinex.f-perpetual.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/resources/instruments/symbols-kraken-spot.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/resources/instruments/symbols-kraken.f-future.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/resources/instruments/symbols-kraken.f-perpetual.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/restarts/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/restarts/state_resolvers.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/restarts/time_finders.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/restorers/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/restorers/balance.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/restorers/factory.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/restorers/interfaces.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/restorers/position.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/restorers/signal.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/restorers/state.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/restorers/utils.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/state/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/state/dummy.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/state/redis.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/ta/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/ta/indicators.pxd +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/ta/indicators.pyi +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/ta/indicators.pyx +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/base.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/project/accounts.toml.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/project/config.yml.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/project/jlive.sh.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/project/jpaper.sh.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/project/pyproject.toml.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/project/src/{{ strategy_name }}/__init__.py.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/project/src/{{ strategy_name }}/strategy.py.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/project/template.yml +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/.claude/skills/qubx-cli/SKILL.md +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/.claude/skills/qubx-indicators/SKILL.md +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/.claude/skills/simulation-explorer/SKILL.md +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/.claude/skills/strategy-release/SKILL.md +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/.github/workflows/ci.yml.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/.gitignore.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/.python-version +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/.vscode/launch.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/.vscode/settings.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/.vscode/tasks.json +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/CLAUDE.md.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/README.md.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/configs/.gitkeep +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/justfile.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/pyproject.toml.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/research/.gitkeep +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/src/{{ strategy_name }}/__init__.py.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/src/{{ strategy_name }}/cli.py.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/src/{{ strategy_name }}/strategy.py.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/template.yml +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/repo/tests/test_strategy.py.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/simple/__init__.py.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/simple/accounts.toml.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/simple/config.yml.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/simple/jlive.sh.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/simple/jpaper.sh.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/simple/strategy.py.j2 +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/templates/simple/template.yml +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/trackers/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/trackers/advanced.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/trackers/composite.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/trackers/rebalancers.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/trackers/riskctrl.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/trackers/sizers.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/_pyxreloader.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/charting/lookinglass.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/charting/mpl_helpers.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/charting/orderbook.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/collections.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/hft/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/hft/numba_utils.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/hft/orderbook.pyi +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/hft/orderbook.pyx +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/marketdata/binance.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/marketdata/ccxt.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/marketdata/dukas.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/misc.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/nonce.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/ntp.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/numbers_utils.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/orderbook.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/plotting/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/plotting/dashboard.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/plotting/data.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/plotting/interfaces.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/plotting/renderers/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/plotting/renderers/plotly.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/questdb.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/rate_limiter.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/results.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/ringbuffer.pxd +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/ringbuffer.pyi +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/ringbuffer.pyx +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/_jupyter_runner.pyt +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/accounts.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/configs.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/factory.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/kernel_service.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/runner.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/app.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/handlers.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/init_code.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/kernel.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/styles.tcss +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/widgets/__init__.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/widgets/account_summary.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/widgets/command_input.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/widgets/debug_log.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/widgets/orders_table.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/widgets/positions_table.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/widgets/quotes_table.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/runner/textual/widgets/repl_output.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/s3.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/slack.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/throttler.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/time.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/utils/websocket_manager.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/tests/strategies/macd_crossover/src/macd_crossover/indicators/macd.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/tests/strategies/macd_crossover/src/macd_crossover/models/macd_crossover.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/tests/strategies/macd_crossover/src/macd_crossover/models/utils.py +0 -0
- {qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/tests/strategies/obi_trader/src/obi_trader/models/obi_trader.py +0 -0
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '1.1.3.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 1, 3, '
|
|
21
|
+
__version__ = version = '1.1.3.dev24'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 1, 3, 'dev24')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -110,6 +110,20 @@ def main(debug: bool, debug_port: int, log_level: str):
|
|
|
110
110
|
@click.option("--no-notifiers", is_flag=True, default=False, help="Disable lifecycle notifiers.", show_default=True)
|
|
111
111
|
@click.option("--no-exporters", is_flag=True, default=False, help="Disable trade exporters.", show_default=True)
|
|
112
112
|
@click.option("--override", type=Path, default=None, help="Sparse YAML file to deep-merge on top of config.", show_default=False)
|
|
113
|
+
@click.option(
|
|
114
|
+
"--from-sources",
|
|
115
|
+
is_flag=True,
|
|
116
|
+
default=False,
|
|
117
|
+
help="Clone the repo pinned in config.release.source and run the strategy from that checkout.",
|
|
118
|
+
show_default=True,
|
|
119
|
+
)
|
|
120
|
+
@click.option(
|
|
121
|
+
"--refresh-sources",
|
|
122
|
+
is_flag=True,
|
|
123
|
+
default=False,
|
|
124
|
+
help="Force re-clone of the source cache (only with --from-sources).",
|
|
125
|
+
show_default=True,
|
|
126
|
+
)
|
|
113
127
|
def run(
|
|
114
128
|
config_file: Path,
|
|
115
129
|
account_file: Path | None,
|
|
@@ -129,6 +143,8 @@ def run(
|
|
|
129
143
|
no_notifiers: bool,
|
|
130
144
|
no_exporters: bool,
|
|
131
145
|
override: Path | None,
|
|
146
|
+
from_sources: bool,
|
|
147
|
+
refresh_sources: bool,
|
|
132
148
|
):
|
|
133
149
|
"""
|
|
134
150
|
Starts the strategy with the given configuration file. If paper mode is enabled, account is not required.
|
|
@@ -137,6 +153,11 @@ def run(
|
|
|
137
153
|
- If provided, the account file is searched first.\n
|
|
138
154
|
- If exists, accounts.toml located in the same folder with the config searched.\n
|
|
139
155
|
- If neither of the above are provided, the accounts.toml in the ~/qubx/accounts.toml path is searched.
|
|
156
|
+
|
|
157
|
+
With --from-sources, the repo pinned in ``config.release.source`` is cloned into
|
|
158
|
+
``.releases/sources/<repo>_<ref>/``, its dependencies installed via ``uv sync``,
|
|
159
|
+
and then ``qubx run`` is re-invoked inside that checkout. Useful for verifying
|
|
160
|
+
that a release config actually boots against its pinned strategy code.
|
|
140
161
|
"""
|
|
141
162
|
from qubx.utils.misc import add_project_to_system_path, logo
|
|
142
163
|
from qubx.utils.runner.runner import run_strategy_yaml, run_strategy_yaml_in_jupyter
|
|
@@ -147,6 +168,68 @@ def run(
|
|
|
147
168
|
click.echo("Error: --jupyter and --textual cannot be used together.", err=True)
|
|
148
169
|
raise click.Abort()
|
|
149
170
|
|
|
171
|
+
if from_sources:
|
|
172
|
+
import subprocess
|
|
173
|
+
import sys
|
|
174
|
+
|
|
175
|
+
from .release import prepare_source_checkout
|
|
176
|
+
|
|
177
|
+
abs_config = str(config_file.resolve())
|
|
178
|
+
try:
|
|
179
|
+
clone_dir, _ = prepare_source_checkout(
|
|
180
|
+
config_file=abs_config,
|
|
181
|
+
refresh=refresh_sources,
|
|
182
|
+
install_project=True,
|
|
183
|
+
)
|
|
184
|
+
except Exception as e:
|
|
185
|
+
click.echo(click.style(f"Failed to prepare source checkout: {e}", fg="red"), err=True)
|
|
186
|
+
raise click.Abort()
|
|
187
|
+
|
|
188
|
+
# Re-invoke `qubx run` inside the cloned venv. Forward every flag the user passed,
|
|
189
|
+
# minus --from-sources/--refresh-sources, and replace the config path with its
|
|
190
|
+
# absolute form so the inner invocation finds it regardless of CWD.
|
|
191
|
+
forwarded: list[str] = []
|
|
192
|
+
if account_file:
|
|
193
|
+
forwarded += ["--account-file", str(Path(account_file).resolve())]
|
|
194
|
+
if paper:
|
|
195
|
+
forwarded.append("--paper")
|
|
196
|
+
if jupyter:
|
|
197
|
+
forwarded.append("--jupyter")
|
|
198
|
+
if textual:
|
|
199
|
+
forwarded.append("--textual")
|
|
200
|
+
if textual_dev:
|
|
201
|
+
forwarded.append("--textual-dev")
|
|
202
|
+
if textual_web:
|
|
203
|
+
forwarded.append("--textual-web")
|
|
204
|
+
if textual_port is not None:
|
|
205
|
+
forwarded += ["--textual-port", str(textual_port)]
|
|
206
|
+
if textual_host and textual_host != "0.0.0.0":
|
|
207
|
+
forwarded += ["--textual-host", textual_host]
|
|
208
|
+
if kernel_only:
|
|
209
|
+
forwarded.append("--kernel-only")
|
|
210
|
+
if connect:
|
|
211
|
+
forwarded += ["--connect", str(Path(connect).resolve())]
|
|
212
|
+
if restore:
|
|
213
|
+
forwarded.append("--restore")
|
|
214
|
+
if no_color:
|
|
215
|
+
forwarded.append("--no-color")
|
|
216
|
+
if dev:
|
|
217
|
+
forwarded.append("--dev")
|
|
218
|
+
if no_emission:
|
|
219
|
+
forwarded.append("--no-emission")
|
|
220
|
+
if no_notifiers:
|
|
221
|
+
forwarded.append("--no-notifiers")
|
|
222
|
+
if no_exporters:
|
|
223
|
+
forwarded.append("--no-exporters")
|
|
224
|
+
if override:
|
|
225
|
+
forwarded += ["--override", str(Path(override).resolve())]
|
|
226
|
+
|
|
227
|
+
cmd = ["uv", "run", "qubx", "run", abs_config, *forwarded]
|
|
228
|
+
logger.info(f"Running inside source checkout: <cyan>{clone_dir}</cyan>")
|
|
229
|
+
logger.info(f"<dim>$ {' '.join(cmd)}</dim>")
|
|
230
|
+
result = subprocess.run(cmd, cwd=str(clone_dir))
|
|
231
|
+
sys.exit(result.returncode)
|
|
232
|
+
|
|
150
233
|
if dev:
|
|
151
234
|
add_project_to_system_path() # Adds ~/projects in dev mode
|
|
152
235
|
add_project_to_system_path(config_file.parent)
|
|
@@ -378,6 +461,20 @@ def validate(config_file: Path, no_check_imports: bool):
|
|
|
378
461
|
help="Commit changes and create tag in repo (default: False)",
|
|
379
462
|
show_default=True,
|
|
380
463
|
)
|
|
464
|
+
@click.option(
|
|
465
|
+
"--from-sources",
|
|
466
|
+
is_flag=True,
|
|
467
|
+
default=False,
|
|
468
|
+
help="Clone the repo pinned in config.release.source and build the release from that checkout.",
|
|
469
|
+
show_default=True,
|
|
470
|
+
)
|
|
471
|
+
@click.option(
|
|
472
|
+
"--refresh-sources",
|
|
473
|
+
is_flag=True,
|
|
474
|
+
default=False,
|
|
475
|
+
help="Force re-clone of the source cache (only with --from-sources).",
|
|
476
|
+
show_default=True,
|
|
477
|
+
)
|
|
381
478
|
def release(
|
|
382
479
|
directory: str,
|
|
383
480
|
config: str,
|
|
@@ -385,6 +482,8 @@ def release(
|
|
|
385
482
|
message: str | None,
|
|
386
483
|
commit: bool,
|
|
387
484
|
output_dir: str,
|
|
485
|
+
from_sources: bool,
|
|
486
|
+
refresh_sources: bool,
|
|
388
487
|
) -> None:
|
|
389
488
|
"""
|
|
390
489
|
Releases the strategy to a zip file.
|
|
@@ -399,8 +498,26 @@ def release(
|
|
|
399
498
|
- logging: Logging configuration
|
|
400
499
|
|
|
401
500
|
All of the dependencies are included in the zip file.
|
|
501
|
+
|
|
502
|
+
With --from-sources, the config's ``release.source`` section is used to clone
|
|
503
|
+
the referenced repo at the specified ref and build the release from that
|
|
504
|
+
checkout instead of the local ``directory``. Used for CI-driven releases
|
|
505
|
+
where the config lives in a separate repo from the strategy code.
|
|
402
506
|
"""
|
|
403
|
-
from .release import release_strategy
|
|
507
|
+
from .release import release_from_source, release_strategy
|
|
508
|
+
|
|
509
|
+
if from_sources:
|
|
510
|
+
zip_path = release_from_source(
|
|
511
|
+
config_file=config,
|
|
512
|
+
output_dir=output_dir,
|
|
513
|
+
tag=tag,
|
|
514
|
+
refresh=refresh_sources,
|
|
515
|
+
)
|
|
516
|
+
if zip_path:
|
|
517
|
+
click.echo(zip_path)
|
|
518
|
+
else:
|
|
519
|
+
raise click.Abort()
|
|
520
|
+
return
|
|
404
521
|
|
|
405
522
|
release_strategy(
|
|
406
523
|
directory=directory,
|
|
@@ -412,47 +529,6 @@ def release(
|
|
|
412
529
|
)
|
|
413
530
|
|
|
414
531
|
|
|
415
|
-
@main.command("release-from-source")
|
|
416
|
-
@click.option(
|
|
417
|
-
"--config",
|
|
418
|
-
"-c",
|
|
419
|
-
type=click.Path(exists=True, resolve_path=True),
|
|
420
|
-
help="Path to a config YAML file with a release.source section",
|
|
421
|
-
required=True,
|
|
422
|
-
)
|
|
423
|
-
@click.option(
|
|
424
|
-
"--output-dir",
|
|
425
|
-
"-o",
|
|
426
|
-
type=click.Path(exists=False),
|
|
427
|
-
help="Output directory to put zip file.",
|
|
428
|
-
default=".releases",
|
|
429
|
-
show_default=True,
|
|
430
|
-
)
|
|
431
|
-
@click.option(
|
|
432
|
-
"--tag",
|
|
433
|
-
"-t",
|
|
434
|
-
type=click.STRING,
|
|
435
|
-
help="Additional tag for this release",
|
|
436
|
-
required=False,
|
|
437
|
-
)
|
|
438
|
-
def release_from_source_cmd(config: str, output_dir: str, tag: str | None) -> None:
|
|
439
|
-
"""
|
|
440
|
-
Build a release by cloning the source repo specified in the config's release.source section.
|
|
441
|
-
|
|
442
|
-
Used for CI-driven releases where the config lives in a separate repo from the strategy code.
|
|
443
|
-
The config must have a release.source section specifying the GitHub repo and ref.
|
|
444
|
-
"""
|
|
445
|
-
from .release import release_from_source
|
|
446
|
-
|
|
447
|
-
zip_path = release_from_source(
|
|
448
|
-
config_file=config,
|
|
449
|
-
output_dir=output_dir,
|
|
450
|
-
tag=tag,
|
|
451
|
-
)
|
|
452
|
-
if zip_path:
|
|
453
|
-
click.echo(zip_path)
|
|
454
|
-
|
|
455
|
-
|
|
456
532
|
@main.command()
|
|
457
533
|
@click.argument(
|
|
458
534
|
"zip-file",
|
|
@@ -562,102 +562,146 @@ def release_strategy(
|
|
|
562
562
|
logger.opt(colors=False).error(f"Error releasing strategy: {e}")
|
|
563
563
|
|
|
564
564
|
|
|
565
|
-
def
|
|
565
|
+
def prepare_source_checkout(
|
|
566
566
|
config_file: str,
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
567
|
+
cache_root: str | Path = ".releases/sources",
|
|
568
|
+
refresh: bool = False,
|
|
569
|
+
install_project: bool = True,
|
|
570
|
+
) -> tuple[Path, StrategyConfig]:
|
|
570
571
|
"""
|
|
571
|
-
|
|
572
|
+
Prepare a source checkout for --from-sources workflows.
|
|
572
573
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
into the clone, and runs the standard release flow.
|
|
574
|
+
Clones the repo specified in ``config.release.source`` into a cached dir
|
|
575
|
+
(reusing it across invocations) and runs ``uv sync --all-extras`` so
|
|
576
|
+
dependencies are resolved and the strategy package is importable.
|
|
577
577
|
|
|
578
578
|
Args:
|
|
579
|
-
config_file: Path to the strategy config YAML (must have
|
|
580
|
-
|
|
581
|
-
|
|
579
|
+
config_file: Path to the strategy config YAML (must have release.source).
|
|
580
|
+
cache_root: Root dir for cached checkouts. Relative paths are resolved
|
|
581
|
+
against the current working directory.
|
|
582
|
+
refresh: If True, wipe any existing cached checkout and re-clone.
|
|
583
|
+
install_project: If True (default), install the project package into the
|
|
584
|
+
cloned venv (needed for ``qubx run``). Set to False for release flows
|
|
585
|
+
that only need deps in the uv git cache.
|
|
582
586
|
|
|
583
587
|
Returns:
|
|
584
|
-
|
|
588
|
+
Tuple of (clone_dir, parsed_strategy_config).
|
|
585
589
|
"""
|
|
586
590
|
import subprocess
|
|
587
|
-
import tempfile
|
|
588
591
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
+
config_path = os.path.abspath(os.path.expanduser(config_file))
|
|
593
|
+
if not is_config_file(config_path):
|
|
594
|
+
raise ValueError(f"Not a valid config file: {config_file}")
|
|
592
595
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
raise ValueError(f"Not a valid config file: {config_file}")
|
|
596
|
+
stg_config = load_strategy_config_from_yaml(config_path, resolve_env=False)
|
|
597
|
+
if not stg_config.release or not stg_config.release.source:
|
|
598
|
+
raise ValueError("Config must have a release.source section with repo and ref")
|
|
597
599
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
raise ValueError("Config must have a release.source section with repo and ref")
|
|
600
|
+
source = stg_config.release.source
|
|
601
|
+
repo_url = f"https://github.com/{source.repo}.git"
|
|
602
|
+
ref = source.ref
|
|
602
603
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
604
|
+
# Cache key: <owner>_<name>_<ref>, with ref sanitized for the filesystem.
|
|
605
|
+
owner, name = source.repo.split("/", 1)
|
|
606
|
+
safe_ref = re.sub(r"[^A-Za-z0-9._-]", "_", ref)
|
|
607
|
+
cache_dir = Path(cache_root).expanduser().resolve() / f"{owner}_{name}_{safe_ref}"
|
|
606
608
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
+
if refresh and cache_dir.exists():
|
|
610
|
+
logger.info(f"Refreshing cached checkout at <cyan>{cache_dir}</cyan>")
|
|
611
|
+
shutil.rmtree(cache_dir)
|
|
609
612
|
|
|
613
|
+
if not cache_dir.exists():
|
|
614
|
+
cache_dir.parent.mkdir(parents=True, exist_ok=True)
|
|
615
|
+
logger.info(f"Cloning <cyan>{source.repo}</cyan> at ref '<yellow>{ref}</yellow>' to {cache_dir}")
|
|
610
616
|
try:
|
|
611
617
|
subprocess.run(
|
|
612
|
-
["git", "clone", "--depth", "1", "--branch", ref, repo_url,
|
|
618
|
+
["git", "clone", "--depth", "1", "--branch", ref, repo_url, str(cache_dir)],
|
|
613
619
|
check=True,
|
|
614
620
|
capture_output=True,
|
|
615
621
|
text=True,
|
|
616
622
|
)
|
|
617
623
|
except subprocess.CalledProcessError:
|
|
618
|
-
# --branch doesn't work with commit SHAs
|
|
624
|
+
# --branch doesn't work with commit SHAs; fall back to full clone + checkout.
|
|
619
625
|
logger.info(f"Shallow clone failed for ref '{ref}', trying full clone...")
|
|
620
|
-
|
|
621
|
-
|
|
626
|
+
if cache_dir.exists():
|
|
627
|
+
shutil.rmtree(cache_dir)
|
|
628
|
+
cache_dir.mkdir(parents=True, exist_ok=True)
|
|
622
629
|
subprocess.run(
|
|
623
|
-
["git", "clone", repo_url,
|
|
630
|
+
["git", "clone", repo_url, str(cache_dir)],
|
|
624
631
|
check=True,
|
|
625
632
|
capture_output=True,
|
|
626
633
|
text=True,
|
|
627
634
|
)
|
|
628
635
|
subprocess.run(
|
|
629
636
|
["git", "checkout", ref],
|
|
630
|
-
cwd=
|
|
637
|
+
cwd=str(cache_dir),
|
|
631
638
|
check=True,
|
|
632
639
|
capture_output=True,
|
|
633
640
|
text=True,
|
|
634
641
|
)
|
|
642
|
+
else:
|
|
643
|
+
logger.info(f"Reusing cached checkout at <cyan>{cache_dir}</cyan>")
|
|
635
644
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
645
|
+
# Resolve and install dependencies in the cloned project.
|
|
646
|
+
# --all-extras pulls in optional extras (qubx-lighter, xmetals plugins).
|
|
647
|
+
# Skipping --no-install-project installs the strategy package itself into
|
|
648
|
+
# the cloned venv — required for `qubx run` to import the strategy.
|
|
649
|
+
sync_args = ["uv", "sync", "--all-extras"]
|
|
650
|
+
if not install_project:
|
|
651
|
+
sync_args.insert(2, "--no-install-project")
|
|
652
|
+
logger.info(f"Running <cyan>{' '.join(sync_args)}</cyan> in {cache_dir}")
|
|
653
|
+
result = subprocess.run(sync_args, cwd=str(cache_dir), capture_output=True, text=True)
|
|
654
|
+
if result.returncode != 0:
|
|
655
|
+
logger.opt(colors=False).error(f"uv sync failed:\n{result.stderr}")
|
|
656
|
+
raise subprocess.CalledProcessError(result.returncode, result.args, output=result.stdout, stderr=result.stderr)
|
|
657
|
+
|
|
658
|
+
return cache_dir, stg_config
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
def release_from_source(
|
|
662
|
+
config_file: str,
|
|
663
|
+
output_dir: str,
|
|
664
|
+
tag: str | None = None,
|
|
665
|
+
refresh: bool = False,
|
|
666
|
+
) -> str | None:
|
|
667
|
+
"""
|
|
668
|
+
Build a release by cloning the source repo specified in ``config.release.source``.
|
|
669
|
+
|
|
670
|
+
Thin wrapper around ``prepare_source_checkout`` + the standard release flow.
|
|
671
|
+
Used by ``qubx release --from-sources``.
|
|
672
|
+
|
|
673
|
+
Args:
|
|
674
|
+
config_file: Path to the strategy config YAML (must have a release.source section)
|
|
675
|
+
output_dir: Directory to write the release ZIP
|
|
676
|
+
tag: Optional tag suffix for the release name
|
|
677
|
+
refresh: Force re-clone of the source cache
|
|
678
|
+
|
|
679
|
+
Returns:
|
|
680
|
+
Path to the created ZIP file, or None on failure
|
|
681
|
+
"""
|
|
682
|
+
from qubx import QubxLogConfig
|
|
683
|
+
|
|
684
|
+
QubxLogConfig.set_log_level("INFO")
|
|
685
|
+
|
|
686
|
+
try:
|
|
687
|
+
config_path = os.path.abspath(os.path.expanduser(config_file))
|
|
688
|
+
# release flow reads source files directly from the clone; no need to install the project.
|
|
689
|
+
clone_dir, stg_config = prepare_source_checkout(
|
|
690
|
+
config_file=config_path,
|
|
691
|
+
refresh=refresh,
|
|
692
|
+
install_project=False,
|
|
646
693
|
)
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
raise subprocess.CalledProcessError(result.returncode, result.args)
|
|
694
|
+
assert stg_config.release and stg_config.release.source # verified in helper
|
|
695
|
+
ref = stg_config.release.source.ref
|
|
650
696
|
|
|
651
|
-
# Copy the config into the clone root so release can find it
|
|
697
|
+
# Copy the config into the clone root so the release flow can find it.
|
|
652
698
|
config_basename = os.path.basename(config_path)
|
|
653
|
-
cloned_config = os.path.join(clone_dir, config_basename)
|
|
699
|
+
cloned_config = os.path.join(str(clone_dir), config_basename)
|
|
654
700
|
shutil.copy2(config_path, cloned_config)
|
|
655
701
|
|
|
656
|
-
|
|
657
|
-
logger.info(f"Running release from {clone_dir} ...")
|
|
702
|
+
logger.info(f"Running release from <cyan>{clone_dir}</cyan>")
|
|
658
703
|
output_dir = os.path.abspath(output_dir)
|
|
659
|
-
stg_info = load_strategy_from_config(Path(cloned_config), clone_dir)
|
|
660
|
-
pyproject_root = clone_dir
|
|
704
|
+
stg_info = load_strategy_from_config(Path(cloned_config), str(clone_dir))
|
|
661
705
|
|
|
662
706
|
git_info = ReleaseInfo(
|
|
663
707
|
tag=generate_tag(stg_info.name, tag),
|
|
@@ -670,12 +714,11 @@ def release_from_source(
|
|
|
670
714
|
create_released_pack(
|
|
671
715
|
stg_info=stg_info,
|
|
672
716
|
git_info=git_info,
|
|
673
|
-
pyproject_root=
|
|
717
|
+
pyproject_root=str(clone_dir),
|
|
674
718
|
output_dir=output_dir,
|
|
675
719
|
config_file=cloned_config,
|
|
676
720
|
)
|
|
677
721
|
|
|
678
|
-
# Find the created ZIP
|
|
679
722
|
zip_path = os.path.join(output_dir, f"{git_info.tag}.zip")
|
|
680
723
|
if os.path.exists(zip_path):
|
|
681
724
|
logger.info(f"Release created: {zip_path}")
|
|
@@ -687,10 +730,6 @@ def release_from_source(
|
|
|
687
730
|
except Exception as e:
|
|
688
731
|
logger.opt(colors=False).error(f"Error in release_from_source: {e}")
|
|
689
732
|
return None
|
|
690
|
-
finally:
|
|
691
|
-
# Clean up temp clone
|
|
692
|
-
if "clone_dir" in locals():
|
|
693
|
-
shutil.rmtree(clone_dir, ignore_errors=True)
|
|
694
733
|
|
|
695
734
|
|
|
696
735
|
def _find_source_root(pyproject_root: str, project_name: str) -> str | None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/binance/exchange.py
RENAMED
|
File without changes
|
{qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/hyperliquid/__init__.py
RENAMED
|
File without changes
|
{qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/hyperliquid/account.py
RENAMED
|
File without changes
|
{qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/hyperliquid/broker.py
RENAMED
|
File without changes
|
{qubx-1.1.3.dev23 → qubx-1.1.3.dev24}/src/qubx/connectors/ccxt/exchanges/hyperliquid/hyperliquid.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
|