Qubx 1.0.4.dev1__tar.gz → 1.0.4.dev2__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 (268) hide show
  1. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/PKG-INFO +15 -16
  2. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/pyproject.toml +18 -22
  3. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/_version.py +2 -2
  4. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/cli/release.py +10 -5
  5. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/.gitignore +0 -0
  6. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/LICENSE +0 -0
  7. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/README.md +0 -0
  8. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/scripts/build.py +0 -0
  9. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/__init__.py +0 -0
  10. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/_nb_magic.py +0 -0
  11. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/__init__.py +0 -0
  12. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/account.py +0 -0
  13. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/broker.py +0 -0
  14. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/data.py +0 -0
  15. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/iteratedstream.py +0 -0
  16. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/management.py +0 -0
  17. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/ome.py +0 -0
  18. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/optimization.py +0 -0
  19. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/runner.py +0 -0
  20. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/sentinels.py +0 -0
  21. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/simulated_data.py +0 -0
  22. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/simulated_exchange.py +0 -0
  23. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/simulator.py +0 -0
  24. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/transfers.py +0 -0
  25. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/backtester/utils.py +0 -0
  26. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/cli/__init__.py +0 -0
  27. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/cli/commands.py +0 -0
  28. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/cli/deploy.py +0 -0
  29. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/cli/misc.py +0 -0
  30. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/cli/theme.py +0 -0
  31. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/cli/tui.py +0 -0
  32. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/config.py +0 -0
  33. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/__init__.py +0 -0
  34. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/__init__.py +0 -0
  35. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/account.py +0 -0
  36. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/adapters/__init__.py +0 -0
  37. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/adapters/polling_adapter.py +0 -0
  38. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/broker.py +0 -0
  39. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/connection_manager.py +0 -0
  40. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/data.py +0 -0
  41. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exceptions.py +0 -0
  42. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchange_manager.py +0 -0
  43. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/__init__.py +0 -0
  44. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/base.py +0 -0
  45. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/binance/broker.py +0 -0
  46. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/binance/exchange.py +0 -0
  47. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex.py +0 -0
  48. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex_account.py +0 -0
  49. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/gateio/__init__.py +0 -0
  50. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/gateio/gateio.py +0 -0
  51. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/hyperliquid/__init__.py +0 -0
  52. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/hyperliquid/account.py +0 -0
  53. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/hyperliquid/broker.py +0 -0
  54. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/hyperliquid/hyperliquid.py +0 -0
  55. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/kraken/kraken.py +0 -0
  56. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/okx/__init__.py +0 -0
  57. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/okx/account.py +0 -0
  58. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/okx/broker.py +0 -0
  59. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/exchanges/okx/okx.py +0 -0
  60. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/factory.py +0 -0
  61. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/handlers/__init__.py +0 -0
  62. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/handlers/base.py +0 -0
  63. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/handlers/factory.py +0 -0
  64. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/handlers/funding_rate.py +0 -0
  65. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/handlers/liquidation.py +0 -0
  66. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/handlers/ohlc.py +0 -0
  67. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/handlers/open_interest.py +0 -0
  68. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/handlers/orderbook.py +0 -0
  69. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/handlers/quote.py +0 -0
  70. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/handlers/trade.py +0 -0
  71. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/subscription_config.py +0 -0
  72. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/subscription_manager.py +0 -0
  73. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/subscription_orchestrator.py +0 -0
  74. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/utils.py +0 -0
  75. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/ccxt/warmup_service.py +0 -0
  76. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/registry.py +0 -0
  77. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/tardis/data.py +0 -0
  78. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/connectors/tardis/utils.py +0 -0
  79. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/__init__.py +0 -0
  80. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/account.py +0 -0
  81. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/basics.py +0 -0
  82. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/context.py +0 -0
  83. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/detectors/__init__.py +0 -0
  84. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/detectors/delisting.py +0 -0
  85. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/detectors/stale.py +0 -0
  86. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/errors.py +0 -0
  87. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/exceptions.py +0 -0
  88. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/helpers.py +0 -0
  89. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/initializer.py +0 -0
  90. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/interfaces.py +0 -0
  91. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/loggers.py +0 -0
  92. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/lookups.py +0 -0
  93. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/metrics.py +0 -0
  94. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/mixins/__init__.py +0 -0
  95. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/mixins/market.py +0 -0
  96. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/mixins/processing.py +0 -0
  97. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/mixins/subscription.py +0 -0
  98. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/mixins/trading.py +0 -0
  99. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/mixins/universe.py +0 -0
  100. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/mixins/utils.py +0 -0
  101. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/series.pxd +0 -0
  102. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/series.pyi +0 -0
  103. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/series.pyx +0 -0
  104. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/utils.pyi +0 -0
  105. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/core/utils.pyx +0 -0
  106. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/__init__.py +0 -0
  107. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/cache.py +0 -0
  108. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/containers.py +0 -0
  109. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/guards.py +0 -0
  110. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/registry.py +0 -0
  111. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/storage.py +0 -0
  112. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/storages/ccxt.py +0 -0
  113. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/storages/csv.py +0 -0
  114. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/storages/handy.py +0 -0
  115. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/storages/multi.py +0 -0
  116. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/storages/questdb.py +0 -0
  117. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/storages/stub.py +0 -0
  118. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/storages/utils.py +0 -0
  119. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/data/transformers.py +0 -0
  120. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/emitters/__init__.py +0 -0
  121. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/emitters/base.py +0 -0
  122. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/emitters/composite.py +0 -0
  123. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/emitters/csv.py +0 -0
  124. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/emitters/indicator.py +0 -0
  125. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/emitters/inmemory.py +0 -0
  126. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/emitters/prometheus.py +0 -0
  127. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/emitters/questdb.py +0 -0
  128. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/exporters/__init__.py +0 -0
  129. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/exporters/composite.py +0 -0
  130. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/exporters/formatters/__init__.py +0 -0
  131. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/exporters/formatters/base.py +0 -0
  132. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/exporters/formatters/incremental.py +0 -0
  133. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/exporters/formatters/slack.py +0 -0
  134. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/exporters/formatters/target_position.py +0 -0
  135. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/exporters/redis_streams.py +0 -0
  136. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/exporters/slack.py +0 -0
  137. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/gathering/simplest.py +0 -0
  138. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/health/__init__.py +0 -0
  139. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/health/base.py +0 -0
  140. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/health/dummy.py +0 -0
  141. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/health/server.py +0 -0
  142. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/loggers/__init__.py +0 -0
  143. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/loggers/csv.py +0 -0
  144. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/loggers/factory.py +0 -0
  145. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/loggers/inmemory.py +0 -0
  146. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/loggers/mongo.py +0 -0
  147. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/notifications/__init__.py +0 -0
  148. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/notifications/composite.py +0 -0
  149. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/notifications/slack.py +0 -0
  150. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/notifications/throttler.py +0 -0
  151. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/pandaz/__init__.py +0 -0
  152. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/pandaz/stats.py +0 -0
  153. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/pandaz/ta.py +0 -0
  154. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/pandaz/utils.py +0 -0
  155. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/plugins/__init__.py +0 -0
  156. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/plugins/loader.py +0 -0
  157. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/resources/_build.py +0 -0
  158. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/resources/crypto-fees.ini +0 -0
  159. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/resources/instruments/hyperliquid-spot.json +0 -0
  160. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/resources/instruments/hyperliquid.f-perpetual.json +0 -0
  161. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/resources/instruments/symbols-binance-spot.json +0 -0
  162. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/resources/instruments/symbols-binance.cm-future.json +0 -0
  163. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/resources/instruments/symbols-binance.cm-perpetual.json +0 -0
  164. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/resources/instruments/symbols-binance.um-future.json +0 -0
  165. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/resources/instruments/symbols-binance.um-perpetual.json +0 -0
  166. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/resources/instruments/symbols-bitfinex.f-perpetual.json +0 -0
  167. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/resources/instruments/symbols-kraken-spot.json +0 -0
  168. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/resources/instruments/symbols-kraken.f-future.json +0 -0
  169. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/resources/instruments/symbols-kraken.f-perpetual.json +0 -0
  170. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/restarts/__init__.py +0 -0
  171. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/restarts/state_resolvers.py +0 -0
  172. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/restarts/time_finders.py +0 -0
  173. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/restorers/__init__.py +0 -0
  174. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/restorers/balance.py +0 -0
  175. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/restorers/factory.py +0 -0
  176. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/restorers/interfaces.py +0 -0
  177. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/restorers/position.py +0 -0
  178. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/restorers/signal.py +0 -0
  179. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/restorers/state.py +0 -0
  180. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/restorers/utils.py +0 -0
  181. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/state/__init__.py +0 -0
  182. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/state/dummy.py +0 -0
  183. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/state/redis.py +0 -0
  184. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/ta/__init__.py +0 -0
  185. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/ta/indicators.pxd +0 -0
  186. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/ta/indicators.pyi +0 -0
  187. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/ta/indicators.pyx +0 -0
  188. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/__init__.py +0 -0
  189. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/base.py +0 -0
  190. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/project/accounts.toml.j2 +0 -0
  191. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/project/config.yml.j2 +0 -0
  192. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/project/jlive.sh.j2 +0 -0
  193. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/project/jpaper.sh.j2 +0 -0
  194. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/project/pyproject.toml.j2 +0 -0
  195. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/project/src/{{ strategy_name }}/__init__.py.j2 +0 -0
  196. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/project/src/{{ strategy_name }}/strategy.py.j2 +0 -0
  197. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/project/template.yml +0 -0
  198. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/simple/__init__.py.j2 +0 -0
  199. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/simple/accounts.toml.j2 +0 -0
  200. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/simple/config.yml.j2 +0 -0
  201. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/simple/jlive.sh.j2 +0 -0
  202. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/simple/jpaper.sh.j2 +0 -0
  203. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/simple/strategy.py.j2 +0 -0
  204. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/templates/simple/template.yml +0 -0
  205. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/trackers/__init__.py +0 -0
  206. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/trackers/advanced.py +0 -0
  207. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/trackers/composite.py +0 -0
  208. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/trackers/rebalancers.py +0 -0
  209. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/trackers/riskctrl.py +0 -0
  210. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/trackers/sizers.py +0 -0
  211. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/__init__.py +0 -0
  212. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/_pyxreloader.py +0 -0
  213. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/charting/lookinglass.py +0 -0
  214. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/charting/mpl_helpers.py +0 -0
  215. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/charting/orderbook.py +0 -0
  216. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/collections.py +0 -0
  217. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/hft/__init__.py +0 -0
  218. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/hft/numba_utils.py +0 -0
  219. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/hft/orderbook.pyi +0 -0
  220. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/hft/orderbook.pyx +0 -0
  221. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/marketdata/binance.py +0 -0
  222. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/marketdata/ccxt.py +0 -0
  223. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/marketdata/dukas.py +0 -0
  224. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/misc.py +0 -0
  225. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/nonce.py +0 -0
  226. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/ntp.py +0 -0
  227. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/numbers_utils.py +0 -0
  228. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/orderbook.py +0 -0
  229. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/plotting/__init__.py +0 -0
  230. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/plotting/dashboard.py +0 -0
  231. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/plotting/data.py +0 -0
  232. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/plotting/interfaces.py +0 -0
  233. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/plotting/renderers/__init__.py +0 -0
  234. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/plotting/renderers/plotly.py +0 -0
  235. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/questdb.py +0 -0
  236. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/rate_limiter.py +0 -0
  237. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/results.py +0 -0
  238. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/ringbuffer.pxd +0 -0
  239. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/ringbuffer.pyi +0 -0
  240. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/ringbuffer.pyx +0 -0
  241. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/__init__.py +0 -0
  242. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/_jupyter_runner.pyt +0 -0
  243. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/accounts.py +0 -0
  244. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/configs.py +0 -0
  245. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/factory.py +0 -0
  246. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/kernel_service.py +0 -0
  247. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/runner.py +0 -0
  248. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/textual/__init__.py +0 -0
  249. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/textual/app.py +0 -0
  250. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/textual/handlers.py +0 -0
  251. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/textual/init_code.py +0 -0
  252. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/textual/kernel.py +0 -0
  253. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/textual/styles.tcss +0 -0
  254. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/textual/widgets/__init__.py +0 -0
  255. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/textual/widgets/command_input.py +0 -0
  256. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/textual/widgets/debug_log.py +0 -0
  257. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/textual/widgets/orders_table.py +0 -0
  258. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/textual/widgets/positions_table.py +0 -0
  259. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/textual/widgets/quotes_table.py +0 -0
  260. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/runner/textual/widgets/repl_output.py +0 -0
  261. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/slack.py +0 -0
  262. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/throttler.py +0 -0
  263. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/time.py +0 -0
  264. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/src/qubx/utils/websocket_manager.py +0 -0
  265. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/tests/strategies/macd_crossover/src/macd_crossover/indicators/macd.py +0 -0
  266. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/tests/strategies/macd_crossover/src/macd_crossover/models/macd_crossover.py +0 -0
  267. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/tests/strategies/macd_crossover/src/macd_crossover/models/utils.py +0 -0
  268. {qubx-1.0.4.dev1 → qubx-1.0.4.dev2}/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.0.4.dev1
