Qubx 1.1.3.dev11__tar.gz → 1.1.3.dev13__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 (308) hide show
  1. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/PKG-INFO +1 -1
  2. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/_version.py +2 -2
  3. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/context.py +2 -0
  4. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/mixins/processing.py +7 -11
  5. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/rate_limiting/backend.py +8 -3
  6. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/rate_limiting/engine.py +1 -1
  7. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/rate_limiting/redis_backend.py +22 -13
  8. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/runner.py +1 -4
  9. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/.gitignore +0 -0
  10. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/LICENSE +0 -0
  11. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/README.md +0 -0
  12. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/pyproject.toml +0 -0
  13. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/scripts/build.py +0 -0
  14. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/__init__.py +0 -0
  15. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/_nb_magic.py +0 -0
  16. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/__init__.py +0 -0
  17. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/account.py +0 -0
  18. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/broker.py +0 -0
  19. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/data.py +0 -0
  20. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/iteratedstream.py +0 -0
  21. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/management.py +0 -0
  22. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/ome.py +0 -0
  23. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/optimization.py +0 -0
  24. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/runner.py +0 -0
  25. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/sentinels.py +0 -0
  26. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/simulated_data.py +0 -0
  27. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/simulated_exchange.py +0 -0
  28. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/simulator.py +0 -0
  29. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/transfers.py +0 -0
  30. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/backtester/utils.py +0 -0
  31. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/cli/__init__.py +0 -0
  32. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/cli/commands.py +0 -0
  33. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/cli/deploy.py +0 -0
  34. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/cli/misc.py +0 -0
  35. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/cli/release.py +0 -0
  36. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/cli/resolver.py +0 -0
  37. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/cli/s3.py +0 -0
  38. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/cli/theme.py +0 -0
  39. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/cli/tui.py +0 -0
  40. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/cli/user_config.py +0 -0
  41. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/config.py +0 -0
  42. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/__init__.py +0 -0
  43. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/__init__.py +0 -0
  44. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/account.py +0 -0
  45. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/adapters/__init__.py +0 -0
  46. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/adapters/polling_adapter.py +0 -0
  47. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/broker.py +0 -0
  48. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/connection_manager.py +0 -0
  49. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/data.py +0 -0
  50. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exceptions.py +0 -0
  51. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchange_manager.py +0 -0
  52. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/__init__.py +0 -0
  53. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/base.py +0 -0
  54. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/binance/broker.py +0 -0
  55. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/binance/exchange.py +0 -0
  56. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex.py +0 -0
  57. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex_account.py +0 -0
  58. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/gateio/__init__.py +0 -0
  59. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/gateio/gateio.py +0 -0
  60. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/hyperliquid/__init__.py +0 -0
  61. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/hyperliquid/account.py +0 -0
  62. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/hyperliquid/broker.py +0 -0
  63. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/hyperliquid/hyperliquid.py +0 -0
  64. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/kraken/kraken.py +0 -0
  65. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/okx/__init__.py +0 -0
  66. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/okx/account.py +0 -0
  67. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/okx/broker.py +0 -0
  68. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/exchanges/okx/okx.py +0 -0
  69. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/factory.py +0 -0
  70. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/handlers/__init__.py +0 -0
  71. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/handlers/base.py +0 -0
  72. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/handlers/factory.py +0 -0
  73. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/handlers/funding_rate.py +0 -0
  74. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/handlers/liquidation.py +0 -0
  75. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/handlers/ohlc.py +0 -0
  76. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/handlers/open_interest.py +0 -0
  77. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/handlers/orderbook.py +0 -0
  78. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/handlers/quote.py +0 -0
  79. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/handlers/trade.py +0 -0
  80. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/rate_limits.py +0 -0
  81. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/subscription_config.py +0 -0
  82. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/subscription_manager.py +0 -0
  83. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/subscription_orchestrator.py +0 -0
  84. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/utils.py +0 -0
  85. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/ccxt/warmup_service.py +0 -0
  86. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/registry.py +0 -0
  87. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/tardis/data.py +0 -0
  88. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/connectors/tardis/utils.py +0 -0
  89. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/control/__init__.py +0 -0
  90. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/control/builtin.py +0 -0
  91. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/control/decorator.py +0 -0
  92. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/control/executor.py +0 -0
  93. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/control/interfaces.py +0 -0
  94. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/control/server.py +0 -0
  95. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/control/types.py +0 -0
  96. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/__init__.py +0 -0
  97. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/account.py +0 -0
  98. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/basics.py +0 -0
  99. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/detectors/__init__.py +0 -0
  100. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/detectors/delisting.py +0 -0
  101. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/detectors/stale.py +0 -0
  102. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/errors.py +0 -0
  103. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/exceptions.py +0 -0
  104. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/helpers.py +0 -0
  105. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/initializer.py +0 -0
  106. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/interfaces.py +0 -0
  107. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/loggers.py +0 -0
  108. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/lookups.py +0 -0
  109. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/metrics.py +0 -0
  110. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/mixins/__init__.py +0 -0
  111. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/mixins/market.py +0 -0
  112. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/mixins/subscription.py +0 -0
  113. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/mixins/trading.py +0 -0
  114. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/mixins/universe.py +0 -0
  115. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/mixins/utils.py +0 -0
  116. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/series.pxd +0 -0
  117. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/series.pyi +0 -0
  118. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/series.pyx +0 -0
  119. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/utils.pyi +0 -0
  120. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/core/utils.pyx +0 -0
  121. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/__init__.py +0 -0
  122. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/cache.py +0 -0
  123. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/containers.py +0 -0
  124. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/guards.py +0 -0
  125. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/registry.py +0 -0
  126. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/storage.py +0 -0
  127. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/storages/ccxt.py +0 -0
  128. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/storages/csv.py +0 -0
  129. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/storages/handy.py +0 -0
  130. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/storages/multi.py +0 -0
  131. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/storages/questdb.py +0 -0
  132. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/storages/stub.py +0 -0
  133. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/storages/utils.py +0 -0
  134. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/data/transformers.py +0 -0
  135. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/emitters/__init__.py +0 -0
  136. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/emitters/base.py +0 -0
  137. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/emitters/composite.py +0 -0
  138. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/emitters/csv.py +0 -0
  139. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/emitters/indicator.py +0 -0
  140. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/emitters/inmemory.py +0 -0
  141. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/emitters/prometheus.py +0 -0
  142. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/emitters/questdb.py +0 -0
  143. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/exporters/__init__.py +0 -0
  144. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/exporters/composite.py +0 -0
  145. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/exporters/formatters/__init__.py +0 -0
  146. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/exporters/formatters/base.py +0 -0
  147. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/exporters/formatters/incremental.py +0 -0
  148. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/exporters/formatters/slack.py +0 -0
  149. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/exporters/formatters/target_position.py +0 -0
  150. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/exporters/redis_streams.py +0 -0
  151. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/exporters/slack.py +0 -0
  152. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/gathering/simplest.py +0 -0
  153. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/health/__init__.py +0 -0
  154. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/health/base.py +0 -0
  155. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/health/dummy.py +0 -0
  156. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/loggers/__init__.py +0 -0
  157. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/loggers/csv.py +0 -0
  158. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/loggers/factory.py +0 -0
  159. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/loggers/inmemory.py +0 -0
  160. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/loggers/mongo.py +0 -0
  161. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/loggers/postgres.py +0 -0
  162. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/notifications/__init__.py +0 -0
  163. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/notifications/composite.py +0 -0
  164. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/notifications/slack.py +0 -0
  165. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/notifications/throttler.py +0 -0
  166. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/pandaz/__init__.py +0 -0
  167. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/pandaz/stats.py +0 -0
  168. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/pandaz/ta.py +0 -0
  169. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/pandaz/utils.py +0 -0
  170. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/plugins/__init__.py +0 -0
  171. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/plugins/loader.py +0 -0
  172. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/rate_limiting/__init__.py +0 -0
  173. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/rate_limiting/config.py +0 -0
  174. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/rate_limiting/ip_resolver.py +0 -0
  175. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/resources/_build.py +0 -0
  176. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/resources/crypto-fees.ini +0 -0
  177. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/resources/instruments/hyperliquid-spot.json +0 -0
  178. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/resources/instruments/hyperliquid.f-perpetual.json +0 -0
  179. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/resources/instruments/symbols-binance-spot.json +0 -0
  180. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/resources/instruments/symbols-binance.cm-future.json +0 -0
  181. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/resources/instruments/symbols-binance.cm-perpetual.json +0 -0
  182. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/resources/instruments/symbols-binance.um-future.json +0 -0
  183. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/resources/instruments/symbols-binance.um-perpetual.json +0 -0
  184. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/resources/instruments/symbols-bitfinex.f-perpetual.json +0 -0
  185. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/resources/instruments/symbols-kraken-spot.json +0 -0
  186. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/resources/instruments/symbols-kraken.f-future.json +0 -0
  187. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/resources/instruments/symbols-kraken.f-perpetual.json +0 -0
  188. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/restarts/__init__.py +0 -0
  189. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/restarts/state_resolvers.py +0 -0
  190. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/restarts/time_finders.py +0 -0
  191. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/restorers/__init__.py +0 -0
  192. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/restorers/balance.py +0 -0
  193. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/restorers/factory.py +0 -0
  194. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/restorers/interfaces.py +0 -0
  195. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/restorers/position.py +0 -0
  196. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/restorers/signal.py +0 -0
  197. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/restorers/state.py +0 -0
  198. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/restorers/utils.py +0 -0
  199. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/state/__init__.py +0 -0
  200. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/state/dummy.py +0 -0
  201. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/state/redis.py +0 -0
  202. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/ta/__init__.py +0 -0
  203. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/ta/indicators.pxd +0 -0
  204. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/ta/indicators.pyi +0 -0
  205. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/ta/indicators.pyx +0 -0
  206. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/__init__.py +0 -0
  207. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/base.py +0 -0
  208. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/project/accounts.toml.j2 +0 -0
  209. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/project/config.yml.j2 +0 -0
  210. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/project/jlive.sh.j2 +0 -0
  211. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/project/jpaper.sh.j2 +0 -0
  212. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/project/pyproject.toml.j2 +0 -0
  213. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/project/src/{{ strategy_name }}/__init__.py.j2 +0 -0
  214. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/project/src/{{ strategy_name }}/strategy.py.j2 +0 -0
  215. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/project/template.yml +0 -0
  216. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/.claude/skills/qubx-cli/SKILL.md +0 -0
  217. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/.claude/skills/qubx-indicators/SKILL.md +0 -0
  218. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/.claude/skills/simulation-explorer/SKILL.md +0 -0
  219. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/.claude/skills/strategy-release/SKILL.md +0 -0
  220. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/.github/workflows/ci.yml.j2 +0 -0
  221. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/.gitignore.j2 +0 -0
  222. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/.python-version +0 -0
  223. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/.vscode/launch.json +0 -0
  224. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/.vscode/settings.json +0 -0
  225. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/.vscode/tasks.json +0 -0
  226. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/CLAUDE.md.j2 +0 -0
  227. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/README.md.j2 +0 -0
  228. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/configs/.gitkeep +0 -0
  229. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/justfile.j2 +0 -0
  230. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/pyproject.toml.j2 +0 -0
  231. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/research/.gitkeep +0 -0
  232. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/src/{{ strategy_name }}/__init__.py.j2 +0 -0
  233. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/src/{{ strategy_name }}/cli.py.j2 +0 -0
  234. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/src/{{ strategy_name }}/strategy.py.j2 +0 -0
  235. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/template.yml +0 -0
  236. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/repo/tests/test_strategy.py.j2 +0 -0
  237. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/simple/__init__.py.j2 +0 -0
  238. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/simple/accounts.toml.j2 +0 -0
  239. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/simple/config.yml.j2 +0 -0
  240. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/simple/jlive.sh.j2 +0 -0
  241. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/simple/jpaper.sh.j2 +0 -0
  242. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/simple/strategy.py.j2 +0 -0
  243. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/templates/simple/template.yml +0 -0
  244. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/trackers/__init__.py +0 -0
  245. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/trackers/advanced.py +0 -0
  246. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/trackers/composite.py +0 -0
  247. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/trackers/rebalancers.py +0 -0
  248. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/trackers/riskctrl.py +0 -0
  249. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/trackers/sizers.py +0 -0
  250. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/__init__.py +0 -0
  251. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/_pyxreloader.py +0 -0
  252. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/charting/lookinglass.py +0 -0
  253. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/charting/mpl_helpers.py +0 -0
  254. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/charting/orderbook.py +0 -0
  255. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/collections.py +0 -0
  256. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/hft/__init__.py +0 -0
  257. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/hft/numba_utils.py +0 -0
  258. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/hft/orderbook.pyi +0 -0
  259. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/hft/orderbook.pyx +0 -0
  260. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/marketdata/binance.py +0 -0
  261. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/marketdata/ccxt.py +0 -0
  262. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/marketdata/dukas.py +0 -0
  263. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/misc.py +0 -0
  264. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/nonce.py +0 -0
  265. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/ntp.py +0 -0
  266. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/numbers_utils.py +0 -0
  267. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/orderbook.py +0 -0
  268. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/plotting/__init__.py +0 -0
  269. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/plotting/dashboard.py +0 -0
  270. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/plotting/data.py +0 -0
  271. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/plotting/interfaces.py +0 -0
  272. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/plotting/renderers/__init__.py +0 -0
  273. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/plotting/renderers/plotly.py +0 -0
  274. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/questdb.py +0 -0
  275. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/rate_limiter.py +0 -0
  276. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/results.py +0 -0
  277. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/ringbuffer.pxd +0 -0
  278. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/ringbuffer.pyi +0 -0
  279. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/ringbuffer.pyx +0 -0
  280. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/__init__.py +0 -0
  281. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/_jupyter_runner.pyt +0 -0
  282. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/accounts.py +0 -0
  283. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/configs.py +0 -0
  284. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/factory.py +0 -0
  285. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/kernel_service.py +0 -0
  286. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/__init__.py +0 -0
  287. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/app.py +0 -0
  288. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/handlers.py +0 -0
  289. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/init_code.py +0 -0
  290. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/kernel.py +0 -0
  291. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/styles.tcss +0 -0
  292. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/widgets/__init__.py +0 -0
  293. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/widgets/account_summary.py +0 -0
  294. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/widgets/command_input.py +0 -0
  295. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/widgets/debug_log.py +0 -0
  296. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/widgets/orders_table.py +0 -0
  297. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/widgets/positions_table.py +0 -0
  298. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/widgets/quotes_table.py +0 -0
  299. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/runner/textual/widgets/repl_output.py +0 -0
  300. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/s3.py +0 -0
  301. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/slack.py +0 -0
  302. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/throttler.py +0 -0
  303. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/time.py +0 -0
  304. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/src/qubx/utils/websocket_manager.py +0 -0
  305. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/tests/strategies/macd_crossover/src/macd_crossover/indicators/macd.py +0 -0
  306. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/tests/strategies/macd_crossover/src/macd_crossover/models/macd_crossover.py +0 -0
  307. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/tests/strategies/macd_crossover/src/macd_crossover/models/utils.py +0 -0
  308. {qubx-1.1.3.dev11 → qubx-1.1.3.dev13}/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.3.dev11
