Qubx 1.1.2.dev4__tar.gz → 1.1.2.dev5__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.
Files changed (294) hide show
  1. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/PKG-INFO +1 -1
  2. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/_version.py +2 -2
  3. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/metrics.py +121 -9
  4. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/.gitignore +0 -0
  5. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/LICENSE +0 -0
  6. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/README.md +0 -0
  7. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/pyproject.toml +0 -0
  8. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/scripts/build.py +0 -0
  9. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/__init__.py +0 -0
  10. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/_nb_magic.py +0 -0
  11. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/__init__.py +0 -0
  12. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/account.py +0 -0
  13. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/broker.py +0 -0
  14. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/data.py +0 -0
  15. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/iteratedstream.py +0 -0
  16. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/management.py +0 -0
  17. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/ome.py +0 -0
  18. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/optimization.py +0 -0
  19. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/runner.py +0 -0
  20. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/sentinels.py +0 -0
  21. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/simulated_data.py +0 -0
  22. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/simulated_exchange.py +0 -0
  23. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/simulator.py +0 -0
  24. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/transfers.py +0 -0
  25. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/backtester/utils.py +0 -0
  26. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/cli/__init__.py +0 -0
  27. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/cli/commands.py +0 -0
  28. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/cli/deploy.py +0 -0
  29. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/cli/misc.py +0 -0
  30. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/cli/release.py +0 -0
  31. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/cli/resolver.py +0 -0
  32. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/cli/s3.py +0 -0
  33. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/cli/theme.py +0 -0
  34. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/cli/tui.py +0 -0
  35. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/cli/user_config.py +0 -0
  36. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/config.py +0 -0
  37. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/__init__.py +0 -0
  38. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/__init__.py +0 -0
  39. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/account.py +0 -0
  40. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/adapters/__init__.py +0 -0
  41. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/adapters/polling_adapter.py +0 -0
  42. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/broker.py +0 -0
  43. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/connection_manager.py +0 -0
  44. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/data.py +0 -0
  45. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exceptions.py +0 -0
  46. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchange_manager.py +0 -0
  47. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/__init__.py +0 -0
  48. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/base.py +0 -0
  49. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/binance/broker.py +0 -0
  50. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/binance/exchange.py +0 -0
  51. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex.py +0 -0
  52. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex_account.py +0 -0
  53. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/gateio/__init__.py +0 -0
  54. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/gateio/gateio.py +0 -0
  55. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/hyperliquid/__init__.py +0 -0
  56. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/hyperliquid/account.py +0 -0
  57. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/hyperliquid/broker.py +0 -0
  58. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/hyperliquid/hyperliquid.py +0 -0
  59. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/kraken/kraken.py +0 -0
  60. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/okx/__init__.py +0 -0
  61. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/okx/account.py +0 -0
  62. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/okx/broker.py +0 -0
  63. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/exchanges/okx/okx.py +0 -0
  64. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/factory.py +0 -0
  65. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/handlers/__init__.py +0 -0
  66. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/handlers/base.py +0 -0
  67. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/handlers/factory.py +0 -0
  68. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/handlers/funding_rate.py +0 -0
  69. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/handlers/liquidation.py +0 -0
  70. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/handlers/ohlc.py +0 -0
  71. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/handlers/open_interest.py +0 -0
  72. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/handlers/orderbook.py +0 -0
  73. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/handlers/quote.py +0 -0
  74. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/handlers/trade.py +0 -0
  75. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/subscription_config.py +0 -0
  76. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/subscription_manager.py +0 -0
  77. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/subscription_orchestrator.py +0 -0
  78. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/utils.py +0 -0
  79. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/ccxt/warmup_service.py +0 -0
  80. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/registry.py +0 -0
  81. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/tardis/data.py +0 -0
  82. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/connectors/tardis/utils.py +0 -0
  83. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/__init__.py +0 -0
  84. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/account.py +0 -0
  85. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/basics.py +0 -0
  86. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/context.py +0 -0
  87. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/detectors/__init__.py +0 -0
  88. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/detectors/delisting.py +0 -0
  89. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/detectors/stale.py +0 -0
  90. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/errors.py +0 -0
  91. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/exceptions.py +0 -0
  92. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/helpers.py +0 -0
  93. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/initializer.py +0 -0
  94. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/interfaces.py +0 -0
  95. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/loggers.py +0 -0
  96. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/lookups.py +0 -0
  97. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/mixins/__init__.py +0 -0
  98. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/mixins/market.py +0 -0
  99. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/mixins/processing.py +0 -0
  100. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/mixins/subscription.py +0 -0
  101. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/mixins/trading.py +0 -0
  102. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/mixins/universe.py +0 -0
  103. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/mixins/utils.py +0 -0
  104. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/series.pxd +0 -0
  105. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/series.pyi +0 -0
  106. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/series.pyx +0 -0
  107. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/utils.pyi +0 -0
  108. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/core/utils.pyx +0 -0
  109. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/__init__.py +0 -0
  110. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/cache.py +0 -0
  111. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/containers.py +0 -0
  112. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/guards.py +0 -0
  113. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/registry.py +0 -0
  114. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/storage.py +0 -0
  115. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/storages/ccxt.py +0 -0
  116. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/storages/csv.py +0 -0
  117. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/storages/handy.py +0 -0
  118. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/storages/multi.py +0 -0
  119. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/storages/questdb.py +0 -0
  120. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/storages/stub.py +0 -0
  121. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/storages/utils.py +0 -0
  122. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/data/transformers.py +0 -0
  123. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/emitters/__init__.py +0 -0
  124. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/emitters/base.py +0 -0
  125. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/emitters/composite.py +0 -0
  126. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/emitters/csv.py +0 -0
  127. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/emitters/indicator.py +0 -0
  128. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/emitters/inmemory.py +0 -0
  129. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/emitters/prometheus.py +0 -0
  130. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/emitters/questdb.py +0 -0
  131. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/exporters/__init__.py +0 -0
  132. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/exporters/composite.py +0 -0
  133. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/exporters/formatters/__init__.py +0 -0
  134. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/exporters/formatters/base.py +0 -0
  135. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/exporters/formatters/incremental.py +0 -0
  136. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/exporters/formatters/slack.py +0 -0
  137. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/exporters/formatters/target_position.py +0 -0
  138. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/exporters/redis_streams.py +0 -0
  139. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/exporters/slack.py +0 -0
  140. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/gathering/simplest.py +0 -0
  141. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/health/__init__.py +0 -0
  142. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/health/base.py +0 -0
  143. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/health/dummy.py +0 -0
  144. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/health/server.py +0 -0
  145. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/loggers/__init__.py +0 -0
  146. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/loggers/csv.py +0 -0
  147. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/loggers/factory.py +0 -0
  148. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/loggers/inmemory.py +0 -0
  149. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/loggers/mongo.py +0 -0
  150. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/notifications/__init__.py +0 -0
  151. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/notifications/composite.py +0 -0
  152. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/notifications/slack.py +0 -0
  153. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/notifications/throttler.py +0 -0
  154. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/pandaz/__init__.py +0 -0
  155. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/pandaz/stats.py +0 -0
  156. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/pandaz/ta.py +0 -0
  157. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/pandaz/utils.py +0 -0
  158. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/plugins/__init__.py +0 -0
  159. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/plugins/loader.py +0 -0
  160. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/resources/_build.py +0 -0
  161. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/resources/crypto-fees.ini +0 -0
  162. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/resources/instruments/hyperliquid-spot.json +0 -0
  163. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/resources/instruments/hyperliquid.f-perpetual.json +0 -0
  164. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/resources/instruments/symbols-binance-spot.json +0 -0
  165. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/resources/instruments/symbols-binance.cm-future.json +0 -0
  166. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/resources/instruments/symbols-binance.cm-perpetual.json +0 -0
  167. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/resources/instruments/symbols-binance.um-future.json +0 -0
  168. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/resources/instruments/symbols-binance.um-perpetual.json +0 -0
  169. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/resources/instruments/symbols-bitfinex.f-perpetual.json +0 -0
  170. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/resources/instruments/symbols-kraken-spot.json +0 -0
  171. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/resources/instruments/symbols-kraken.f-future.json +0 -0
  172. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/resources/instruments/symbols-kraken.f-perpetual.json +0 -0
  173. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/restarts/__init__.py +0 -0
  174. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/restarts/state_resolvers.py +0 -0
  175. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/restarts/time_finders.py +0 -0
  176. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/restorers/__init__.py +0 -0
  177. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/restorers/balance.py +0 -0
  178. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/restorers/factory.py +0 -0
  179. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/restorers/interfaces.py +0 -0
  180. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/restorers/position.py +0 -0
  181. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/restorers/signal.py +0 -0
  182. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/restorers/state.py +0 -0
  183. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/restorers/utils.py +0 -0
  184. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/state/__init__.py +0 -0
  185. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/state/dummy.py +0 -0
  186. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/state/redis.py +0 -0
  187. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/ta/__init__.py +0 -0
  188. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/ta/indicators.pxd +0 -0
  189. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/ta/indicators.pyi +0 -0
  190. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/ta/indicators.pyx +0 -0
  191. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/__init__.py +0 -0
  192. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/base.py +0 -0
  193. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/project/accounts.toml.j2 +0 -0
  194. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/project/config.yml.j2 +0 -0
  195. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/project/jlive.sh.j2 +0 -0
  196. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/project/jpaper.sh.j2 +0 -0
  197. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/project/pyproject.toml.j2 +0 -0
  198. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/project/src/{{ strategy_name }}/__init__.py.j2 +0 -0
  199. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/project/src/{{ strategy_name }}/strategy.py.j2 +0 -0
  200. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/project/template.yml +0 -0
  201. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/.claude/skills/qubx-cli/SKILL.md +0 -0
  202. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/.claude/skills/qubx-indicators/SKILL.md +0 -0
  203. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/.claude/skills/simulation-explorer/SKILL.md +0 -0
  204. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/.claude/skills/strategy-release/SKILL.md +0 -0
  205. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/.github/workflows/ci.yml.j2 +0 -0
  206. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/.gitignore.j2 +0 -0
  207. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/.python-version +0 -0
  208. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/.vscode/launch.json +0 -0
  209. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/.vscode/settings.json +0 -0
  210. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/.vscode/tasks.json +0 -0
  211. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/CLAUDE.md.j2 +0 -0
  212. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/README.md.j2 +0 -0
  213. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/configs/.gitkeep +0 -0
  214. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/justfile.j2 +0 -0
  215. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/pyproject.toml.j2 +0 -0
  216. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/research/.gitkeep +0 -0
  217. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/src/{{ strategy_name }}/__init__.py.j2 +0 -0
  218. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/src/{{ strategy_name }}/cli.py.j2 +0 -0
  219. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/src/{{ strategy_name }}/strategy.py.j2 +0 -0
  220. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/template.yml +0 -0
  221. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/repo/tests/test_strategy.py.j2 +0 -0
  222. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/simple/__init__.py.j2 +0 -0
  223. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/simple/accounts.toml.j2 +0 -0
  224. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/simple/config.yml.j2 +0 -0
  225. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/simple/jlive.sh.j2 +0 -0
  226. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/simple/jpaper.sh.j2 +0 -0
  227. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/simple/strategy.py.j2 +0 -0
  228. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/templates/simple/template.yml +0 -0
  229. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/trackers/__init__.py +0 -0
  230. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/trackers/advanced.py +0 -0
  231. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/trackers/composite.py +0 -0
  232. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/trackers/rebalancers.py +0 -0
  233. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/trackers/riskctrl.py +0 -0
  234. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/trackers/sizers.py +0 -0
  235. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/__init__.py +0 -0
  236. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/_pyxreloader.py +0 -0
  237. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/charting/lookinglass.py +0 -0
  238. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/charting/mpl_helpers.py +0 -0
  239. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/charting/orderbook.py +0 -0
  240. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/collections.py +0 -0
  241. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/hft/__init__.py +0 -0
  242. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/hft/numba_utils.py +0 -0
  243. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/hft/orderbook.pyi +0 -0
  244. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/hft/orderbook.pyx +0 -0
  245. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/marketdata/binance.py +0 -0
  246. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/marketdata/ccxt.py +0 -0
  247. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/marketdata/dukas.py +0 -0
  248. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/misc.py +0 -0
  249. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/nonce.py +0 -0
  250. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/ntp.py +0 -0
  251. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/numbers_utils.py +0 -0
  252. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/orderbook.py +0 -0
  253. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/plotting/__init__.py +0 -0
  254. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/plotting/dashboard.py +0 -0
  255. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/plotting/data.py +0 -0
  256. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/plotting/interfaces.py +0 -0
  257. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/plotting/renderers/__init__.py +0 -0
  258. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/plotting/renderers/plotly.py +0 -0
  259. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/questdb.py +0 -0
  260. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/rate_limiter.py +0 -0
  261. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/results.py +0 -0
  262. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/ringbuffer.pxd +0 -0
  263. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/ringbuffer.pyi +0 -0
  264. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/ringbuffer.pyx +0 -0
  265. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/__init__.py +0 -0
  266. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/_jupyter_runner.pyt +0 -0
  267. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/accounts.py +0 -0
  268. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/configs.py +0 -0
  269. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/factory.py +0 -0
  270. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/kernel_service.py +0 -0
  271. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/runner.py +0 -0
  272. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/__init__.py +0 -0
  273. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/app.py +0 -0
  274. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/handlers.py +0 -0
  275. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/init_code.py +0 -0
  276. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/kernel.py +0 -0
  277. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/styles.tcss +0 -0
  278. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/widgets/__init__.py +0 -0
  279. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/widgets/account_summary.py +0 -0
  280. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/widgets/command_input.py +0 -0
  281. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/widgets/debug_log.py +0 -0
  282. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/widgets/orders_table.py +0 -0
  283. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/widgets/positions_table.py +0 -0
  284. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/widgets/quotes_table.py +0 -0
  285. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/runner/textual/widgets/repl_output.py +0 -0
  286. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/s3.py +0 -0
  287. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/slack.py +0 -0
  288. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/throttler.py +0 -0
  289. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/time.py +0 -0
  290. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/src/qubx/utils/websocket_manager.py +0 -0
  291. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/tests/strategies/macd_crossover/src/macd_crossover/indicators/macd.py +0 -0
  292. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/tests/strategies/macd_crossover/src/macd_crossover/models/macd_crossover.py +0 -0
  293. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/tests/strategies/macd_crossover/src/macd_crossover/models/utils.py +0 -0
  294. {qubx-1.1.2.dev4 → qubx-1.1.2.dev5}/tests/strategies/obi_trader/src/obi_trader/models/obi_trader.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Qubx
3
- Version: 1.1.2.dev4
3
+ Version: 1.1.2.dev5
4
4
  Summary: Qubx - Quantitative Trading Framework
5
5
  Project-URL: homepage, https://xlydian.com
6
6
  Project-URL: repository, https://github.com/xLydianSoftware/Qubx
@@ -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.dev4'
22
- __version_tuple__ = version_tuple = (1, 1, 2, 'dev4')
21
+ __version__ = version = '1.1.2.dev5'
22
+ __version_tuple__ = version_tuple = (1, 1, 2, 'dev5')
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 get_funding_pnl(self, start: OptTimestamp = None, stop: OptTimestamp = None) -> pd.Series:
932
- return self.get_funding_per_asset(start, stop).iloc[-1].sort_values(ascending=False).rename("funding_pnl")
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".*{asset}.*_Commissions").loc[start:stop].sum(axis=1).cumsum()
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.Series:
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(asset, start, stop, pct_from_initial_capital=pct_from_initial_capital, include_funding=include_funding)
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
- last_pnl = pnl.iloc[-1]
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] = last_pnl
985
- return pd.Series(asset_to_pnl).sort_values(ascending=False)
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:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes