Qubx 1.0.0.dev3__tar.gz → 1.0.0.dev4__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 (263) hide show
  1. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/PKG-INFO +2 -1
  2. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/pyproject.toml +1 -0
  3. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/__init__.py +7 -1
  4. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/_version.py +2 -2
  5. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/management.py +5 -30
  6. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/runner.py +0 -1
  7. qubx-1.0.0.dev4/src/qubx/config.py +139 -0
  8. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/lookups.py +16 -14
  9. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/metrics.py +6 -2
  10. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/storages/ccxt.py +130 -111
  11. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/storages/questdb.py +36 -0
  12. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/misc.py +1 -1
  13. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/results.py +67 -35
  14. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/runner.py +2 -6
  15. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/.gitignore +0 -0
  16. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/LICENSE +0 -0
  17. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/README.md +0 -0
  18. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/hatch_build.py +0 -0
  19. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/_nb_magic.py +0 -0
  20. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/__init__.py +0 -0
  21. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/account.py +0 -0
  22. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/broker.py +0 -0
  23. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/data.py +0 -0
  24. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/iteratedstream.py +0 -0
  25. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/ome.py +0 -0
  26. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/optimization.py +0 -0
  27. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/sentinels.py +0 -0
  28. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/simulated_data.py +0 -0
  29. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/simulated_exchange.py +0 -0
  30. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/simulator.py +0 -0
  31. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/transfers.py +0 -0
  32. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/backtester/utils.py +0 -0
  33. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/cli/__init__.py +0 -0
  34. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/cli/commands.py +0 -0
  35. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/cli/deploy.py +0 -0
  36. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/cli/misc.py +0 -0
  37. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/cli/release.py +0 -0
  38. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/cli/theme.py +0 -0
  39. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/cli/tui.py +0 -0
  40. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/__init__.py +0 -0
  41. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/__init__.py +0 -0
  42. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/account.py +0 -0
  43. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/adapters/__init__.py +0 -0
  44. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/adapters/polling_adapter.py +0 -0
  45. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/broker.py +0 -0
  46. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/connection_manager.py +0 -0
  47. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/data.py +0 -0
  48. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exceptions.py +0 -0
  49. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchange_manager.py +0 -0
  50. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchanges/__init__.py +0 -0
  51. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchanges/base.py +0 -0
  52. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchanges/binance/broker.py +0 -0
  53. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchanges/binance/exchange.py +0 -0
  54. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex.py +0 -0
  55. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchanges/bitfinex/bitfinex_account.py +0 -0
  56. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchanges/gateio/__init__.py +0 -0
  57. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchanges/gateio/gateio.py +0 -0
  58. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchanges/hyperliquid/__init__.py +0 -0
  59. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchanges/hyperliquid/account.py +0 -0
  60. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchanges/hyperliquid/broker.py +0 -0
  61. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchanges/hyperliquid/hyperliquid.py +0 -0
  62. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/exchanges/kraken/kraken.py +0 -0
  63. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/factory.py +0 -0
  64. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/handlers/__init__.py +0 -0
  65. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/handlers/base.py +0 -0
  66. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/handlers/factory.py +0 -0
  67. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/handlers/funding_rate.py +0 -0
  68. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/handlers/liquidation.py +0 -0
  69. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/handlers/ohlc.py +0 -0
  70. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/handlers/open_interest.py +0 -0
  71. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/handlers/orderbook.py +0 -0
  72. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/handlers/quote.py +0 -0
  73. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/handlers/trade.py +0 -0
  74. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/subscription_config.py +0 -0
  75. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/subscription_manager.py +0 -0
  76. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/subscription_orchestrator.py +0 -0
  77. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/utils.py +0 -0
  78. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/ccxt/warmup_service.py +0 -0
  79. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/registry.py +0 -0
  80. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/tardis/data.py +0 -0
  81. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/connectors/tardis/utils.py +0 -0
  82. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/__init__.py +0 -0
  83. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/account.py +0 -0
  84. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/basics.py +0 -0
  85. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/context.py +0 -0
  86. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/detectors/__init__.py +0 -0
  87. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/detectors/delisting.py +0 -0
  88. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/detectors/stale.py +0 -0
  89. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/errors.py +0 -0
  90. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/exceptions.py +0 -0
  91. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/helpers.py +0 -0
  92. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/initializer.py +0 -0
  93. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/interfaces.py +0 -0
  94. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/loggers.py +0 -0
  95. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/mixins/__init__.py +0 -0
  96. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/mixins/market.py +0 -0
  97. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/mixins/processing.py +0 -0
  98. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/mixins/subscription.py +0 -0
  99. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/mixins/trading.py +0 -0
  100. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/mixins/universe.py +0 -0
  101. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/mixins/utils.py +0 -0
  102. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/series.pxd +0 -0
  103. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/series.pyi +0 -0
  104. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/series.pyx +0 -0
  105. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/utils.pyi +0 -0
  106. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/core/utils.pyx +0 -0
  107. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/__init__.py +0 -0
  108. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/cache.py +0 -0
  109. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/containers.py +0 -0
  110. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/guards.py +0 -0
  111. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/registry.py +0 -0
  112. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/storage.py +0 -0
  113. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/storages/csv.py +0 -0
  114. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/storages/handy.py +0 -0
  115. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/storages/multi.py +0 -0
  116. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/storages/stub.py +0 -0
  117. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/storages/utils.py +0 -0
  118. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/data/transformers.py +0 -0
  119. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/emitters/__init__.py +0 -0
  120. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/emitters/base.py +0 -0
  121. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/emitters/composite.py +0 -0
  122. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/emitters/csv.py +0 -0
  123. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/emitters/indicator.py +0 -0
  124. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/emitters/inmemory.py +0 -0
  125. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/emitters/prometheus.py +0 -0
  126. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/emitters/questdb.py +0 -0
  127. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/exporters/__init__.py +0 -0
  128. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/exporters/composite.py +0 -0
  129. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/exporters/formatters/__init__.py +0 -0
  130. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/exporters/formatters/base.py +0 -0
  131. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/exporters/formatters/incremental.py +0 -0
  132. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/exporters/formatters/slack.py +0 -0
  133. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/exporters/formatters/target_position.py +0 -0
  134. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/exporters/redis_streams.py +0 -0
  135. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/exporters/slack.py +0 -0
  136. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/gathering/simplest.py +0 -0
  137. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/health/__init__.py +0 -0
  138. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/health/base.py +0 -0
  139. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/health/dummy.py +0 -0
  140. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/loggers/__init__.py +0 -0
  141. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/loggers/csv.py +0 -0
  142. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/loggers/factory.py +0 -0
  143. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/loggers/inmemory.py +0 -0
  144. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/loggers/mongo.py +0 -0
  145. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/notifications/__init__.py +0 -0
  146. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/notifications/composite.py +0 -0
  147. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/notifications/slack.py +0 -0
  148. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/notifications/throttler.py +0 -0
  149. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/pandaz/__init__.py +0 -0
  150. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/pandaz/stats.py +0 -0
  151. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/pandaz/ta.py +0 -0
  152. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/pandaz/utils.py +0 -0
  153. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/plugins/__init__.py +0 -0
  154. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/plugins/loader.py +0 -0
  155. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/resources/_build.py +0 -0
  156. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/resources/crypto-fees.ini +0 -0
  157. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/resources/instruments/hyperliquid-spot.json +0 -0
  158. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/resources/instruments/hyperliquid.f-perpetual.json +0 -0
  159. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/resources/instruments/symbols-binance-spot.json +0 -0
  160. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/resources/instruments/symbols-binance.cm-future.json +0 -0
  161. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/resources/instruments/symbols-binance.cm-perpetual.json +0 -0
  162. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/resources/instruments/symbols-binance.um-future.json +0 -0
  163. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/resources/instruments/symbols-binance.um-perpetual.json +0 -0
  164. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/resources/instruments/symbols-bitfinex.f-perpetual.json +0 -0
  165. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/resources/instruments/symbols-kraken-spot.json +0 -0
  166. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/resources/instruments/symbols-kraken.f-future.json +0 -0
  167. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/resources/instruments/symbols-kraken.f-perpetual.json +0 -0
  168. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/restarts/__init__.py +0 -0
  169. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/restarts/state_resolvers.py +0 -0
  170. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/restarts/time_finders.py +0 -0
  171. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/restorers/__init__.py +0 -0
  172. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/restorers/balance.py +0 -0
  173. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/restorers/factory.py +0 -0
  174. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/restorers/interfaces.py +0 -0
  175. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/restorers/position.py +0 -0
  176. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/restorers/signal.py +0 -0
  177. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/restorers/state.py +0 -0
  178. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/restorers/utils.py +0 -0
  179. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/state/__init__.py +0 -0
  180. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/state/dummy.py +0 -0
  181. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/state/redis.py +0 -0
  182. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/ta/__init__.py +0 -0
  183. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/ta/indicators.pxd +0 -0
  184. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/ta/indicators.pyi +0 -0
  185. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/ta/indicators.pyx +0 -0
  186. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/__init__.py +0 -0
  187. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/base.py +0 -0
  188. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/project/accounts.toml.j2 +0 -0
  189. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/project/config.yml.j2 +0 -0
  190. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/project/jlive.sh.j2 +0 -0
  191. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/project/jpaper.sh.j2 +0 -0
  192. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/project/pyproject.toml.j2 +0 -0
  193. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/project/src/{{ strategy_name }}/__init__.py.j2 +0 -0
  194. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/project/src/{{ strategy_name }}/strategy.py.j2 +0 -0
  195. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/project/template.yml +0 -0
  196. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/simple/__init__.py.j2 +0 -0
  197. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/simple/accounts.toml.j2 +0 -0
  198. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/simple/config.yml.j2 +0 -0
  199. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/simple/jlive.sh.j2 +0 -0
  200. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/simple/jpaper.sh.j2 +0 -0
  201. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/simple/strategy.py.j2 +0 -0
  202. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/templates/simple/template.yml +0 -0
  203. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/trackers/__init__.py +0 -0
  204. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/trackers/advanced.py +0 -0
  205. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/trackers/composite.py +0 -0
  206. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/trackers/rebalancers.py +0 -0
  207. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/trackers/riskctrl.py +0 -0
  208. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/trackers/sizers.py +0 -0
  209. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/__init__.py +0 -0
  210. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/_pyxreloader.py +0 -0
  211. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/charting/lookinglass.py +0 -0
  212. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/charting/mpl_helpers.py +0 -0
  213. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/charting/orderbook.py +0 -0
  214. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/collections.py +0 -0
  215. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/hft/__init__.py +0 -0
  216. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/hft/numba_utils.py +0 -0
  217. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/hft/orderbook.pyi +0 -0
  218. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/hft/orderbook.pyx +0 -0
  219. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/marketdata/binance.py +0 -0
  220. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/marketdata/ccxt.py +0 -0
  221. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/marketdata/dukas.py +0 -0
  222. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/nonce.py +0 -0
  223. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/ntp.py +0 -0
  224. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/numbers_utils.py +0 -0
  225. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/orderbook.py +0 -0
  226. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/plotting/__init__.py +0 -0
  227. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/plotting/dashboard.py +0 -0
  228. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/plotting/data.py +0 -0
  229. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/plotting/interfaces.py +0 -0
  230. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/plotting/renderers/__init__.py +0 -0
  231. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/plotting/renderers/plotly.py +0 -0
  232. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/questdb.py +0 -0
  233. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/rate_limiter.py +0 -0
  234. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/ringbuffer.pxd +0 -0
  235. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/ringbuffer.pyi +0 -0
  236. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/ringbuffer.pyx +0 -0
  237. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/__init__.py +0 -0
  238. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/_jupyter_runner.pyt +0 -0
  239. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/accounts.py +0 -0
  240. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/configs.py +0 -0
  241. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/factory.py +0 -0
  242. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/kernel_service.py +0 -0
  243. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/textual/__init__.py +0 -0
  244. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/textual/app.py +0 -0
  245. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/textual/handlers.py +0 -0
  246. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/textual/init_code.py +0 -0
  247. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/textual/kernel.py +0 -0
  248. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/textual/styles.tcss +0 -0
  249. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/textual/widgets/__init__.py +0 -0
  250. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/textual/widgets/command_input.py +0 -0
  251. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/textual/widgets/debug_log.py +0 -0
  252. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/textual/widgets/orders_table.py +0 -0
  253. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/textual/widgets/positions_table.py +0 -0
  254. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/textual/widgets/quotes_table.py +0 -0
  255. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/runner/textual/widgets/repl_output.py +0 -0
  256. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/slack.py +0 -0
  257. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/throttler.py +0 -0
  258. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/time.py +0 -0
  259. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/src/qubx/utils/websocket_manager.py +0 -0
  260. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/tests/strategies/macd_crossover/src/macd_crossover/indicators/macd.py +0 -0
  261. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/tests/strategies/macd_crossover/src/macd_crossover/models/macd_crossover.py +0 -0
  262. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/tests/strategies/macd_crossover/src/macd_crossover/models/utils.py +0 -0
  263. {qubx-1.0.0.dev3 → qubx-1.0.0.dev4}/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.0.dev3
3
+ Version: 1.0.0.dev4
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
@@ -33,6 +33,7 @@ Requires-Dist: psycopg-binary<4,>=3.1.19
33
33
  Requires-Dist: psycopg-pool<4,>=3.2.2
34
34
  Requires-Dist: psycopg<4,>=3.1.18
35
35
  Requires-Dist: pyarrow>=15.0.0
36
+ Requires-Dist: pydantic-settings<3,>=2.4.0
36
37
  Requires-Dist: pydantic<3,>=2.9.2
37
38
  Requires-Dist: pymongo<5,>=4.6.1
38
39
  Requires-Dist: python-binance<2,>=1.0.19
@@ -34,6 +34,7 @@ dependencies = [
34
34
  "importlib-metadata",
35
35
  "stackprinter>=0.2.10,<1",
36
36
  "pydantic>=2.9.2,<3",
37
+ "pydantic-settings>=2.4.0,<3",
37
38
  "python-dotenv>=1.0.0,<2",
38
39
  "cython==3.0.8",
39
40
  "croniter>=2.0.5,<3",
@@ -57,7 +57,13 @@ def formatter(record):
57
57
  class QubxLogConfig:
58
58
  @staticmethod
59
59
  def get_log_level():
60
- return os.getenv("QUBX_LOG_LEVEL", "WARNING")
60
+ # Env var takes priority (for CLI --log-level override), then settings
61
+ env_level = os.getenv("QUBX_LOG_LEVEL")
62
+ if env_level:
63
+ return env_level
64
+ from qubx.config import settings
65
+
66
+ return settings.log_level
61
67
 
62
68
  @staticmethod
63
69
  def set_log_level(level: str):
@@ -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.0.dev3'
32
- __version_tuple__ = version_tuple = (1, 0, 0, 'dev3')
31
+ __version__ = version = '1.0.0.dev4'
32
+ __version_tuple__ = version_tuple = (1, 0, 0, 'dev4')
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -105,11 +105,7 @@ class BacktestStorage:
105
105
 
106
106
  Args:
107
107
  base_path: Root path for backtest storage (local dir or cloud URI)
108
- storage_options: Cloud storage credentials. None = auto-detect from:
109
- QUBX_S3_KEY / AWS_ACCESS_KEY_ID
110
- QUBX_S3_SECRET / AWS_SECRET_ACCESS_KEY
111
- QUBX_S3_REGION / AWS_DEFAULT_REGION
112
- QUBX_S3_ENDPOINT / AWS_ENDPOINT_URL
108
+ storage_options: Cloud storage credentials dict. None = uses default_s3_account from settings.
113
109
  """
114
110
  try:
115
111
  import duckdb
@@ -217,33 +213,12 @@ class BacktestStorage:
217
213
 
218
214
  def _load_from_path(self, run_path: str) -> TradingSessionResult:
219
215
  """
220
- Load a TradingSessionResult using the already-configured DuckDB connection.
216
+ Load a TradingSessionResult from parquet storage (local or cloud).
221
217
 
222
- All parquet reads go through ``self._conn`` (httpfs for S3, local for disk)
223
- so no s3fs / aiobotocore dependency is needed and connection pooling is
224
- handled by DuckDB internally.
218
+ Delegates to SimulationResultsSaver.load() which reads data files
219
+ in parallel using a ThreadPoolExecutor.
225
220
  """
226
-
227
- def _read(filename: str) -> pd.DataFrame:
228
- p = f"{run_path.rstrip('/')}/{filename}"
229
- try:
230
- return self._conn.execute(f"SELECT * FROM read_parquet('{p}')").df()
231
- except Exception:
232
- return pd.DataFrame()
233
-
234
- meta_df = _read(SimulationResultsSaver.METADATA_FILE)
235
- if meta_df.empty:
236
- raise FileNotFoundError(f"Metadata not found at '{run_path}'")
237
-
238
- return SimulationResultsSaver._from_dfs(
239
- meta=meta_df.iloc[0].to_dict(),
240
- portfolio=_read(SimulationResultsSaver.DATA_FILES["portfolio"]),
241
- executions=_read(SimulationResultsSaver.DATA_FILES["executions"]),
242
- signals=_read(SimulationResultsSaver.DATA_FILES["signals"]),
243
- targets=_read(SimulationResultsSaver.DATA_FILES["targets"]),
244
- transfers=_read(SimulationResultsSaver.DATA_FILES["transfers"]),
245
- emitter=_read(SimulationResultsSaver.DATA_FILES["emitter"]),
246
- )
221
+ return SimulationResultsSaver.load(run_path, self._storage_options)
247
222
 
248
223
  def load(self, backtest_id: str) -> TradingSessionResult:
249
224
  """
@@ -33,7 +33,6 @@ from qubx.data.storage import IStorage
33
33
  from qubx.health import DummyHealthMonitor
34
34
  from qubx.loggers.inmemory import InMemoryLogsWriter
35
35
  from qubx.pandaz.utils import _frame_to_str
36
- from qubx.utils.results import SimulationResultsSaver
37
36
  from qubx.utils.runner.configs import PrefetchConfig
38
37
  from qubx.utils.time import now_ns
39
38
 
@@ -0,0 +1,139 @@
1
+ """Unified configuration management for Qubx.
2
+
3
+ Provides a single source of truth for all Qubx settings using pydantic-settings.
4
+ Configuration is loaded from (in priority order):
5
+ 1. Environment variables (prefix QUBX_)
6
+ 2. ~/.qubx/config.json
7
+
8
+ Usage:
9
+ from qubx.config import settings, get_s3_account
10
+
11
+ # Access settings
12
+ print(settings.log_level)
13
+ print(settings.s3)
14
+
15
+ # Get a named S3 account
16
+ account = get_s3_account("hetzner")
17
+ print(account.endpoint_url)
18
+ """
19
+
20
+ import json
21
+ from functools import lru_cache
22
+ from pathlib import Path
23
+ from typing import Any, ClassVar
24
+
25
+ from pydantic import BaseModel
26
+ from pydantic_settings import BaseSettings, PydanticBaseSettingsSource
27
+
28
+
29
+ class S3Account(BaseModel):
30
+ """S3-compatible storage account credentials."""
31
+
32
+ endpoint_url: str
33
+ access_key_id: str
34
+ secret_access_key: str
35
+ region: str | None = None
36
+
37
+
38
+ class LookupConfig(BaseModel):
39
+ """Configuration for instrument/fees lookups."""
40
+
41
+ type: str = "file"
42
+ mongo_url: str | None = None
43
+ reload_interval: str | None = None
44
+ path: str | None = None
45
+
46
+
47
+ class _QubxJsonConfigSource(PydanticBaseSettingsSource):
48
+ """Load settings from ~/.qubx/config.json."""
49
+
50
+ _CONFIG_PATH: ClassVar[Path] = Path.home() / ".qubx" / "config.json"
51
+
52
+ def __init__(self, settings_cls: type[BaseSettings], config_path: Path | None = None):
53
+ super().__init__(settings_cls)
54
+ self._path = config_path or self._CONFIG_PATH
55
+
56
+ def get_field_value(self, field: Any, field_name: str) -> tuple[Any, str, bool]:
57
+ data = self._load()
58
+ value = data.get(field_name)
59
+ return value, field_name, value is not None
60
+
61
+ def _load(self) -> dict:
62
+ if not self._path.exists():
63
+ return {}
64
+ try:
65
+ return json.loads(self._path.read_text())
66
+ except (json.JSONDecodeError, OSError):
67
+ return {}
68
+
69
+ def __call__(self) -> dict[str, Any]:
70
+ data = self._load()
71
+ return {k: v for k, v in data.items() if v is not None}
72
+
73
+
74
+ class QubxSettings(BaseSettings):
75
+ """Qubx framework settings.
76
+
77
+ Resolution order:
78
+ 1. Environment variables (prefix QUBX_, nested with __)
79
+ 2. ~/.qubx/config.json
80
+ 3. Defaults
81
+ """
82
+
83
+ s3: dict[str, S3Account] = {}
84
+ default_s3_account: str | None = None
85
+ log_level: str = "WARNING"
86
+ instrument_lookup: LookupConfig = LookupConfig()
87
+ fees_lookup: LookupConfig = LookupConfig()
88
+
89
+ model_config = {"env_prefix": "QUBX_", "env_nested_delimiter": "__"}
90
+
91
+ @classmethod
92
+ def settings_customise_sources(
93
+ cls,
94
+ settings_cls: type[BaseSettings],
95
+ init_settings: PydanticBaseSettingsSource,
96
+ env_settings: PydanticBaseSettingsSource,
97
+ dotenv_settings: PydanticBaseSettingsSource,
98
+ file_secret_settings: PydanticBaseSettingsSource,
99
+ ) -> tuple[PydanticBaseSettingsSource, ...]:
100
+ return (
101
+ init_settings,
102
+ env_settings,
103
+ dotenv_settings,
104
+ _QubxJsonConfigSource(settings_cls),
105
+ )
106
+
107
+
108
+ @lru_cache(maxsize=1)
109
+ def get_settings() -> QubxSettings:
110
+ """Get the singleton QubxSettings instance."""
111
+ return QubxSettings()
112
+
113
+
114
+ def get_s3_account(name: str) -> S3Account:
115
+ """Look up a named S3 account from settings.
116
+
117
+ Args:
118
+ name: Account name (e.g., "hetzner")
119
+
120
+ Returns:
121
+ S3Account with credentials
122
+
123
+ Raises:
124
+ KeyError: If account not found
125
+ """
126
+ s = get_settings()
127
+ if name not in s.s3:
128
+ available = list(s.s3.keys()) or "(none)"
129
+ raise KeyError(f"S3 account '{name}' not found in config. Available: {available}")
130
+ return s.s3[name]
131
+
132
+
133
+ def reset_settings() -> None:
134
+ """Clear the cached settings (useful for testing)."""
135
+ get_settings.cache_clear()
136
+
137
+
138
+ # Module-level singleton
139
+ settings = get_settings()
@@ -27,9 +27,6 @@ _DEF_FEES_FOLDER = "fees"
27
27
 
28
28
  _PACKAGED_FEES_FILE = "crypto-fees.ini"
29
29
 
30
- _INI_FILE = "settings.ini"
31
- _INI_SECTION_INSTRUMENTS = "instrument-lookup"
32
- _INI_SECTION_FEES = "fees-lookup"
33
30
 
34
31
 
35
32
  class _InstrumentEncoder(json.JSONEncoder):
@@ -451,19 +448,24 @@ class LookupsManager(InstrumentsLookup, FeesLookup):
451
448
  if not hasattr(cls, "instance"):
452
449
  cls.instance = super(LookupsManager, cls).__new__(cls)
453
450
 
454
- # - try to load settings
455
- parser = configparser.ConfigParser()
456
- parser.read(Path(get_local_qubx_folder()) / _INI_FILE)
451
+ from qubx.config import settings
457
452
 
458
- if _INI_SECTION_INSTRUMENTS in parser:
459
- cls.instance._i_lookup = LookupsManager._get_instrument_lookup(**dict(parser[_INI_SECTION_INSTRUMENTS]))
460
- else:
461
- cls.instance._i_lookup = FileInstrumentsLookupWithCCXT()
453
+ i_cfg = settings.instrument_lookup
454
+ f_cfg = settings.fees_lookup
462
455
 
463
- if _INI_SECTION_FEES in parser:
464
- cls.instance._t_lookup = LookupsManager._get_fees_lookup(**dict(parser[_INI_SECTION_FEES]))
465
- else:
466
- cls.instance._t_lookup = FeesLookupFile()
456
+ i_kwargs = {}
457
+ if i_cfg.mongo_url:
458
+ i_kwargs["mongo_url"] = i_cfg.mongo_url
459
+ if i_cfg.reload_interval:
460
+ i_kwargs["reload_interval"] = i_cfg.reload_interval
461
+ if i_cfg.path:
462
+ i_kwargs["path"] = i_cfg.path
463
+ cls.instance._i_lookup = LookupsManager._get_instrument_lookup(type=i_cfg.type, **i_kwargs)
464
+
465
+ f_kwargs = {}
466
+ if f_cfg.path:
467
+ f_kwargs["path"] = f_cfg.path
468
+ cls.instance._t_lookup = LookupsManager._get_fees_lookup(type=f_cfg.type, **f_kwargs)
467
469
 
468
470
  return cls.instance
469
471
 
@@ -713,8 +713,12 @@ class TradingSessionResult:
713
713
  creation_time=self.creation_time,
714
714
  author=self.author,
715
715
  variation_name=self.variation_name,
716
- emitter_data=_slice_df(self.emitter_data),
717
- transfers_log=_slice_df(self.transfers_log),
716
+ emitter_data=_slice_df(self.emitter_data.set_index("timestamp")).reset_index()
717
+ if self.emitter_data is not None
718
+ else None,
719
+ transfers_log=_slice_df(self.transfers_log.set_index("timestamp")).reset_index()
720
+ if self.transfers_log is not None
721
+ else None,
718
722
  )
719
723
  tsr.qubx_version = self.qubx_version
720
724
  tsr.description = self.description