3
+ Version: 1.1.3.dev13
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.3.dev11'
22
- __version_tuple__ = version_tuple = (1, 1, 3, 'dev11')
21
+ __version__ = version = '1.1.3.dev13'
22
+ __version_tuple__ = version_tuple = (1, 1, 3, 'dev13')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -161,6 +161,7 @@ class StrategyContext(IStrategyContext):
161
161
  state_snapshot_interval: str | None = None,
162
162
  rate_limit_backend: Any | None = None,
163
163
  rate_limiting_config: Any | None = None,
164
+ event_loop: "asyncio.AbstractEventLoop | None" = None,
164
165
  ) -> None:
165
166
  self.account = account
166
167
  self.strategy = self.__instantiate_strategy(strategy, config)
@@ -194,6 +195,7 @@ class StrategyContext(IStrategyContext):
194
195
  self._state_snapshot_interval = state_snapshot_interval
195
196
  self._rate_limit_backend = rate_limit_backend
196
197
  self._rate_limiting_config = rate_limiting_config
198
+ self.event_loop = event_loop
197
199
 
198
200
  # Initialize shutdown handling
199
201
  self._stop_lock = Lock()
@@ -314,22 +314,18 @@ class ProcessingManager(IProcessingManager):
314
314
  def _emit_rate_limit_metrics(self, ctx) -> None:
315
315
  """Emit rate limit metrics for all registered rate limiters."""
316
316
  import asyncio
317
+ import concurrent.futures
317
318
 
318
- if ctx.emitter is None:
319
+ if ctx.emitter is None or ctx.event_loop is None:
319
320
  return
320
321
 
321
322
  for exchange_name, rate_limiter in ctx.rate_limiters.items():
322
323
  try:
323
- # collect_metrics is async but we're in sync context
324
- loop = asyncio.get_event_loop()
325
- if loop.is_running():
326
- future = asyncio.ensure_future(rate_limiter.collect_metrics())
327
- future.add_done_callback(
328
- lambda f, _ctx=ctx: self._do_emit_metrics(_ctx, f.result()) if not f.cancelled() else None
329
- )
330
- else:
331
- metrics = loop.run_until_complete(rate_limiter.collect_metrics())
332
- self._do_emit_metrics(ctx, metrics)
324
+ future = asyncio.run_coroutine_threadsafe(rate_limiter.collect_metrics(), ctx.event_loop)
325
+ metrics = future.result(timeout=5)
326
+ self._do_emit_metrics(ctx, metrics)
327
+ except concurrent.futures.TimeoutError:
328
+ logger.warning(f"Rate limit metrics collection timed out for {exchange_name}")
333
329
  except Exception as e:
334
330
  logger.error(f"Failed to collect rate limit metrics for {exchange_name}: {e}")
335
331
 
@@ -33,11 +33,16 @@ class IRateLimitBackend(ABC):
33
33
  """
34
34
 
35
35
  @abstractmethod
36
- async def get_remaining(self, key: str) -> float | None:
36
+ async def get_remaining(self, key: str, capacity: float = 0, refill_rate: float = 0) -> float | None:
37
37
  """Get remaining tokens for a key (non-blocking).
38
38
 
39
+ Args:
40
+ key: Bucket identifier
41
+ capacity: Pool capacity (for computing refill on read)
42
+ refill_rate: Tokens per second (for computing refill on read)
43
+
39
44
  Returns:
40
- Token count, or None if key doesn't exist
45
+ Token count (with refill applied), or None if key doesn't exist
41
46
  """
42
47
 
43
48
  @abstractmethod
@@ -70,7 +75,7 @@ class InMemoryBackend(IRateLimitBackend):
70
75
  await limiter.acquire(weight)
71
76
  return time.monotonic() - start
72
77
 
73
- async def get_remaining(self, key: str) -> float | None:
78
+ async def get_remaining(self, key: str, capacity: float = 0, refill_rate: float = 0) -> float | None:
74
79
  limiter = self._limiters.get(key)
75
80
  if limiter is None:
76
81
  return None
@@ -333,7 +333,7 @@ class ExchangeRateLimiter:
333
333
  remaining = self._quota_remaining.get(pool_name, 0)
334
334
  else:
335
335
  key = self._key_for(pool)
336
- remaining = await self._backend.get_remaining(key)
336
+ remaining = await self._backend.get_remaining(key, pool.capacity, pool.refill_rate)
337
337
  if remaining is None:
338
338
  remaining = pool.capacity
339
339
 
@@ -35,7 +35,7 @@ tokens = math.min(capacity, tokens + tokens_to_add)
35
35
  if tokens >= weight then
36
36
  tokens = tokens - weight
37
37
  redis.call('HSET', key, 'tokens', tokens, 'last_refill', now)
38
- redis.call('EXPIRE', key, 300) -- 5 min TTL to auto-cleanup stale keys
38
+ redis.call('EXPIRE', key, 600) -- 10 min TTL to auto-cleanup stale keys
39
39
  return 0 -- no wait needed
40
40
  else
41
41
  -- Calculate wait time
@@ -56,12 +56,18 @@ local refill_rate = tonumber(ARGV[2])
56
56
  local now = tonumber(ARGV[3])
57
57
 
58
58
  local tokens = tonumber(redis.call('HGET', key, 'tokens'))
59
- if tokens == nil then return capacity * 1000 end
59
+ if tokens == nil then return -1 end
60
+
61
+ -- Compute refilled value (same logic as acquire)
62
+ if refill_rate > 0 then
63
+ local last_refill = tonumber(redis.call('HGET', key, 'last_refill') or now)
64
+ local elapsed = now - last_refill
65
+ local tokens_to_add = elapsed * refill_rate
66
+ tokens = math.min(capacity, tokens + tokens_to_add)
67
+ end
60
68
 
61
- local last_refill = tonumber(redis.call('HGET', key, 'last_refill') or now)
62
- local elapsed = now - last_refill
63
- local tokens_to_add = elapsed * refill_rate
64
- tokens = math.min(capacity, tokens + tokens_to_add)
69
+ -- Refresh TTL on read (keeps keys alive while bot is running)
70
+ redis.call('EXPIRE', key, 600)
65
71
 
66
72
  return math.floor(tokens * 1000) -- return as millitokens for precision
67
73
  """
@@ -72,7 +78,7 @@ local remaining = tonumber(ARGV[1])
72
78
  local now = tonumber(ARGV[2])
73
79
 
74
80
  redis.call('HSET', key, 'tokens', remaining, 'last_refill', now)
75
- redis.call('EXPIRE', key, 300)
81
+ redis.call('EXPIRE', key, 600)
76
82
  return 1
77
83
  """
78
84
 
@@ -111,13 +117,16 @@ class RedisBackend(IRateLimitBackend):
111
117
  await __import__("asyncio").sleep(wait_s)
112
118
  now = time.time()
113
119
 
114
- async def get_remaining(self, key: str) -> float | None:
115
- # We need capacity and refill_rate to compute remaining after refill,
116
- # but we don't have them here. Return raw stored tokens.
117
- raw = await self._redis.hget(key, "tokens")
118
- if raw is None:
120
+ async def get_remaining(self, key: str, capacity: float = 0, refill_rate: float = 0) -> float | None:
121
+ now = time.time()
122
+ result = await self._get_remaining_script(
123
+ keys=[key],
124
+ args=[capacity, refill_rate, now],
125
+ )
126
+ result = float(result)
127
+ if result < 0:
119
128
  return None
120
- return float(raw)
129
+ return result / 1000.0 # convert millitokens back
121
130
 
122
131
  async def set_remaining(self, key: str, remaining: float) -> None:
123
132
  now = time.time()
@@ -657,12 +657,9 @@ def create_strategy_context(
657
657
  state_snapshot_interval=_state_snapshot_interval,
658
658
  rate_limit_backend=_rate_limit_backend,
659
659
  rate_limiting_config=_rate_limiting_config,
660
+ event_loop=loop,
660
661
  )
661
662
 
662
- # Store the shared event loop reference for cleanup
663
- if loop is not None:
664
- ctx._shared_event_loop = loop # type: ignore
665
-
666
663
  # Set context for metric emitters to enable is_live tag and time access
667
664
  if _metric_emitter is not None:
668
665
  _metric_emitter.set_context(ctx)
File without changes
File without changes
File without changes
File without changes
File without changes