Qubx 1.1.2.dev4__tar.gz → 1.1.2.dev6__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.2.dev4 → qubx-1.1.2.dev6}/PKG-INFO +1 -1
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/_version.py +2 -2
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/metrics.py +121 -9
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/storages/multi.py +17 -5
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/.gitignore +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/LICENSE +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/README.md +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/pyproject.toml +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/scripts/build.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/_nb_magic.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/account.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/broker.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/data.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/iteratedstream.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/management.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/ome.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/optimization.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/runner.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/sentinels.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/simulated_data.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/simulated_exchange.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/simulator.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/transfers.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/backtester/utils.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/cli/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/cli/commands.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/cli/deploy.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/cli/misc.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/cli/release.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/cli/resolver.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/cli/s3.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/cli/theme.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/cli/tui.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/cli/user_config.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/config.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/account.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/adapters/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/adapters/polling_adapter.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/broker.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/connection_manager.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/data.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exceptions.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchange_manager.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/base.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/binance/broker.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/binance/exchange.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex_account.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/gateio/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/gateio/gateio.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/hyperliquid/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/hyperliquid/account.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/hyperliquid/broker.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/hyperliquid/hyperliquid.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/kraken/kraken.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/okx/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/okx/account.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/okx/broker.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/okx/okx.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/factory.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/handlers/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/handlers/base.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/handlers/factory.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/handlers/funding_rate.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/handlers/liquidation.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/handlers/ohlc.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/handlers/open_interest.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/handlers/orderbook.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/handlers/quote.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/handlers/trade.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/subscription_config.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/subscription_manager.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/subscription_orchestrator.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/utils.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/warmup_service.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/registry.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/tardis/data.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/tardis/utils.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/account.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/basics.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/context.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/detectors/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/detectors/delisting.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/detectors/stale.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/errors.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/exceptions.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/helpers.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/initializer.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/interfaces.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/loggers.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/lookups.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/mixins/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/mixins/market.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/mixins/processing.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/mixins/subscription.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/mixins/trading.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/mixins/universe.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/mixins/utils.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/series.pxd +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/series.pyi +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/series.pyx +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/utils.pyi +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/core/utils.pyx +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/cache.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/containers.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/guards.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/registry.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/storage.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/storages/ccxt.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/storages/csv.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/storages/handy.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/storages/questdb.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/storages/stub.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/storages/utils.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/data/transformers.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/emitters/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/emitters/base.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/emitters/composite.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/emitters/csv.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/emitters/indicator.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/emitters/inmemory.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/emitters/prometheus.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/emitters/questdb.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/exporters/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/exporters/composite.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/exporters/formatters/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/exporters/formatters/base.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/exporters/formatters/incremental.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/exporters/formatters/slack.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/exporters/formatters/target_position.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/exporters/redis_streams.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/exporters/slack.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/gathering/simplest.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/health/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/health/base.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/health/dummy.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/health/server.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/loggers/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/loggers/csv.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/loggers/factory.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/loggers/inmemory.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/loggers/mongo.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/notifications/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/notifications/composite.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/notifications/slack.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/notifications/throttler.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/pandaz/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/pandaz/stats.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/pandaz/ta.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/pandaz/utils.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/plugins/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/plugins/loader.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/resources/_build.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/resources/crypto-fees.ini +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/resources/instruments/hyperliquid-spot.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/resources/instruments/hyperliquid.f-perpetual.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/resources/instruments/symbols-binance-spot.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/resources/instruments/symbols-binance.cm-future.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/resources/instruments/symbols-binance.cm-perpetual.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/resources/instruments/symbols-binance.um-future.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/resources/instruments/symbols-binance.um-perpetual.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/resources/instruments/symbols-bitfinex.f-perpetual.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/resources/instruments/symbols-kraken-spot.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/resources/instruments/symbols-kraken.f-future.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/resources/instruments/symbols-kraken.f-perpetual.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/restarts/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/restarts/state_resolvers.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/restarts/time_finders.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/restorers/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/restorers/balance.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/restorers/factory.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/restorers/interfaces.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/restorers/position.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/restorers/signal.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/restorers/state.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/restorers/utils.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/state/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/state/dummy.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/state/redis.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/ta/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/ta/indicators.pxd +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/ta/indicators.pyi +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/ta/indicators.pyx +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/base.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/project/accounts.toml.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/project/config.yml.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/project/jlive.sh.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/project/jpaper.sh.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/project/pyproject.toml.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/project/src/{{ strategy_name }}/__init__.py.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/project/src/{{ strategy_name }}/strategy.py.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/project/template.yml +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/.claude/skills/qubx-cli/SKILL.md +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/.claude/skills/qubx-indicators/SKILL.md +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/.claude/skills/simulation-explorer/SKILL.md +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/.claude/skills/strategy-release/SKILL.md +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/.github/workflows/ci.yml.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/.gitignore.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/.python-version +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/.vscode/launch.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/.vscode/settings.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/.vscode/tasks.json +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/CLAUDE.md.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/README.md.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/configs/.gitkeep +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/justfile.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/pyproject.toml.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/research/.gitkeep +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/src/{{ strategy_name }}/__init__.py.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/src/{{ strategy_name }}/cli.py.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/src/{{ strategy_name }}/strategy.py.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/template.yml +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/repo/tests/test_strategy.py.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/simple/__init__.py.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/simple/accounts.toml.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/simple/config.yml.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/simple/jlive.sh.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/simple/jpaper.sh.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/simple/strategy.py.j2 +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/templates/simple/template.yml +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/trackers/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/trackers/advanced.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/trackers/composite.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/trackers/rebalancers.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/trackers/riskctrl.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/trackers/sizers.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/_pyxreloader.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/charting/lookinglass.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/charting/mpl_helpers.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/charting/orderbook.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/collections.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/hft/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/hft/numba_utils.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/hft/orderbook.pyi +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/hft/orderbook.pyx +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/marketdata/binance.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/marketdata/ccxt.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/marketdata/dukas.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/misc.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/nonce.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/ntp.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/numbers_utils.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/orderbook.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/plotting/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/plotting/dashboard.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/plotting/data.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/plotting/interfaces.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/plotting/renderers/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/plotting/renderers/plotly.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/questdb.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/rate_limiter.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/results.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/ringbuffer.pxd +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/ringbuffer.pyi +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/ringbuffer.pyx +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/_jupyter_runner.pyt +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/accounts.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/configs.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/factory.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/kernel_service.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/runner.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/app.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/handlers.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/init_code.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/kernel.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/styles.tcss +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/widgets/__init__.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/widgets/account_summary.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/widgets/command_input.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/widgets/debug_log.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/widgets/orders_table.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/widgets/positions_table.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/widgets/quotes_table.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/runner/textual/widgets/repl_output.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/s3.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/slack.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/throttler.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/time.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/utils/websocket_manager.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/tests/strategies/macd_crossover/src/macd_crossover/indicators/macd.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/tests/strategies/macd_crossover/src/macd_crossover/models/macd_crossover.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/tests/strategies/macd_crossover/src/macd_crossover/models/utils.py +0 -0
- {qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/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.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 1, 2, '
|
|
21
|
+
__version__ = version = '1.1.2.dev6'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 1, 2, 'dev6')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -913,11 +913,34 @@ class TradingSessionResult:
|
|
|
913
913
|
return pd.Series(dtype=float)
|
|
914
914
|
return calculate_leverage(self.portfolio_log, self.get_total_capital(), self.start)
|
|
915
915
|
|
|
916
|
+
@property
|
|
917
|
+
def gross_leverage(self) -> pd.Series:
|
|
918
|
+
"""Get gross leverage over time (sum of absolute exposures / capital)"""
|
|
919
|
+
if self.portfolio_log.empty:
|
|
920
|
+
return pd.Series(dtype=float)
|
|
921
|
+
return calculate_gross_leverage(self.portfolio_log, self.get_total_capital(), self.start)
|
|
922
|
+
|
|
916
923
|
def get_funding_per_symbol(self, start: OptTimestamp = None, stop: OptTimestamp = None) -> pd.DataFrame:
|
|
917
924
|
if self.portfolio_log.empty:
|
|
918
925
|
return pd.DataFrame(dtype=float)
|
|
919
926
|
return calculate_funding_per_symbol(self.portfolio_log, start, stop)
|
|
920
927
|
|
|
928
|
+
def get_commissions_per_asset(
|
|
929
|
+
self, start: OptTimestamp = None, stop: OptTimestamp = None, filter_zero: bool = True
|
|
930
|
+
) -> pd.DataFrame:
|
|
931
|
+
if self.portfolio_log.empty:
|
|
932
|
+
return pd.DataFrame(dtype=float)
|
|
933
|
+
return calculate_commissions_per_asset(self.portfolio_log, start, stop, filter_zero)
|
|
934
|
+
|
|
935
|
+
def get_commissions_total(self, start: OptTimestamp = None, stop: OptTimestamp = None) -> pd.Series:
|
|
936
|
+
return self.get_commissions_per_asset(start, stop).sum(axis=1).rename("commissions_total")
|
|
937
|
+
|
|
938
|
+
def get_commissions_breakdown(self, start: OptTimestamp = None, stop: OptTimestamp = None) -> pd.Series:
|
|
939
|
+
df = self.get_commissions_per_asset(start, stop)
|
|
940
|
+
if df.empty:
|
|
941
|
+
return pd.Series(dtype=float)
|
|
942
|
+
return df.iloc[-1].sort_values(ascending=False).rename("commissions_breakdown")
|
|
943
|
+
|
|
921
944
|
def get_funding_per_asset(
|
|
922
945
|
self, start: OptTimestamp = None, stop: OptTimestamp = None, filter_zero: bool = True
|
|
923
946
|
) -> pd.DataFrame:
|
|
@@ -928,8 +951,8 @@ class TradingSessionResult:
|
|
|
928
951
|
def get_funding_total(self, start: OptTimestamp = None, stop: OptTimestamp = None) -> pd.Series:
|
|
929
952
|
return self.get_funding_per_asset(start, stop).sum(axis=1).rename("funding_total")
|
|
930
953
|
|
|
931
|
-
def
|
|
932
|
-
return self.get_funding_per_asset(start, stop).iloc[-1].sort_values(ascending=False).rename("
|
|
954
|
+
def get_funding_breakdown(self, start: OptTimestamp = None, stop: OptTimestamp = None) -> pd.Series:
|
|
955
|
+
return self.get_funding_per_asset(start, stop).iloc[-1].sort_values(ascending=False).rename("funding_breakdown")
|
|
933
956
|
|
|
934
957
|
def get_asset_pnl(
|
|
935
958
|
self,
|
|
@@ -951,7 +974,7 @@ class TradingSessionResult:
|
|
|
951
974
|
funding_delta = funding.diff().fillna(funding.iloc[0])
|
|
952
975
|
pnl -= funding_delta.cumsum()
|
|
953
976
|
if commission_factor:
|
|
954
|
-
comm = portfolio.filter(regex=f"
|
|
977
|
+
comm = portfolio.filter(regex=f".*:{asset}USD.*_Commissions").loc[start:stop].sum(axis=1).cumsum()
|
|
955
978
|
pnl -= comm * commission_factor
|
|
956
979
|
return pnl / init_capital * 100 if pct_from_initial_capital else pnl
|
|
957
980
|
|
|
@@ -959,10 +982,11 @@ class TradingSessionResult:
|
|
|
959
982
|
self,
|
|
960
983
|
start: OptTimestamp = None,
|
|
961
984
|
stop: OptTimestamp = None,
|
|
985
|
+
commission_factor: float = 1.0,
|
|
962
986
|
pct_from_initial_capital: bool = False,
|
|
963
987
|
drop_zero: bool = True,
|
|
964
988
|
include_funding: bool = False,
|
|
965
|
-
) -> pd.
|
|
989
|
+
) -> pd.DataFrame:
|
|
966
990
|
start = start or self.start
|
|
967
991
|
stop = stop or self.stop
|
|
968
992
|
assets = set()
|
|
@@ -976,13 +1000,60 @@ class TradingSessionResult:
|
|
|
976
1000
|
assets.add(instrument.asset)
|
|
977
1001
|
asset_to_pnl = {}
|
|
978
1002
|
for asset in assets:
|
|
979
|
-
pnl = self.get_asset_pnl(
|
|
1003
|
+
pnl = self.get_asset_pnl(
|
|
1004
|
+
asset,
|
|
1005
|
+
start,
|
|
1006
|
+
stop,
|
|
1007
|
+
commission_factor=commission_factor,
|
|
1008
|
+
pct_from_initial_capital=pct_from_initial_capital,
|
|
1009
|
+
include_funding=include_funding,
|
|
1010
|
+
)
|
|
980
1011
|
if pnl is not None and not pnl.empty:
|
|
981
|
-
|
|
982
|
-
if drop_zero and last_pnl == 0:
|
|
1012
|
+
if drop_zero and pnl.iloc[-1] == 0:
|
|
983
1013
|
continue
|
|
984
|
-
asset_to_pnl[asset] =
|
|
985
|
-
|
|
1014
|
+
asset_to_pnl[asset] = pnl
|
|
1015
|
+
if not asset_to_pnl:
|
|
1016
|
+
return pd.DataFrame(dtype=float)
|
|
1017
|
+
return pd.DataFrame(asset_to_pnl)
|
|
1018
|
+
|
|
1019
|
+
def get_pnl_total(
|
|
1020
|
+
self,
|
|
1021
|
+
start: OptTimestamp = None,
|
|
1022
|
+
stop: OptTimestamp = None,
|
|
1023
|
+
commission_factor: float = 1.0,
|
|
1024
|
+
pct_from_initial_capital: bool = False,
|
|
1025
|
+
include_funding: bool = False,
|
|
1026
|
+
) -> pd.Series:
|
|
1027
|
+
return (
|
|
1028
|
+
self.get_pnl_per_asset(
|
|
1029
|
+
start,
|
|
1030
|
+
stop,
|
|
1031
|
+
commission_factor=commission_factor,
|
|
1032
|
+
pct_from_initial_capital=pct_from_initial_capital,
|
|
1033
|
+
include_funding=include_funding,
|
|
1034
|
+
)
|
|
1035
|
+
.sum(axis=1)
|
|
1036
|
+
.rename("pnl_total")
|
|
1037
|
+
)
|
|
1038
|
+
|
|
1039
|
+
def get_pnl_breakdown(
|
|
1040
|
+
self,
|
|
1041
|
+
start: OptTimestamp = None,
|
|
1042
|
+
stop: OptTimestamp = None,
|
|
1043
|
+
pct_from_initial_capital: bool = False,
|
|
1044
|
+
drop_zero: bool = True,
|
|
1045
|
+
include_funding: bool = False,
|
|
1046
|
+
) -> pd.Series:
|
|
1047
|
+
df = self.get_pnl_per_asset(
|
|
1048
|
+
start,
|
|
1049
|
+
stop,
|
|
1050
|
+
pct_from_initial_capital=pct_from_initial_capital,
|
|
1051
|
+
drop_zero=drop_zero,
|
|
1052
|
+
include_funding=include_funding,
|
|
1053
|
+
)
|
|
1054
|
+
if df.empty:
|
|
1055
|
+
return pd.Series(dtype=float)
|
|
1056
|
+
return df.iloc[-1].sort_values(ascending=False).rename("pnl_breakdown")
|
|
986
1057
|
|
|
987
1058
|
def get_position_asset(self, asset: str, start: OptTimestamp = None, stop: OptTimestamp = None) -> pd.DataFrame:
|
|
988
1059
|
pos = self.portfolio_log.filter(regex=f".*{asset}.*_Pos")
|
|
@@ -2062,6 +2133,14 @@ def calculate_leverage(
|
|
|
2062
2133
|
return (value.squeeze() / capital).mul(100).rename("Leverage") # type: ignore
|
|
2063
2134
|
|
|
2064
2135
|
|
|
2136
|
+
def calculate_gross_leverage(portfolio: pd.DataFrame, init_capital: float, start: str | pd.Timestamp) -> pd.Series:
|
|
2137
|
+
total_pnl = calculate_total_pnl(portfolio, split_cumulative=False).loc[start:]
|
|
2138
|
+
capital = init_capital + total_pnl["Total_PnL"].cumsum() - total_pnl["Total_Commissions"].cumsum()
|
|
2139
|
+
value_columns = [col for col in portfolio.columns if "_Value" in col]
|
|
2140
|
+
abs_value = portfolio[value_columns].loc[start:].abs().sum(axis=1)
|
|
2141
|
+
return (abs_value / capital).mul(100).rename("Gross Leverage")
|
|
2142
|
+
|
|
2143
|
+
|
|
2065
2144
|
def calculate_leverage_per_symbol(
|
|
2066
2145
|
session: TradingSessionResult,
|
|
2067
2146
|
start: str | pd.Timestamp | None = None,
|
|
@@ -2173,6 +2252,39 @@ def _slice_df(df: pd.DataFrame, start: OptTimestamp = None, stop: OptTimestamp =
|
|
|
2173
2252
|
return df
|
|
2174
2253
|
|
|
2175
2254
|
|
|
2255
|
+
def calculate_commissions_per_symbol(
|
|
2256
|
+
portfolio_log: pd.DataFrame, start: OptTimestamp = None, stop: OptTimestamp = None
|
|
2257
|
+
) -> pd.DataFrame:
|
|
2258
|
+
"""Calculate cumulative commissions for each symbol in the trading session."""
|
|
2259
|
+
return _slice_df(portfolio_log.filter(like="_Commissions"), start, stop).cumsum()
|
|
2260
|
+
|
|
2261
|
+
|
|
2262
|
+
def calculate_commissions_per_asset(
|
|
2263
|
+
portfolio_log: pd.DataFrame,
|
|
2264
|
+
start: OptTimestamp = None,
|
|
2265
|
+
stop: OptTimestamp = None,
|
|
2266
|
+
filter_zero: bool = True,
|
|
2267
|
+
) -> pd.DataFrame:
|
|
2268
|
+
"""
|
|
2269
|
+
Calculate cumulative commissions for each asset in the trading session.
|
|
2270
|
+
"""
|
|
2271
|
+
df = calculate_commissions_per_symbol(portfolio_log, start, stop)
|
|
2272
|
+
df = df.rename(columns=lambda x: x.replace("_Commissions", ""))
|
|
2273
|
+
|
|
2274
|
+
# Map each column (EXCHANGE:SYMBOL) to its asset name
|
|
2275
|
+
col_to_asset: dict[str, str] = {}
|
|
2276
|
+
for col in df.columns:
|
|
2277
|
+
exchange, symbol = col.split(":")
|
|
2278
|
+
instr = lookup.find_symbol(exchange, symbol)
|
|
2279
|
+
col_to_asset[col] = instr.asset if instr else col
|
|
2280
|
+
|
|
2281
|
+
# Group by asset and sum
|
|
2282
|
+
df = df.rename(columns=col_to_asset).T.groupby(level=0).sum().T
|
|
2283
|
+
if filter_zero:
|
|
2284
|
+
df = df.loc[:, df.ne(0).any(axis=0)]
|
|
2285
|
+
return df
|
|
2286
|
+
|
|
2287
|
+
|
|
2176
2288
|
def calculate_funding_per_symbol(
|
|
2177
2289
|
portfolio_log: pd.DataFrame, start: OptTimestamp = None, stop: OptTimestamp = None
|
|
2178
2290
|
) -> pd.DataFrame:
|
|
@@ -143,7 +143,9 @@ class MultiReader(IReader):
|
|
|
143
143
|
dtype_ref = result.dtype
|
|
144
144
|
batches.append(result.data)
|
|
145
145
|
except Exception as e:
|
|
146
|
-
|
|
146
|
+
# - expected when one storage doesn't carry this dtype (e.g. QuestDB has no
|
|
147
|
+
# vendor microstructure tables); the next reader will be tried
|
|
148
|
+
logger.debug(f"{reader.__class__.__name__} has no '{data_id}' ({dtype}): {e}")
|
|
147
149
|
|
|
148
150
|
return batches, time_idx, schema, dtype_ref
|
|
149
151
|
|
|
@@ -180,9 +182,14 @@ class MultiReader(IReader):
|
|
|
180
182
|
time_idx = raw.index
|
|
181
183
|
dtype_ref = raw.dtype
|
|
182
184
|
except Exception as e:
|
|
183
|
-
|
|
185
|
+
# - expected when one storage doesn't carry this dtype; the next reader will be tried
|
|
186
|
+
logger.debug(f"{reader.__class__.__name__} has no ({dtype}) for multi data_ids: {e}")
|
|
184
187
|
|
|
185
188
|
if not batches_per_id:
|
|
189
|
+
# - all readers exhausted with no data — only now it's worth a warning
|
|
190
|
+
logger.warning(
|
|
191
|
+
f"No data for ({dtype}) in any of {len(self._readers)} reader(s): {[r.__class__.__name__ for r in self._readers]}"
|
|
192
|
+
)
|
|
186
193
|
return RawMultiData([])
|
|
187
194
|
|
|
188
195
|
merged_raws = [
|
|
@@ -239,7 +246,9 @@ class MultiReader(IReader):
|
|
|
239
246
|
if ts_name is None:
|
|
240
247
|
ts_name = f.name
|
|
241
248
|
ts_unit = f.type.unit
|
|
242
|
-
elif f.name == ts_name and _precision_rank.get(f.type.unit, 0) > _precision_rank.get(
|
|
249
|
+
elif f.name == ts_name and _precision_rank.get(f.type.unit, 0) > _precision_rank.get(
|
|
250
|
+
ts_unit or "s", 0
|
|
251
|
+
):
|
|
243
252
|
ts_unit = f.type.unit
|
|
244
253
|
# - fallback: if no timestamp column found, default to "ms"
|
|
245
254
|
ts_unit = ts_unit or "ms"
|
|
@@ -407,11 +416,14 @@ class MultiStorage(IStorage):
|
|
|
407
416
|
|
|
408
417
|
def __init__(
|
|
409
418
|
self,
|
|
410
|
-
storages: list[IStorage],
|
|
419
|
+
storages: list[str | IStorage],
|
|
411
420
|
tolerance: str | None = None,
|
|
412
421
|
keep: str = "last",
|
|
413
422
|
):
|
|
414
|
-
|
|
423
|
+
from qubx.data.registry import StorageRegistry
|
|
424
|
+
|
|
425
|
+
# - resolve string URIs (e.g. "qdb::quantlab") to IStorage instances
|
|
426
|
+
self._storages = [StorageRegistry.get(s) if isinstance(s, str) else s for s in storages]
|
|
415
427
|
self._tolerance = tolerance
|
|
416
428
|
self._keep = keep
|
|
417
429
|
self._reader_cache: dict[tuple[str, str], IReader] = {}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex_account.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/hyperliquid/__init__.py
RENAMED
|
File without changes
|
{qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/hyperliquid/account.py
RENAMED
|
File without changes
|
{qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/src/qubx/connectors/ccxt/exchanges/hyperliquid/broker.py
RENAMED
|
File without changes
|
{qubx-1.1.2.dev4 → qubx-1.1.2.dev6}/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
|