3
+ Version: 1.0.4.dev2
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
@@ -9,12 +9,16 @@ Author-email: Dmitry Marienko <dmitry.marienko@xlydian.com>, Yuriy Arabskyy <yur
9
9
  License-File: LICENSE
10
10
  Requires-Python: <4.0,>=3.12
11
11
  Requires-Dist: aiohttp<3.11,>=3.10.11
12
+ Requires-Dist: boto3<2,>=1.34.0
12
13
  Requires-Dist: click<9,>=8.1.7
13
14
  Requires-Dist: croniter<3,>=2.0.5
15
+ Requires-Dist: duckdb>=1.0.0
14
16
  Requires-Dist: gitpython<4,>=3.1.44
15
17
  Requires-Dist: importlib-metadata
18
+ Requires-Dist: ipykernel<7,>=6.29.0
16
19
  Requires-Dist: jinja2<4,>=3.1.0
17
20
  Requires-Dist: joblib<2,>=1.3.0
21
+ Requires-Dist: jupyter-client<9,>=8.0.0
18
22
  Requires-Dist: loguru<1,>=0.7.2
19
23
  Requires-Dist: msgspec<1,>=0.18.6
20
24
  Requires-Dist: ntplib<1,>=0.4.0
@@ -22,17 +26,27 @@ Requires-Dist: numba<1,>=0.59.1
22
26
  Requires-Dist: numpy>=1.26.3
23
27
  Requires-Dist: orjson<4,>=3.10.15
24
28
  Requires-Dist: pandas<3,>=2.2.2
29
+ Requires-Dist: prometheus-client<1,>=0.21.1
30
+ Requires-Dist: psycopg-binary<4,>=3.1.19
31
+ Requires-Dist: psycopg-pool<4,>=3.2.2
32
+ Requires-Dist: psycopg<4,>=3.1.18
25
33
  Requires-Dist: pyarrow>=15.0.0
26
34
  Requires-Dist: pydantic-settings<3,>=2.4.0
27
35
  Requires-Dist: pydantic<3,>=2.9.2
36
+ Requires-Dist: pymongo<5,>=4.6.1
28
37
  Requires-Dist: python-dotenv<2,>=1.0.0
29
38
  Requires-Dist: pyyaml<7,>=6.0.2
39
+ Requires-Dist: questdb<3,>=2.0.3
40
+ Requires-Dist: redis<6,>=5.2.1
30
41
  Requires-Dist: rich<14,>=13.9.4
31
42
  Requires-Dist: scipy<2,>=1.12.0
32
43
  Requires-Dist: sortedcontainers<3,>=2.4.0
33
44
  Requires-Dist: stackprinter<1,>=0.2.10
34
45
  Requires-Dist: statsmodels<1,>=0.14.6
35
46
  Requires-Dist: tabulate<1,>=0.9.0
47
+ Requires-Dist: textual-autocomplete<5,>=4.0.0
48
+ Requires-Dist: textual-serve<2,>=1.0.0
49
+ Requires-Dist: textual[syntax]<7,>=6.0.0
36
50
  Requires-Dist: toml<1,>=0.10.2
37
51
  Requires-Dist: tqdm<5,>=4.66.0
38
52
  Requires-Dist: uvloop<1,>=0.22.1; sys_platform != 'win32'
@@ -43,25 +57,10 @@ Provides-Extra: bitfinex
43
57
  Requires-Dist: qubx-bitfinex-api<4,>=3.0.7; extra == 'bitfinex'
44
58
  Provides-Extra: connectors
45
59
  Requires-Dist: ccxt<5,>=4.2.68; extra == 'connectors'
46
- Provides-Extra: db
47
- Requires-Dist: duckdb>=1.0.0; extra == 'db'
48
- Requires-Dist: psycopg-binary<4,>=3.1.19; extra == 'db'
49
- Requires-Dist: psycopg-pool<4,>=3.2.2; extra == 'db'
50
- Requires-Dist: psycopg<4,>=3.1.18; extra == 'db'
51
- Requires-Dist: pymongo<5,>=4.6.1; extra == 'db'
52
- Requires-Dist: questdb<3,>=2.0.3; extra == 'db'
53
- Requires-Dist: redis<6,>=5.2.1; extra == 'db'
54
60
  Provides-Extra: jupyter
55
61
  Requires-Dist: ipywidgets<9,>=8.1.5; extra == 'jupyter'
56
62
  Requires-Dist: jupyter-console<7,>=6.6.3; extra == 'jupyter'
57
63
  Requires-Dist: jupyter<2,>=1.1.1; extra == 'jupyter'
58
- Provides-Extra: k8
59
- Requires-Dist: boto3<2,>=1.34.0; extra == 'k8'
60
- Requires-Dist: prometheus-client<1,>=0.21.1; extra == 'k8'
61
- Provides-Extra: tui
62
- Requires-Dist: textual-autocomplete<5,>=4.0.0; extra == 'tui'
63
- Requires-Dist: textual-serve<2,>=1.0.0; extra == 'tui'
64
- Requires-Dist: textual[syntax]<7,>=6.0.0; extra == 'tui'
65
64
  Provides-Extra: viz
66
65
  Requires-Dist: dash-bootstrap-components<2,>=1.6.0; extra == 'viz'
67
66
  Requires-Dist: dash<3,>=2.18.2; extra == 'viz'
@@ -46,6 +46,23 @@ dependencies = [
46
46
  "rich>=13.9.4,<14",
47
47
  "click>=8.1.7,<9",
48
48
  "statsmodels>=0.14.6,<1",
49
+ # Database backends
50
+ "pymongo>=4.6.1,<5",
51
+ "redis>=5.2.1,<6",
52
+ "psycopg>=3.1.18,<4",
53
+ "psycopg-binary>=3.1.19,<4",
54
+ "psycopg-pool>=3.2.2,<4",
55
+ "questdb>=2.0.3,<3",
56
+ "duckdb>=1.0.0",
57
+ # Terminal UI
58
+ "textual[syntax]>=6.0.0,<7",
59
+ "textual-autocomplete>=4.0.0,<5",
60
+ "textual-serve>=1.0.0,<2",
61
+ "jupyter-client>=8.0.0,<9",
62
+ "ipykernel>=6.29.0,<7",
63
+ # Production monitoring & cloud
64
+ "prometheus-client>=0.21.1,<1",
65
+ "boto3>=1.34.0,<2",
49
66
  ]
50
67
 
51
68
  [project.urls]
@@ -57,7 +74,7 @@ docs = "https://xlydiansoftware.github.io/Qubx"
57
74
  qubx = "qubx.cli.commands:main"
58
75
 
59
76
  # ============================================================
60
- # OPTIONAL DEPENDENCIES (`pip install qubx[connectors,db,...]`)
77
+ # OPTIONAL DEPENDENCIES (`pip install qubx[connectors,...]`)
61
78
  # ============================================================
62
79
  [project.optional-dependencies]
63
80
  # Exchange connectors (ccxt-based)
@@ -66,16 +83,6 @@ connectors = ["ccxt>=4.2.68,<5"]
66
83
  binance = ["python-binance>=1.0.19,<2"]
67
84
  # Bitfinex-specific (custom API client)
68
85
  bitfinex = ["qubx-bitfinex-api>=3.0.7,<4"]
69
- # Database backends (MongoDB, Redis, PostgreSQL/QuestDB, DuckDB)
70
- db = [
71
- "pymongo>=4.6.1,<5",
72
- "redis>=5.2.1,<6",
73
- "psycopg>=3.1.18,<4",
74
- "psycopg-binary>=3.1.19,<4",
75
- "psycopg-pool>=3.2.2,<4",
76
- "questdb>=2.0.3,<3",
77
- "duckdb>=1.0.0",
78
- ]
79
86
  # Visualization & charting
80
87
  viz = [
81
88
  "matplotlib>=3.8.4,<4",
@@ -83,23 +90,12 @@ viz = [
83
90
  "dash>=2.18.2,<3",
84
91
  "dash-bootstrap-components>=1.6.0,<2",
85
92
  ]
86
- # Terminal UI (textual TUI, browse command)
87
- tui = [
88
- "textual[syntax]>=6.0.0,<7",
89
- "textual-autocomplete>=4.0.0,<5",
90
- "textual-serve>=1.0.0,<2",
91
- ]
92
93
  # Jupyter integration
93
94
  jupyter = [
94
95
  "jupyter>=1.1.1,<2",
95
96
  "jupyter-console>=6.6.3,<7",
96
97
  "ipywidgets>=8.1.5,<9",
97
98
  ]
98
- # Kubernetes / production monitoring
99
- k8 = [
100
- "prometheus-client>=0.21.1,<1",
101
- "boto3>=1.34.0,<2",
102
- ]
103
99
 
104
100
  # ============================================================
105
101
  # BUILD SYSTEM
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '1.0.4.dev1'
32
- __version_tuple__ = version_tuple = (1, 0, 4, 'dev1')
31
+ __version__ = version = '1.0.4.dev2'
32
+ __version_tuple__ = version_tuple = (1, 0, 4, 'dev2')
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -633,10 +633,15 @@ def _scan_strategy_deps(
633
633
  all_deps.extend(group_deps)
634
634
 
635
635
  # Step 4: for each declared dep, check if the strategy uses it
636
+ import re
637
+
636
638
  scanned_deps: list[str] = []
637
639
  for dep_spec in all_deps:
638
- # Extract package name from spec like "cachetools>=6.2.1,<7"
639
- pkg_name = dep_spec.split(">=")[0].split("==")[0].split("<")[0].split("[")[0].strip()
640
+ # Parse dep spec like "qubx[connectors,db,k8,tui]==1.0.3" or "cachetools>=6.2.1,<7"
641
+ # Extract: package name, extras (if any), version specifiers
642
+ match = re.match(r'^([A-Za-z0-9_.-]+)(\[[^\]]*\])?', dep_spec)
643
+ pkg_name = match.group(1).strip() if match else dep_spec.split("[")[0].split(">")[0].split("=")[0].split("<")[0].strip()
644
+ extras = match.group(2) or "" if match else ""
640
645
  pkg_name_normalized = pkg_name.lower().replace("-", "_")
641
646
 
642
647
  # Determine import names for this package
@@ -652,7 +657,7 @@ def _scan_strategy_deps(
652
657
  if dist.files:
653
658
  for f in dist.files:
654
659
  parts = str(f).split("/")
655
- if len(parts) > 1 and not parts[0].endswith(".dist-info"):
660
+ if len(parts) > 1 and parts[0] and not parts[0].endswith(".dist-info"):
656
661
  import_names.add(parts[0].replace("-", "_"))
657
662
  if not import_names:
658
663
  import_names.add(pkg_name_normalized)
@@ -662,10 +667,10 @@ def _scan_strategy_deps(
662
667
 
663
668
  # Check if any import name is used by strategy
664
669
  if import_names & strategy_imports:
665
- # Pin version from lock file
670
+ # Pin version from lock file, preserving extras
666
671
  version = lock_versions.get(pkg_name_normalized)
667
672
  if version:
668
- pinned = f"{pkg_name}=={version}"
673
+ pinned = f"{pkg_name}{extras}=={version}"
669
674
  else:
670
675
  # Fallback to declared spec
671
676
  pinned = dep_spec
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes