Qubx 1.2.2.dev1__tar.gz → 1.2.2.dev3__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.2.2.dev1 → qubx-1.2.2.dev3}/PKG-INFO +1 -1
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/_version.py +2 -2
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/cli/release.py +5 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/account.py +27 -1
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/hyperliquid/account.py +13 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/okx/account.py +69 -3
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/account.py +8 -2
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/utils.pyx +6 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/.gitignore +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/LICENSE +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/README.md +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/pyproject.toml +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/scripts/build.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/_nb_magic.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/account.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/broker.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/data.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/iteratedstream.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/management.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/ome.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/optimization.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/runner.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/sentinels.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/simulated_data.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/simulated_exchange.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/simulator.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/transfers.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/backtester/utils.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/cli/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/cli/commands.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/cli/deploy.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/cli/misc.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/cli/resolver.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/cli/s3.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/cli/theme.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/cli/tui.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/cli/user_config.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/config.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/adapters/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/adapters/polling_adapter.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/broker.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/connection_manager.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/data.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exceptions.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchange_manager.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/base.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/binance/broker.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/binance/exchange.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex_account.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/gateio/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/gateio/gateio.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/hyperliquid/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/hyperliquid/broker.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/hyperliquid/hyperliquid.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/kraken/kraken.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/okx/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/okx/broker.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/okx/okx.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/factory.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/handlers/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/handlers/base.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/handlers/factory.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/handlers/funding_rate.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/handlers/liquidation.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/handlers/ohlc.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/handlers/open_interest.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/handlers/orderbook.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/handlers/quote.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/handlers/trade.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/rate_limits.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/subscription_config.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/subscription_manager.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/subscription_orchestrator.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/utils.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/warmup_service.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/registry.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/tardis/data.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/tardis/utils.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/control/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/control/builtin.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/control/decorator.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/control/executor.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/control/interfaces.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/control/server.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/control/types.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/basics.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/context.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/detectors/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/detectors/delisting.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/detectors/stale.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/errors.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/exceptions.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/helpers.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/initializer.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/interfaces.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/loggers.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/lookups.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/metrics.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/mixins/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/mixins/market.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/mixins/processing.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/mixins/subscription.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/mixins/trading.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/mixins/universe.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/mixins/utils.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/series.pxd +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/series.pyi +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/series.pyx +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/core/utils.pyi +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/cache.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/containers.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/guards.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/registry.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/storage.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/storages/ccxt.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/storages/csv.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/storages/handy.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/storages/multi.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/storages/questdb.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/storages/stub.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/storages/utils.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/data/transformers.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/emitters/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/emitters/base.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/emitters/composite.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/emitters/csv.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/emitters/indicator.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/emitters/inmemory.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/emitters/prometheus.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/emitters/questdb.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/exporters/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/exporters/composite.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/exporters/formatters/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/exporters/formatters/base.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/exporters/formatters/incremental.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/exporters/formatters/slack.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/exporters/formatters/target_position.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/exporters/redis_streams.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/exporters/slack.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/gathering/simplest.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/health/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/health/base.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/health/dummy.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/loggers/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/loggers/csv.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/loggers/factory.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/loggers/inmemory.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/loggers/mongo.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/loggers/postgres.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/notifications/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/notifications/composite.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/notifications/slack.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/notifications/throttler.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/pandaz/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/pandaz/stats.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/pandaz/ta.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/pandaz/utils.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/plugins/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/plugins/loader.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/rate_limiting/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/rate_limiting/backend.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/rate_limiting/config.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/rate_limiting/engine.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/rate_limiting/ip_resolver.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/rate_limiting/manager.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/rate_limiting/pools.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/rate_limiting/redis_backend.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/resources/_build.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/resources/crypto-fees.ini +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/resources/instruments/hyperliquid-spot.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/resources/instruments/hyperliquid.f-perpetual.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/resources/instruments/symbols-binance-spot.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/resources/instruments/symbols-binance.cm-future.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/resources/instruments/symbols-binance.cm-perpetual.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/resources/instruments/symbols-binance.um-future.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/resources/instruments/symbols-binance.um-perpetual.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/resources/instruments/symbols-bitfinex.f-perpetual.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/resources/instruments/symbols-kraken-spot.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/resources/instruments/symbols-kraken.f-future.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/resources/instruments/symbols-kraken.f-perpetual.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/restarts/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/restarts/state_resolvers.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/restarts/time_finders.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/restorers/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/restorers/balance.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/restorers/factory.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/restorers/interfaces.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/restorers/position.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/restorers/signal.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/restorers/state.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/restorers/utils.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/state/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/state/dummy.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/state/redis.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/ta/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/ta/indicators.pxd +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/ta/indicators.pyi +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/ta/indicators.pyx +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/base.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/project/accounts.toml.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/project/config.yml.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/project/jlive.sh.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/project/jpaper.sh.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/project/pyproject.toml.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/project/src/{{ strategy_name }}/__init__.py.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/project/src/{{ strategy_name }}/strategy.py.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/project/template.yml +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/.claude/skills/qubx-cli/SKILL.md +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/.claude/skills/qubx-indicators/SKILL.md +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/.claude/skills/simulation-explorer/SKILL.md +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/.claude/skills/strategy-release/SKILL.md +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/.github/workflows/ci.yml.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/.gitignore.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/.python-version +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/.vscode/launch.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/.vscode/settings.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/.vscode/tasks.json +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/CLAUDE.md.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/README.md.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/configs/.gitkeep +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/justfile.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/pyproject.toml.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/research/.gitkeep +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/src/{{ strategy_name }}/__init__.py.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/src/{{ strategy_name }}/cli.py.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/src/{{ strategy_name }}/strategy.py.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/template.yml +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/repo/tests/test_strategy.py.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/simple/__init__.py.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/simple/accounts.toml.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/simple/config.yml.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/simple/jlive.sh.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/simple/jpaper.sh.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/simple/strategy.py.j2 +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/templates/simple/template.yml +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/trackers/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/trackers/advanced.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/trackers/composite.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/trackers/rebalancers.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/trackers/riskctrl.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/trackers/sizers.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/_pyxreloader.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/charting/lookinglass.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/charting/mpl_helpers.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/charting/orderbook.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/collections.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/hft/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/hft/numba_utils.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/hft/orderbook.pyi +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/hft/orderbook.pyx +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/marketdata/binance.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/marketdata/ccxt.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/marketdata/dukas.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/misc.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/nonce.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/ntp.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/numbers_utils.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/orderbook.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/plotting/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/plotting/dashboard.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/plotting/data.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/plotting/interfaces.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/plotting/renderers/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/plotting/renderers/plotly.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/questdb.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/rate_limiter.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/results.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/ringbuffer.pxd +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/ringbuffer.pyi +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/ringbuffer.pyx +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/_jupyter_runner.pyt +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/accounts.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/configs.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/factory.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/kernel_service.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/runner.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/app.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/handlers.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/init_code.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/kernel.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/styles.tcss +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/widgets/__init__.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/widgets/account_summary.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/widgets/command_input.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/widgets/debug_log.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/widgets/orders_table.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/widgets/positions_table.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/widgets/quotes_table.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/runner/textual/widgets/repl_output.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/s3.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/slack.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/throttler.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/time.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/utils/websocket_manager.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/tests/strategies/macd_crossover/src/macd_crossover/indicators/macd.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/tests/strategies/macd_crossover/src/macd_crossover/models/macd_crossover.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/tests/strategies/macd_crossover/src/macd_crossover/models/utils.py +0 -0
- {qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/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.2.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 2, 2, '
|
|
21
|
+
__version__ = version = '1.2.2.dev3'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 2, 2, 'dev3')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -1432,12 +1432,14 @@ def _bundle_source_overrides(
|
|
|
1432
1432
|
continue
|
|
1433
1433
|
|
|
1434
1434
|
checkout_dir = _find_uv_git_checkout(commit_sha)
|
|
1435
|
+
cloned_locally = False
|
|
1435
1436
|
if not checkout_dir:
|
|
1436
1437
|
# Cache miss — clone the repo at the exact commit
|
|
1437
1438
|
git_url = source["git"]
|
|
1438
1439
|
git_ref = source.get("tag") or source.get("branch") or commit_sha
|
|
1439
1440
|
logger.info(f" {pkg_name}: cache miss, cloning {git_url} at {git_ref} ...")
|
|
1440
1441
|
checkout_dir = os.path.join(os.path.dirname(wheels_dir), f".git-clone-{pkg_norm}")
|
|
1442
|
+
cloned_locally = True
|
|
1441
1443
|
try:
|
|
1442
1444
|
subprocess.run(
|
|
1443
1445
|
["git", "clone", "--depth", "1", "--branch", git_ref, git_url, checkout_dir],
|
|
@@ -1473,6 +1475,9 @@ def _bundle_source_overrides(
|
|
|
1473
1475
|
logger.info(f" Bundled {pkg_name}=={pkg_ver} from git")
|
|
1474
1476
|
except subprocess.CalledProcessError as e:
|
|
1475
1477
|
logger.opt(colors=False).warning(f" Failed to build wheel for {pkg_name}: {e.stderr or e}")
|
|
1478
|
+
finally:
|
|
1479
|
+
if cloned_locally and os.path.isdir(checkout_dir):
|
|
1480
|
+
shutil.rmtree(checkout_dir, ignore_errors=True)
|
|
1476
1481
|
|
|
1477
1482
|
return bundled
|
|
1478
1483
|
|
|
@@ -222,7 +222,10 @@ class CcxtAccountProcessor(BasicAccountProcessor):
|
|
|
222
222
|
except Exception as e:
|
|
223
223
|
logger.warning(f"Failed to fetch balance data before polling started: {e}")
|
|
224
224
|
|
|
225
|
-
|
|
225
|
+
if self._exchange_total_capital is not None:
|
|
226
|
+
return self._exchange_total_capital
|
|
227
|
+
|
|
228
|
+
# fallback: sum of balances + market value of all positions on non spot/margin
|
|
226
229
|
_currency_to_value = {c: self._get_currency_value(b.total, c) for c, b in self._balances.items()}
|
|
227
230
|
_positions_value = sum([p.market_value_funds for p in self._positions.values() if p.instrument.is_futures()])
|
|
228
231
|
return sum(_currency_to_value.values()) + _positions_value
|
|
@@ -316,9 +319,32 @@ class CcxtAccountProcessor(BasicAccountProcessor):
|
|
|
316
319
|
await self._subscribe_instruments(list(self._required_instruments))
|
|
317
320
|
self._latest_instruments.update(self._required_instruments)
|
|
318
321
|
|
|
322
|
+
def _extract_portfolio_value(self, balances_raw: dict) -> float | None:
|
|
323
|
+
"""Extract exchange-reported portfolio value (equity) from raw balance response.
|
|
324
|
+
|
|
325
|
+
Override in exchange-specific processors for non-standard responses.
|
|
326
|
+
Base implementation handles Binance futures (totalMarginBalance).
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
Total equity as float, or None to fall back to computed value.
|
|
330
|
+
"""
|
|
331
|
+
info = balances_raw.get("info", {})
|
|
332
|
+
val = info.get("totalMarginBalance")
|
|
333
|
+
if val is not None:
|
|
334
|
+
try:
|
|
335
|
+
return float(val)
|
|
336
|
+
except (ValueError, TypeError):
|
|
337
|
+
pass
|
|
338
|
+
return None
|
|
339
|
+
|
|
319
340
|
async def _update_balance(self) -> None:
|
|
320
341
|
"""Fetch and update balances from exchange"""
|
|
321
342
|
balances_raw = await self.exchange_manager.exchange.fetch_balance()
|
|
343
|
+
|
|
344
|
+
equity = self._extract_portfolio_value(balances_raw)
|
|
345
|
+
if equity is not None:
|
|
346
|
+
self._exchange_total_capital = equity
|
|
347
|
+
|
|
322
348
|
balances = ccxt_convert_balance(balances_raw, self.exchange)
|
|
323
349
|
current_balances = self.get_balances()
|
|
324
350
|
|
{qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/hyperliquid/account.py
RENAMED
|
@@ -23,6 +23,19 @@ class HyperliquidAccountProcessor(CcxtAccountProcessor):
|
|
|
23
23
|
so we must subscribe to both channels separately.
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
|
+
def _extract_portfolio_value(self, balances_raw: dict) -> float | None:
|
|
27
|
+
"""Extract Hyperliquid account value from raw balance response."""
|
|
28
|
+
info = balances_raw.get("info", {})
|
|
29
|
+
for key in ("marginSummary", "crossMarginSummary"):
|
|
30
|
+
summary = info.get(key, {})
|
|
31
|
+
val = summary.get("accountValue")
|
|
32
|
+
if val is not None:
|
|
33
|
+
try:
|
|
34
|
+
return float(val)
|
|
35
|
+
except (ValueError, TypeError):
|
|
36
|
+
pass
|
|
37
|
+
return None
|
|
38
|
+
|
|
26
39
|
async def _subscribe_instruments(self, instruments: list[Instrument]):
|
|
27
40
|
"""Override to filter out instruments from other exchanges (e.g., spot vs futures)."""
|
|
28
41
|
# Filter instruments to only those belonging to this exchange
|
|
@@ -18,8 +18,35 @@ class OkxAccountProcessor(CcxtAccountProcessor):
|
|
|
18
18
|
so we must subscribe to both channels separately:
|
|
19
19
|
- orders channel: for order status updates (watch_orders)
|
|
20
20
|
- trades channel: for trade/fill updates (watch_my_trades)
|
|
21
|
+
|
|
22
|
+
Balance streaming: uses watch_balance WS to get real-time totalEq updates
|
|
23
|
+
instead of relying solely on 30s polling.
|
|
21
24
|
"""
|
|
22
25
|
|
|
26
|
+
def start(self):
|
|
27
|
+
super().start()
|
|
28
|
+
if self._is_running and not self.exchange_manager.exchange.isSandboxModeEnabled:
|
|
29
|
+
self._polling_tasks["balance_ws"] = self._loop.submit(self._watch_balance_stream())
|
|
30
|
+
|
|
31
|
+
async def _watch_balance_stream(self):
|
|
32
|
+
"""Stream balance updates via WS to get real-time totalEq."""
|
|
33
|
+
|
|
34
|
+
async def _watch():
|
|
35
|
+
balances_raw = await self.exchange_manager.exchange.watch_balance()
|
|
36
|
+
equity = self._extract_portfolio_value(balances_raw)
|
|
37
|
+
if equity is not None:
|
|
38
|
+
self._exchange_total_capital = equity
|
|
39
|
+
margin_ratio = self._extract_margin_ratio(balances_raw)
|
|
40
|
+
if margin_ratio is not None:
|
|
41
|
+
self._exchange_margin_ratio = margin_ratio
|
|
42
|
+
|
|
43
|
+
await self._listen_to_stream(
|
|
44
|
+
subscriber=_watch,
|
|
45
|
+
exchange=self.exchange_manager.exchange,
|
|
46
|
+
channel=self.channel,
|
|
47
|
+
name="okx_balance_ws",
|
|
48
|
+
)
|
|
49
|
+
|
|
23
50
|
async def _subscribe_executions(self, name: str, channel: CtrlChannel):
|
|
24
51
|
logger.info("<yellow>[OKX]</yellow> Subscribing to executions (orders + trades)")
|
|
25
52
|
_symbol_to_instrument = {}
|
|
@@ -57,15 +84,54 @@ class OkxAccountProcessor(CcxtAccountProcessor):
|
|
|
57
84
|
),
|
|
58
85
|
)
|
|
59
86
|
|
|
87
|
+
def _get_account_data(self, balances_raw: dict) -> dict:
|
|
88
|
+
"""Get the OKX account data dict from info.data[0]."""
|
|
89
|
+
return balances_raw.get("info", {}).get("data", [{}])[0]
|
|
90
|
+
|
|
91
|
+
def _extract_margin_ratio(self, balances_raw: dict) -> float | None:
|
|
92
|
+
"""Extract OKX margin ratio from the base currency detail entry.
|
|
93
|
+
|
|
94
|
+
The account-level mgnRatio is empty; the real value is per-currency in details.
|
|
95
|
+
We use the base currency's mgnRatio as the account margin ratio.
|
|
96
|
+
"""
|
|
97
|
+
details = self._get_account_data(balances_raw).get("details", [])
|
|
98
|
+
for detail in details:
|
|
99
|
+
if detail.get("ccy", "").upper() == self.base_currency.upper():
|
|
100
|
+
val = detail.get("mgnRatio")
|
|
101
|
+
if val is not None and val != "":
|
|
102
|
+
try:
|
|
103
|
+
return float(val)
|
|
104
|
+
except (ValueError, TypeError):
|
|
105
|
+
pass
|
|
106
|
+
return None
|
|
107
|
+
|
|
108
|
+
def _extract_portfolio_value(self, balances_raw: dict) -> float | None:
|
|
109
|
+
"""Extract OKX total equity from info.data[0].totalEq."""
|
|
110
|
+
total_eq = self._get_account_data(balances_raw).get("totalEq")
|
|
111
|
+
if total_eq is not None and total_eq != "":
|
|
112
|
+
try:
|
|
113
|
+
return float(total_eq)
|
|
114
|
+
except (ValueError, TypeError):
|
|
115
|
+
pass
|
|
116
|
+
return None
|
|
117
|
+
|
|
60
118
|
async def _update_balance(self) -> None:
|
|
61
|
-
"""OKX balance override: use cashBal
|
|
119
|
+
"""OKX balance override: use cashBal for per-currency balances.
|
|
62
120
|
|
|
63
121
|
CCXT maps OKX's `eq` (equity = cashBal + unrealizedPnL) to balance `total`.
|
|
64
|
-
|
|
65
|
-
|
|
122
|
+
We use `cashBal` for individual currency balances, and extract `totalEq`
|
|
123
|
+
as the authoritative portfolio value via _extract_portfolio_value().
|
|
66
124
|
"""
|
|
67
125
|
balances_raw = await self.exchange_manager.exchange.fetch_balance()
|
|
68
126
|
|
|
127
|
+
equity = self._extract_portfolio_value(balances_raw)
|
|
128
|
+
if equity is not None:
|
|
129
|
+
self._exchange_total_capital = equity
|
|
130
|
+
|
|
131
|
+
margin_ratio = self._extract_margin_ratio(balances_raw)
|
|
132
|
+
if margin_ratio is not None:
|
|
133
|
+
self._exchange_margin_ratio = margin_ratio
|
|
134
|
+
|
|
69
135
|
# Extract cashBal from raw OKX response instead of CCXT-parsed eq
|
|
70
136
|
balances: list[AssetBalance] = []
|
|
71
137
|
raw_details = balances_raw.get("info", {}).get("data", [{}])[0].get("details", [])
|
|
@@ -65,6 +65,8 @@ class BasicAccountProcessor(IAccountProcessor):
|
|
|
65
65
|
self._locked_capital_by_order = dict()
|
|
66
66
|
self._pending_order_requests = {}
|
|
67
67
|
self._balances = {}
|
|
68
|
+
self._exchange_total_capital: float | None = None
|
|
69
|
+
self._exchange_margin_ratio: float | None = None
|
|
68
70
|
# Initialize with base currency balance
|
|
69
71
|
self._balances[self.base_currency] = AssetBalance(
|
|
70
72
|
exchange=self.exchange, currency=self.base_currency, free=initial_capital, locked=0.0, total=initial_capital
|
|
@@ -90,7 +92,9 @@ class BasicAccountProcessor(IAccountProcessor):
|
|
|
90
92
|
return self.get_available_margin(exchange)
|
|
91
93
|
|
|
92
94
|
def get_total_capital(self, exchange: str | None = None) -> float:
|
|
93
|
-
|
|
95
|
+
if self._exchange_total_capital is not None:
|
|
96
|
+
return self._exchange_total_capital
|
|
97
|
+
# fallback: sum of cash + market value of all positions
|
|
94
98
|
_cash_amount = self._balances[self.base_currency].total
|
|
95
99
|
_positions_value = sum([p.market_value_funds for p in self._positions.values()])
|
|
96
100
|
return _cash_amount + _positions_value
|
|
@@ -180,7 +184,9 @@ class BasicAccountProcessor(IAccountProcessor):
|
|
|
180
184
|
return self.get_total_capital(exchange) - self.get_total_required_margin(exchange)
|
|
181
185
|
|
|
182
186
|
def get_margin_ratio(self, exchange: str | None = None) -> float:
|
|
183
|
-
|
|
187
|
+
if self._exchange_margin_ratio is not None:
|
|
188
|
+
return self._exchange_margin_ratio
|
|
189
|
+
# fallback: total capital / total required margin
|
|
184
190
|
required_margin = self.get_total_required_margin(exchange)
|
|
185
191
|
if required_margin == 0:
|
|
186
192
|
return 100.0
|
|
@@ -8,6 +8,12 @@ NS = 1_000_000_000
|
|
|
8
8
|
|
|
9
9
|
cpdef recognize_time(time):
|
|
10
10
|
if isinstance(time, str):
|
|
11
|
+
# Strip timezone suffix (e.g. 'Z', '+00:00') — np.datetime64 expects tz-naive ISO strings.
|
|
12
|
+
# All incoming timestamps are assumed UTC.
|
|
13
|
+
if time.endswith('Z') or time.endswith('z'):
|
|
14
|
+
time = time[:-1]
|
|
15
|
+
elif '+' in time[10:]:
|
|
16
|
+
time = time[:time.rindex('+')]
|
|
11
17
|
return np.datetime64(time, 'ns')
|
|
12
18
|
elif isinstance(time, np.datetime64):
|
|
13
19
|
return time
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex_account.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/hyperliquid/__init__.py
RENAMED
|
File without changes
|
{qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/src/qubx/connectors/ccxt/exchanges/hyperliquid/broker.py
RENAMED
|
File without changes
|
{qubx-1.2.2.dev1 → qubx-1.2.2.dev3}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|