OctoBot-Trading 2.4.167__tar.gz → 2.4.169__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 (494) hide show
  1. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/CHANGELOG.md +8 -0
  2. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169/OctoBot_Trading.egg-info}/PKG-INFO +2 -2
  3. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/OctoBot_Trading.egg-info/SOURCES.txt +1 -0
  4. {OctoBot-Trading-2.4.167/OctoBot_Trading.egg-info → OctoBot-Trading-2.4.169}/PKG-INFO +2 -2
  5. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/README.md +1 -1
  6. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/__init__.py +1 -1
  7. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/api/__init__.py +2 -0
  8. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/api/orders.py +6 -0
  9. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/util/exchange_util.py +7 -1
  10. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/__init__.py +4 -0
  11. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/__init__.py +4 -0
  12. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/order_util.py +37 -0
  13. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/portfolio_util.py +87 -26
  14. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/sub_portfolio_data.py +32 -0
  15. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/types/spot_portfolio.py +2 -8
  16. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/util/test_exchange_util.py +42 -1
  17. OctoBot-Trading-2.4.169/tests/personal_data/portfolios/test_portfolio_util.py +566 -0
  18. OctoBot-Trading-2.4.169/tests/personal_data/portfolios/test_sub_portfolio_data.py +123 -0
  19. OctoBot-Trading-2.4.167/tests/personal_data/portfolios/test_portfolio_util.py +0 -318
  20. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/LICENSE +0 -0
  21. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/MANIFEST.in +0 -0
  22. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/OctoBot_Trading.egg-info/dependency_links.txt +0 -0
  23. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/OctoBot_Trading.egg-info/not-zip-safe +0 -0
  24. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/OctoBot_Trading.egg-info/requires.txt +0 -0
  25. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/OctoBot_Trading.egg-info/top_level.txt +0 -0
  26. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/api/channels.py +0 -0
  27. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/api/contracts.py +0 -0
  28. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/api/exchange.py +0 -0
  29. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/api/modes.py +0 -0
  30. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/api/portfolio.py +0 -0
  31. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/api/positions.py +0 -0
  32. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/api/profitability.py +0 -0
  33. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/api/storage.py +0 -0
  34. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/api/symbol_data.py +0 -0
  35. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/api/trader.py +0 -0
  36. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/api/trades.py +0 -0
  37. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/constants.py +0 -0
  38. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/enums.py +0 -0
  39. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/errors.py +0 -0
  40. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_channel.py +0 -0
  41. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/__init__.py +0 -0
  42. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/contracts/__init__.py +0 -0
  43. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/contracts/contract_factory.py +0 -0
  44. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/contracts/future_contract.py +0 -0
  45. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/contracts/margin_contract.py +0 -0
  46. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/exchange_symbol_data.py +0 -0
  47. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/exchange_symbols_data.py +0 -0
  48. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/funding/__init__.py +0 -0
  49. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/funding/channel/__init__.py +0 -0
  50. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/funding/channel/funding.py +0 -0
  51. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/funding/channel/funding_updater.py +0 -0
  52. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/funding/channel/funding_updater_simulator.py +0 -0
  53. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/funding/funding_manager.py +0 -0
  54. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/kline/__init__.py +0 -0
  55. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/kline/channel/__init__.py +0 -0
  56. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/kline/channel/kline.py +0 -0
  57. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/kline/channel/kline_updater.py +0 -0
  58. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/kline/channel/kline_updater_simulator.py +0 -0
  59. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/kline/kline_manager.py +0 -0
  60. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ohlcv/__init__.py +0 -0
  61. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ohlcv/candles_adapter.py +0 -0
  62. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ohlcv/candles_manager.py +0 -0
  63. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ohlcv/channel/__init__.py +0 -0
  64. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ohlcv/channel/ohlcv.py +0 -0
  65. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ohlcv/channel/ohlcv_updater.py +0 -0
  66. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ohlcv/channel/ohlcv_updater_simulator.py +0 -0
  67. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ohlcv/preloaded_candles_manager.py +0 -0
  68. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/order_book/__init__.py +0 -0
  69. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/order_book/channel/__init__.py +0 -0
  70. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/order_book/channel/order_book.py +0 -0
  71. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/order_book/channel/order_book_updater.py +0 -0
  72. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/order_book/channel/order_book_updater_simulator.py +0 -0
  73. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/order_book/order_book_manager.py +0 -0
  74. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/prices/__init__.py +0 -0
  75. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/prices/channel/__init__.py +0 -0
  76. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/prices/channel/price.py +0 -0
  77. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/prices/channel/prices_updater.py +0 -0
  78. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/prices/channel/prices_updater_simulator.py +0 -0
  79. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/prices/price_events_manager.py +0 -0
  80. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/prices/prices_manager.py +0 -0
  81. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/recent_trades/__init__.py +0 -0
  82. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/recent_trades/channel/__init__.py +0 -0
  83. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/recent_trades/channel/recent_trade.py +0 -0
  84. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/recent_trades/channel/recent_trade_updater.py +0 -0
  85. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/recent_trades/channel/recent_trade_updater_simulator.py +0 -0
  86. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/recent_trades/recent_trades_manager.py +0 -0
  87. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ticker/__init__.py +0 -0
  88. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ticker/channel/__init__.py +0 -0
  89. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ticker/channel/ticker.py +0 -0
  90. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ticker/channel/ticker_updater.py +0 -0
  91. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ticker/channel/ticker_updater_simulator.py +0 -0
  92. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchange_data/ticker/ticker_manager.py +0 -0
  93. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/__init__.py +0 -0
  94. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/abstract_exchange.py +0 -0
  95. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/abstract_websocket_exchange.py +0 -0
  96. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/adapters/__init__.py +0 -0
  97. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/adapters/abstract_adapter.py +0 -0
  98. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/config/__init__.py +0 -0
  99. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/config/backtesting_exchange_config.py +0 -0
  100. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/config/exchange_config_data.py +0 -0
  101. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/config/proxy_config.py +0 -0
  102. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/connectors/__init__.py +0 -0
  103. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/connectors/ccxt/__init__.py +0 -0
  104. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/connectors/ccxt/ccxt_adapter.py +0 -0
  105. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/connectors/ccxt/ccxt_client_util.py +0 -0
  106. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/connectors/ccxt/ccxt_clients_cache.py +0 -0
  107. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/connectors/ccxt/ccxt_connector.py +0 -0
  108. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/connectors/ccxt/ccxt_websocket_connector.py +0 -0
  109. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/connectors/ccxt/constants.py +0 -0
  110. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/connectors/ccxt/enums.py +0 -0
  111. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/connectors/simulator/__init__.py +0 -0
  112. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/connectors/simulator/ccxt_client_simulation.py +0 -0
  113. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/connectors/simulator/exchange_simulator_adapter.py +0 -0
  114. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/connectors/simulator/exchange_simulator_connector.py +0 -0
  115. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/exchange_builder.py +0 -0
  116. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/exchange_channels.py +0 -0
  117. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/exchange_details.py +0 -0
  118. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/exchange_factory.py +0 -0
  119. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/exchange_manager.py +0 -0
  120. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/exchange_websocket_factory.py +0 -0
  121. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/exchanges.py +0 -0
  122. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/implementations/__init__.py +0 -0
  123. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/implementations/default_rest_exchange.py +0 -0
  124. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/implementations/default_websocket_exchange.py +0 -0
  125. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/implementations/exchange_simulator.py +0 -0
  126. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/traders/__init__.py +0 -0
  127. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/traders/trader.py +0 -0
  128. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/traders/trader_simulator.py +0 -0
  129. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/types/__init__.py +0 -0
  130. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/types/rest_exchange.py +0 -0
  131. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/types/websocket_exchange.py +0 -0
  132. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/util/__init__.py +0 -0
  133. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/util/exchange_market_status_fixer.py +0 -0
  134. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/util/symbol_details.py +0 -0
  135. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/exchanges/util/websockets_util.py +0 -0
  136. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/__init__.py +0 -0
  137. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/abstract_trading_mode.py +0 -0
  138. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/channel/__init__.py +0 -0
  139. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/channel/abstract_mode_consumer.py +0 -0
  140. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/channel/abstract_mode_producer.py +0 -0
  141. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/channel/mode.py +0 -0
  142. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/mode_activity.py +0 -0
  143. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/mode_config.py +0 -0
  144. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/modes_factory.py +0 -0
  145. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/modes_util.py +0 -0
  146. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/__init__.py +0 -0
  147. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/basic_keywords/__init__.py +0 -0
  148. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/basic_keywords/account_balance.py +0 -0
  149. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/basic_keywords/amount.py +0 -0
  150. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/basic_keywords/configuration.py +0 -0
  151. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/basic_keywords/position.py +0 -0
  152. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/basic_keywords/price.py +0 -0
  153. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/basic_keywords/run_persistence.py +0 -0
  154. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/basic_keywords/trading_signals.py +0 -0
  155. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/basic_keywords/user_inputs.py +0 -0
  156. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/context_management.py +0 -0
  157. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/dsl/__init__.py +0 -0
  158. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/dsl/quantity.py +0 -0
  159. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/script_keywords/dsl/values.py +0 -0
  160. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/scripted_trading_mode/__init__.py +0 -0
  161. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/modes/scripted_trading_mode/abstract_scripted_trading_mode.py +0 -0
  162. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/octobot_channel_consumer.py +0 -0
  163. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/exchange_personal_data.py +0 -0
  164. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/channel/__init__.py +0 -0
  165. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/channel/orders.py +0 -0
  166. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/channel/orders_updater.py +0 -0
  167. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/channel/orders_updater_simulator.py +0 -0
  168. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/decimal_order_adapter.py +0 -0
  169. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/groups/__init__.py +0 -0
  170. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/groups/balanced_take_profit_and_stop_order_group.py +0 -0
  171. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/groups/group_util.py +0 -0
  172. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/groups/one_cancels_the_other_order_group.py +0 -0
  173. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/groups/trailing_on_filled_tp_balanced_order_group.py +0 -0
  174. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/order.py +0 -0
  175. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/order_adapter.py +0 -0
  176. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/order_factory.py +0 -0
  177. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/order_group.py +0 -0
  178. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/order_state.py +0 -0
  179. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/orders_manager.py +0 -0
  180. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/orders_storage_operations.py +0 -0
  181. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/states/__init__.py +0 -0
  182. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/states/cancel_order_state.py +0 -0
  183. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/states/close_order_state.py +0 -0
  184. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/states/fill_order_state.py +0 -0
  185. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/states/open_order_state.py +0 -0
  186. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/states/order_state_factory.py +0 -0
  187. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/states/pending_creation_chained_order_state.py +0 -0
  188. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/states/pending_creation_order_state.py +0 -0
  189. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/trailing_profiles/__init__.py +0 -0
  190. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/trailing_profiles/filled_take_profit_trailing_profile.py +0 -0
  191. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/trailing_profiles/trailing_price_step.py +0 -0
  192. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/trailing_profiles/trailing_profile.py +0 -0
  193. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/trailing_profiles/trailing_profile_factory.py +0 -0
  194. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/trailing_profiles/trailing_profile_types.py +0 -0
  195. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/__init__.py +0 -0
  196. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/limit/__init__.py +0 -0
  197. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/limit/buy_limit_order.py +0 -0
  198. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/limit/limit_order.py +0 -0
  199. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/limit/sell_limit_order.py +0 -0
  200. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/limit/stop_loss_limit_order.py +0 -0
  201. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/limit/stop_loss_order.py +0 -0
  202. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/limit/take_profit_limit_order.py +0 -0
  203. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/limit/take_profit_order.py +0 -0
  204. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/market/__init__.py +0 -0
  205. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/market/buy_market_order.py +0 -0
  206. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/market/market_order.py +0 -0
  207. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/market/sell_market_order.py +0 -0
  208. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/trailing/__init__.py +0 -0
  209. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/trailing/trailing_stop_limit_order.py +0 -0
  210. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/trailing/trailing_stop_order.py +0 -0
  211. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/unknown_order.py +0 -0
  212. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/orders/types/unsupported_order.py +0 -0
  213. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/__init__.py +0 -0
  214. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/asset.py +0 -0
  215. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/assets/__init__.py +0 -0
  216. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/assets/future_asset.py +0 -0
  217. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/assets/margin_asset.py +0 -0
  218. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/assets/spot_asset.py +0 -0
  219. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/channel/__init__.py +0 -0
  220. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/channel/balance.py +0 -0
  221. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/channel/balance_updater.py +0 -0
  222. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/channel/balance_updater_simulator.py +0 -0
  223. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/history/__init__.py +0 -0
  224. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/history/historical_asset_value.py +0 -0
  225. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/history/historical_asset_value_factory.py +0 -0
  226. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/history/historical_portfolio_value_manager.py +0 -0
  227. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/portfolio.py +0 -0
  228. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/portfolio_factory.py +0 -0
  229. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/portfolio_manager.py +0 -0
  230. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/portfolio_profitability.py +0 -0
  231. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/portfolio_value_holder.py +0 -0
  232. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/sub_portfolio.py +0 -0
  233. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/types/__init__.py +0 -0
  234. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/types/future_portfolio.py +0 -0
  235. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/types/margin_portfolio.py +0 -0
  236. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/portfolios/value_converter.py +0 -0
  237. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/__init__.py +0 -0
  238. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/channel/__init__.py +0 -0
  239. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/channel/positions.py +0 -0
  240. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/channel/positions_updater.py +0 -0
  241. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/channel/positions_updater_simulator.py +0 -0
  242. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/position.py +0 -0
  243. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/position_factory.py +0 -0
  244. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/position_state.py +0 -0
  245. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/position_util.py +0 -0
  246. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/positions_manager.py +0 -0
  247. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/states/__init__.py +0 -0
  248. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/states/active_position_state.py +0 -0
  249. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/states/idle_position_state.py +0 -0
  250. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/states/liquidate_position_state.py +0 -0
  251. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/states/position_state_factory.py +0 -0
  252. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/types/__init__.py +0 -0
  253. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/types/inverse_position.py +0 -0
  254. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/positions/types/linear_position.py +0 -0
  255. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/state.py +0 -0
  256. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/trades/__init__.py +0 -0
  257. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/trades/channel/__init__.py +0 -0
  258. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/trades/channel/trades.py +0 -0
  259. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/trades/channel/trades_updater.py +0 -0
  260. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/trades/trade.py +0 -0
  261. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/trades/trade_factory.py +0 -0
  262. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/trades/trade_pnl.py +0 -0
  263. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/trades/trades_manager.py +0 -0
  264. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/trades/trades_util.py +0 -0
  265. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/transactions/__init__.py +0 -0
  266. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/transactions/transaction.py +0 -0
  267. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/transactions/transaction_factory.py +0 -0
  268. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/transactions/transactions_manager.py +0 -0
  269. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/transactions/types/__init__.py +0 -0
  270. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/transactions/types/blockchain_transaction.py +0 -0
  271. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/transactions/types/fee_transaction.py +0 -0
  272. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/transactions/types/realised_pnl_transaction.py +0 -0
  273. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/personal_data/transactions/types/transfer_transaction.py +0 -0
  274. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/signals/__init__.py +0 -0
  275. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/signals/channel/__init__.py +0 -0
  276. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/signals/channel/remote_trading_signal.py +0 -0
  277. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/signals/channel/remote_trading_signal_channel_factory.py +0 -0
  278. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/signals/channel/signal_producer.py +0 -0
  279. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/signals/signal_creation.py +0 -0
  280. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/signals/trading_signal_bundle_builder.py +0 -0
  281. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/signals/util.py +0 -0
  282. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/storage/__init__.py +0 -0
  283. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/storage/abstract_storage.py +0 -0
  284. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/storage/candles_storage.py +0 -0
  285. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/storage/orders_storage.py +0 -0
  286. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/storage/portfolio_storage.py +0 -0
  287. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/storage/storage_manager.py +0 -0
  288. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/storage/trades_storage.py +0 -0
  289. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/storage/transactions_storage.py +0 -0
  290. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/storage/util.py +0 -0
  291. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/supervisors/__init__.py +0 -0
  292. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/supervisors/abstract_portfolio_supervisor.py +0 -0
  293. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/supervisors/abstract_supervisor.py +0 -0
  294. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/util/__init__.py +0 -0
  295. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/util/config_util.py +0 -0
  296. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/util/initializable.py +0 -0
  297. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/util/initialization_util.py +0 -0
  298. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/util/simulator_updater_utils.py +0 -0
  299. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/util/test_tools/__init__.py +0 -0
  300. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/util/test_tools/exchange_data.py +0 -0
  301. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/util/test_tools/exchanges_test_tools.py +0 -0
  302. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/util/test_tools/spot_rest_exchange_test_tools.py +0 -0
  303. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/octobot_trading/util/test_tools/websocket_test_tools.py +0 -0
  304. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/requirements.txt +0 -0
  305. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/setup.cfg +0 -0
  306. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/setup.py +0 -0
  307. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/api/__init__.py +0 -0
  308. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/api/test_channels.py +0 -0
  309. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/api/test_exchange.py +0 -0
  310. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/api/test_modes.py +0 -0
  311. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/api/test_orders.py +0 -0
  312. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/api/test_portfolio.py +0 -0
  313. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/api/test_profitability.py +0 -0
  314. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/api/test_symbol_data.py +0 -0
  315. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/api/test_trader.py +0 -0
  316. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/api/test_trades.py +0 -0
  317. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/cli/__init__.py +0 -0
  318. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/__init__.py +0 -0
  319. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/contracts/__init__.py +0 -0
  320. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/contracts/test_future_contract.py +0 -0
  321. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/contracts/test_margin_contract.py +0 -0
  322. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/funding/__init__.py +0 -0
  323. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/funding/test_funding_manager.py +0 -0
  324. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/kline/__init__.py +0 -0
  325. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/kline/test_kline_manager.py +0 -0
  326. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/ohlcv/__init__.py +0 -0
  327. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/ohlcv/test_candles_adapter.py +0 -0
  328. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/ohlcv/test_candles_manager.py +0 -0
  329. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/order_book/__init__.py +0 -0
  330. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/order_book/test_order_book_manager.py +0 -0
  331. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/prices/__init__.py +0 -0
  332. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/prices/test_price_events_manager.py +0 -0
  333. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/prices/test_prices_manager.py +0 -0
  334. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/recent_trades/__init__.py +0 -0
  335. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/recent_trades/test_recent_trades_manager.py +0 -0
  336. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/test_exchange_symbols_data.py +0 -0
  337. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/ticker/__init__.py +0 -0
  338. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchange_data/ticker/test_ticker_manager.py +0 -0
  339. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/__init__.py +0 -0
  340. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/connectors/__init__.py +0 -0
  341. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/connectors/ccxt/__init__.py +0 -0
  342. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/connectors/ccxt/mock_exchanges_data.py +0 -0
  343. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/connectors/ccxt/test_ccxt_connector.py +0 -0
  344. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/implementations/__init__.py +0 -0
  345. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/implementations/test_default_rest_exchange.py +0 -0
  346. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/implementations/test_default_websocket_exchange.py +0 -0
  347. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/test_abstract_exchange.py +0 -0
  348. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/test_abstract_websocket_exchange.py +0 -0
  349. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/test_exchange_builder.py +0 -0
  350. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/test_exchange_config_data.py +0 -0
  351. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/test_exchange_factory.py +0 -0
  352. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/test_exchange_manager.py +0 -0
  353. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/test_exchange_simulator.py +0 -0
  354. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/test_exchanges.py +0 -0
  355. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/traders/__init__.py +0 -0
  356. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/traders/test_trader.py +0 -0
  357. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/types/__init__.py +0 -0
  358. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/types/test_websocket_exchange.py +0 -0
  359. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/util/__init__.py +0 -0
  360. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/exchanges/util/test_exchange_market_status_fixer.py +0 -0
  361. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/modes/__init__.py +0 -0
  362. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/modes/script_keywords/__init__.py +0 -0
  363. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/modes/script_keywords/basic_keywords/__init__.py +0 -0
  364. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/modes/script_keywords/basic_keywords/test_account_balance.py +0 -0
  365. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/modes/script_keywords/basic_keywords/test_amount.py +0 -0
  366. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/modes/script_keywords/basic_keywords/test_position.py +0 -0
  367. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/modes/script_keywords/basic_keywords/test_price.py +0 -0
  368. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/modes/script_keywords/dsl/__init__.py +0 -0
  369. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/modes/script_keywords/dsl/test_quantity.py +0 -0
  370. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/modes/test_abstract_mode_consumer.py +0 -0
  371. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/modes/test_abstract_trading_mode.py +0 -0
  372. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/modes/test_modes_util.py +0 -0
  373. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/__init__.py +0 -0
  374. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/__init__.py +0 -0
  375. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/groups/__init__.py +0 -0
  376. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/groups/test_balanced_take_profit_and_stop_order_group.py +0 -0
  377. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/groups/test_group_util.py +0 -0
  378. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/groups/test_one_cancels_the_other_order_group.py +0 -0
  379. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/groups/test_trailing_on_filled_tp_balanced_order_group.py +0 -0
  380. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/states/__init__.py +0 -0
  381. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/states/test_cancel_order_state.py +0 -0
  382. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/states/test_close_order_state.py +0 -0
  383. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/states/test_fill_order_state.py +0 -0
  384. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/states/test_open_order_state.py +0 -0
  385. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/states/test_order_state.py +0 -0
  386. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/states/test_order_state_factory.py +0 -0
  387. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/states/test_pending_creation_chained_order_state.py +0 -0
  388. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/states/test_pending_creation_order_state.py +0 -0
  389. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/test_decimal_order_adapter.py +0 -0
  390. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/test_double_filled_order.py +0 -0
  391. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/test_order.py +0 -0
  392. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/test_order_adapter.py +0 -0
  393. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/test_order_factory.py +0 -0
  394. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/test_order_util.py +0 -0
  395. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/test_orders_manager.py +0 -0
  396. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/test_orders_storage_operations.py +0 -0
  397. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/trailing_profiles/__init__.py +0 -0
  398. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/trailing_profiles/test_filled_take_profit_trailing_profile.py +0 -0
  399. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/trailing_profiles/test_trailing_profile_factory.py +0 -0
  400. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/__init__.py +0 -0
  401. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/limit/__init__.py +0 -0
  402. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/limit/test_buy_limit_order.py +0 -0
  403. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/limit/test_limit_order.py +0 -0
  404. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/limit/test_sell_limit_order.py +0 -0
  405. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/limit/test_stop_loss_limit_order.py +0 -0
  406. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/limit/test_stop_loss_order.py +0 -0
  407. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/limit/test_take_profit_limit_order.py +0 -0
  408. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/limit/test_take_profit_order.py +0 -0
  409. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/market/__init__.py +0 -0
  410. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/market/test_buy_market_order.py +0 -0
  411. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/market/test_sell_market_order.py +0 -0
  412. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/test_unknown_order.py +0 -0
  413. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/trailing/__init__.py +0 -0
  414. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/trailing/test_trailing_stop_limit_order.py +0 -0
  415. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/orders/types/trailing/test_trailing_stop_order.py +0 -0
  416. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/__init__.py +0 -0
  417. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/assets/__init__.py +0 -0
  418. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/assets/test_future_asset.py +0 -0
  419. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/assets/test_margin_asset.py +0 -0
  420. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/assets/test_spot_asset.py +0 -0
  421. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/history/__init__.py +0 -0
  422. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/history/test_historical_asset_value_factory.py +0 -0
  423. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/history/test_historical_portfolio_value_manager.py +0 -0
  424. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/test_asset.py +0 -0
  425. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/test_portfolio.py +0 -0
  426. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/test_portfolio_manager.py +0 -0
  427. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/test_portfolio_profitability.py +0 -0
  428. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/test_portfolio_value_holder.py +0 -0
  429. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/test_value_converter.py +0 -0
  430. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/types/__init__.py +0 -0
  431. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/types/test_future_portfolio.py +0 -0
  432. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/types/test_margin_portfolio.py +0 -0
  433. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/portfolios/types/test_spot_portfolio.py +0 -0
  434. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/positions/__init__.py +0 -0
  435. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/positions/channel/__init__.py +0 -0
  436. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/positions/states/__init__.py +0 -0
  437. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/positions/test_position.py +0 -0
  438. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/positions/test_position_factory.py +0 -0
  439. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/positions/test_positions_manager.py +0 -0
  440. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/positions/types/__init__.py +0 -0
  441. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/positions/types/test_inverse_position.py +0 -0
  442. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/positions/types/test_linear_position.py +0 -0
  443. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/trades/__init__.py +0 -0
  444. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/trades/test_trade_factory.py +0 -0
  445. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/trades/test_trade_manager.py +0 -0
  446. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/trades/test_trade_pnl.py +0 -0
  447. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/trades/test_trade_util.py +0 -0
  448. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/transactions/__init__.py +0 -0
  449. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/transactions/test_transaction_factory.py +0 -0
  450. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/personal_data/transactions/test_transactions_manager.py +0 -0
  451. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/signals/__init__.py +0 -0
  452. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/signals/test_trading_signal_bundle_builder.py +0 -0
  453. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/signals/test_util.py +0 -0
  454. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/test_utils/__init__.py +0 -0
  455. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/test_utils/order_util.py +0 -0
  456. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/test_utils/random_numbers.py +0 -0
  457. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/util/__init__.py +0 -0
  458. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests/util/test_config_util.py +0 -0
  459. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/__init__.py +0 -0
  460. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/__init__.py +0 -0
  461. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/real_exchange_tester.py +0 -0
  462. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/real_futures_exchange_tester.py +0 -0
  463. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_ascendex.py +0 -0
  464. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_binance.py +0 -0
  465. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_binance_futures.py +0 -0
  466. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_bingx.py +0 -0
  467. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_bitfinex.py +0 -0
  468. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_bitget.py +0 -0
  469. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_bithumb.py +0 -0
  470. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_bitmart.py +0 -0
  471. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_bitmex.py +0 -0
  472. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_bitso.py +0 -0
  473. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_bitstamp.py +0 -0
  474. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_bybit.py +0 -0
  475. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_bybit_futures.py +0 -0
  476. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_coinbase.py +0 -0
  477. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_coinex.py +0 -0
  478. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_cryptocom.py +0 -0
  479. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_gateio.py +0 -0
  480. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_hitbtc.py +0 -0
  481. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_hollaex.py +0 -0
  482. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_htx.py +0 -0
  483. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_kraken.py +0 -0
  484. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_kucoin.py +0 -0
  485. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_kucoin_futures.py +0 -0
  486. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_mexc.py +0 -0
  487. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_ndax.py +0 -0
  488. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_okcoin.py +0 -0
  489. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_okx.py +0 -0
  490. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_okx_futures.py +0 -0
  491. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_phemex.py +0 -0
  492. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_poloniex.py +0 -0
  493. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_upbit.py +0 -0
  494. {OctoBot-Trading-2.4.167 → OctoBot-Trading-2.4.169}/tests_additional/real_exchanges/test_wavesexchange.py +0 -0
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [2.4.169] - 2025-04-11
8
+ ### Fixed
9
+ [Subportfolio] handle fees hedge cases for filled oreders deltas
10
+
11
+ ## [2.4.168] - 2025-04-01
12
+ ### Updated
13
+ [Subportfolio] handle locked funds from open orders
14
+
7
15
  ## [2.4.167] - 2025-03-31
8
16
  ### Updated
9
17
  [Orders] fixed maker/taker fees of chained orders
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: OctoBot-Trading
3
- Version: 2.4.167
3
+ Version: 2.4.169
4
4
  Summary: OctoBot project trading package
5
5
  Home-page: https://github.com/Drakkar-Software/OctoBot-Trading
6
6
  Author: Drakkar-Software
@@ -16,7 +16,7 @@ Classifier: Operating System :: POSIX
16
16
  Requires-Python: >=3.8
17
17
  License-File: LICENSE
18
18
 
19
- # OctoBot-Trading [2.4.167](https://github.com/Drakkar-Software/OctoBot-Trading/blob/master/CHANGELOG.md)
19
+ # OctoBot-Trading [2.4.169](https://github.com/Drakkar-Software/OctoBot-Trading/blob/master/CHANGELOG.md)
20
20
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/903b6b22bceb4661b608a86fea655f69)](https://app.codacy.com/gh/Drakkar-Software/OctoBot-Trading?utm_source=github.com&utm_medium=referral&utm_content=Drakkar-Software/OctoBot-Trading&utm_campaign=Badge_Grade_Dashboard)
21
21
  [![PyPI](https://img.shields.io/pypi/v/OctoBot-Trading.svg)](https://pypi.python.org/pypi/OctoBot-Trading/)
22
22
  [![Coverage Status](https://coveralls.io/repos/github/Drakkar-Software/OctoBot-Trading/badge.svg?branch=master)](https://coveralls.io/github/Drakkar-Software/OctoBot-Trading?branch=master)
@@ -415,6 +415,7 @@ tests/personal_data/portfolios/test_portfolio_manager.py
415
415
  tests/personal_data/portfolios/test_portfolio_profitability.py
416
416
  tests/personal_data/portfolios/test_portfolio_util.py
417
417
  tests/personal_data/portfolios/test_portfolio_value_holder.py
418
+ tests/personal_data/portfolios/test_sub_portfolio_data.py
418
419
  tests/personal_data/portfolios/test_value_converter.py
419
420
  tests/personal_data/portfolios/assets/__init__.py
420
421
  tests/personal_data/portfolios/assets/test_future_asset.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: OctoBot-Trading
3
- Version: 2.4.167
3
+ Version: 2.4.169
4
4
  Summary: OctoBot project trading package
5
5
  Home-page: https://github.com/Drakkar-Software/OctoBot-Trading
6
6
  Author: Drakkar-Software
@@ -16,7 +16,7 @@ Classifier: Operating System :: POSIX
16
16
  Requires-Python: >=3.8
17
17
  License-File: LICENSE
18
18
 
19
- # OctoBot-Trading [2.4.167](https://github.com/Drakkar-Software/OctoBot-Trading/blob/master/CHANGELOG.md)
19
+ # OctoBot-Trading [2.4.169](https://github.com/Drakkar-Software/OctoBot-Trading/blob/master/CHANGELOG.md)
20
20
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/903b6b22bceb4661b608a86fea655f69)](https://app.codacy.com/gh/Drakkar-Software/OctoBot-Trading?utm_source=github.com&utm_medium=referral&utm_content=Drakkar-Software/OctoBot-Trading&utm_campaign=Badge_Grade_Dashboard)
21
21
  [![PyPI](https://img.shields.io/pypi/v/OctoBot-Trading.svg)](https://pypi.python.org/pypi/OctoBot-Trading/)
22
22
  [![Coverage Status](https://coveralls.io/repos/github/Drakkar-Software/OctoBot-Trading/badge.svg?branch=master)](https://coveralls.io/github/Drakkar-Software/OctoBot-Trading?branch=master)
@@ -1,4 +1,4 @@
1
- # OctoBot-Trading [2.4.167](https://github.com/Drakkar-Software/OctoBot-Trading/blob/master/CHANGELOG.md)
1
+ # OctoBot-Trading [2.4.169](https://github.com/Drakkar-Software/OctoBot-Trading/blob/master/CHANGELOG.md)
2
2
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/903b6b22bceb4661b608a86fea655f69)](https://app.codacy.com/gh/Drakkar-Software/OctoBot-Trading?utm_source=github.com&utm_medium=referral&utm_content=Drakkar-Software/OctoBot-Trading&utm_campaign=Badge_Grade_Dashboard)
3
3
  [![PyPI](https://img.shields.io/pypi/v/OctoBot-Trading.svg)](https://pypi.python.org/pypi/OctoBot-Trading/)
4
4
  [![Coverage Status](https://coveralls.io/repos/github/Drakkar-Software/OctoBot-Trading/badge.svg?branch=master)](https://coveralls.io/github/Drakkar-Software/OctoBot-Trading?branch=master)
@@ -15,4 +15,4 @@
15
15
  # License along with this library.
16
16
 
17
17
  PROJECT_NAME = "OctoBot-Trading"
18
- VERSION = "2.4.167" # major.minor.revision
18
+ VERSION = "2.4.169" # major.minor.revision
@@ -196,6 +196,7 @@ from octobot_trading.api.orders import (
196
196
  get_order_profitability,
197
197
  get_minimal_order_cost,
198
198
  get_order_trailing_profile_dict,
199
+ get_orders_locked_amounts_by_asset,
199
200
  create_order,
200
201
  cancel_all_open_orders,
201
202
  cancel_all_open_orders_with_currency,
@@ -385,6 +386,7 @@ __all__ = [
385
386
  "get_order_profitability",
386
387
  "get_minimal_order_cost",
387
388
  "get_order_trailing_profile_dict",
389
+ "get_orders_locked_amounts_by_asset",
388
390
  "create_order",
389
391
  "cancel_all_open_orders",
390
392
  "cancel_all_open_orders_with_currency",
@@ -13,6 +13,8 @@
13
13
  #
14
14
  # You should have received a copy of the GNU Lesser General Public
15
15
  # License along with this library.
16
+ import decimal
17
+
16
18
  import octobot_commons.logging as logging
17
19
 
18
20
  import octobot_trading.personal_data as personal_data
@@ -100,3 +102,7 @@ def get_minimal_order_cost(exchange_manager, symbol, default_price=None) -> floa
100
102
 
101
103
  def get_order_trailing_profile_dict(order: personal_data.Order) -> dict:
102
104
  return storage.get_order_trailing_profile_dict(order)
105
+
106
+
107
+ def get_orders_locked_amounts_by_asset(open_orders: list[personal_data.Order]) -> dict[str, decimal.Decimal]:
108
+ return personal_data.get_orders_locked_amounts_by_asset(open_orders)
@@ -399,7 +399,7 @@ def update_raw_order_from_raw_trade(order_to_update, raw_trade):
399
399
  enums.ExchangeConstantsOrderColumns.PRICE.value)
400
400
  order_to_update[enums.ExchangeConstantsOrderColumns.TIMESTAMP.value] = order_to_update.get(
401
401
  enums.ExchangeConstantsOrderColumns.TIMESTAMP.value,
402
- raw_trade[enums.ExchangeConstantsOrderColumns.TIMESTAMP.value])
402
+ raw_trade.get(enums.ExchangeConstantsOrderColumns.TIMESTAMP.value))
403
403
  order_to_update[enums.ExchangeConstantsOrderColumns.STATUS.value] = enums.OrderStatus.FILLED.value
404
404
  order_to_update[enums.ExchangeConstantsOrderColumns.FILLED.value] = raw_trade.get(
405
405
  enums.ExchangeConstantsOrderColumns.AMOUNT.value)
@@ -409,6 +409,12 @@ def update_raw_order_from_raw_trade(order_to_update, raw_trade):
409
409
  order_to_update[
410
410
  enums.ExchangeConstantsOrderColumns.FEE.value
411
411
  ] = raw_trade.get(enums.ExchangeConstantsOrderColumns.FEE.value)
412
+ order_to_update[
413
+ enums.ExchangeConstantsOrderColumns.TAG.value
414
+ ] = raw_trade.get(enums.ExchangeConstantsOrderColumns.TAG.value)
415
+ order_to_update[
416
+ enums.ExchangeConstantsOrderColumns.REDUCE_ONLY.value
417
+ ] = raw_trade.get(enums.ExchangeConstantsOrderColumns.REDUCE_ONLY.value, False)
412
418
  return order_to_update
413
419
 
414
420
 
@@ -34,6 +34,8 @@ from octobot_trading.personal_data.orders import (
34
34
  total_fees_from_order_dict,
35
35
  get_locked_funds,
36
36
  get_fees_for_currency,
37
+ get_order_locked_amount,
38
+ get_orders_locked_amounts_by_asset,
37
39
  parse_raw_fees,
38
40
  parse_order_status,
39
41
  parse_is_cancelled,
@@ -270,6 +272,8 @@ __all__ = [
270
272
  "total_fees_from_order_dict",
271
273
  "get_locked_funds",
272
274
  "get_fees_for_currency",
275
+ "get_order_locked_amount",
276
+ "get_orders_locked_amounts_by_asset",
273
277
  "parse_raw_fees",
274
278
  "parse_order_status",
275
279
  "parse_is_cancelled",
@@ -94,6 +94,8 @@ from octobot_trading.personal_data.orders.order_util import (
94
94
  get_locked_funds,
95
95
  total_fees_from_order_dict,
96
96
  get_fees_for_currency,
97
+ get_order_locked_amount,
98
+ get_orders_locked_amounts_by_asset,
97
99
  parse_raw_fees,
98
100
  parse_order_status,
99
101
  parse_is_cancelled,
@@ -170,6 +172,8 @@ __all__ = [
170
172
  "get_locked_funds",
171
173
  "total_fees_from_order_dict",
172
174
  "get_fees_for_currency",
175
+ "get_order_locked_amount",
176
+ "get_orders_locked_amounts_by_asset",
173
177
  "parse_raw_fees",
174
178
  "parse_order_status",
175
179
  "parse_is_cancelled",
@@ -29,6 +29,7 @@ import octobot_trading.errors as errors
29
29
  import octobot_trading.personal_data.orders.decimal_order_adapter as decimal_order_adapter
30
30
  import octobot_trading.exchanges.util.exchange_market_status_fixer as exchange_market_status_fixer
31
31
  import octobot_trading.personal_data.orders.states.fill_order_state as fill_order_state
32
+ import octobot_trading.personal_data.orders.order as order_import
32
33
  from octobot_trading.enums import ExchangeConstantsMarketStatusColumns as Ecmsc
33
34
 
34
35
 
@@ -376,6 +377,42 @@ def get_fees_for_currency(fee, currency):
376
377
  return constants.ZERO
377
378
 
378
379
 
380
+ def get_order_locked_amount(order: order_import.Order) -> decimal.Decimal:
381
+ # take fees into account when in locked asset
382
+ # ( a BTC/USDT order with USDT fees need to lock USDT fees to be able to pay them)
383
+ forecasted_fees = order.get_computed_fee(use_origin_quantity_and_price=not order.is_filled())
384
+ base, quote = symbol_util.parse_symbol(order.symbol).base_and_quote()
385
+ # when buy order
386
+ if order.side == enums.TradeOrderSide.BUY:
387
+ return order.origin_quantity * order.origin_price + get_fees_for_currency(forecasted_fees, quote)
388
+ # when sell order
389
+ return order.origin_quantity + get_fees_for_currency(forecasted_fees, base)
390
+
391
+
392
+ def get_orders_locked_amounts_by_asset(open_orders: list[order_import.Order]) -> dict[str, decimal.Decimal]:
393
+ if not open_orders:
394
+ return {}
395
+ locked_funds_by_asset = {}
396
+ for order in open_orders:
397
+ base, quote = symbol_util.parse_symbol(order.symbol).base_and_quote()
398
+ # use get_order_locked_amount just like trader simulator to ensure locked funds integrity
399
+ if order.side == enums.TradeOrderSide.BUY:
400
+ # buy orders only lock fees in quote
401
+ locked_quote = get_order_locked_amount(order)
402
+ if quote not in locked_funds_by_asset:
403
+ locked_funds_by_asset[quote] = locked_quote
404
+ else:
405
+ locked_funds_by_asset[quote] += locked_quote
406
+ else:
407
+ # sell orders only lock fees in base
408
+ locked_base = get_order_locked_amount(order)
409
+ if base not in locked_funds_by_asset:
410
+ locked_funds_by_asset[base] = locked_base
411
+ else:
412
+ locked_funds_by_asset[base] += locked_base
413
+ return locked_funds_by_asset
414
+
415
+
379
416
  def parse_raw_fees(raw_fees):
380
417
  fees = raw_fees
381
418
  if fees:
@@ -20,6 +20,7 @@ import typing
20
20
  import octobot_trading.personal_data.portfolios.asset as asset
21
21
  import octobot_trading.personal_data.portfolios.assets
22
22
  import octobot_trading.personal_data.orders.order as order_import
23
+ import octobot_trading.personal_data.orders.order_util as order_util
23
24
  import octobot_trading.personal_data.portfolios.sub_portfolio_data as sub_portfolio_data
24
25
  import octobot_trading.constants as constants
25
26
  import octobot_trading.enums as enums
@@ -281,11 +282,12 @@ def _resolve_sub_portfolio(
281
282
  resolved_content = {}
282
283
  funds_deltas = {}
283
284
  missing_funds = {}
284
- forecasted_sub_portfolio_content = sub_portfolio.get_content_after_deltas()
285
285
  missing_amount_by_asset = {}
286
+ forecasted_sub_portfolio_content = sub_portfolio.get_content_after_deltas()
286
287
  for asset_name, holdings in forecasted_sub_portfolio_content.items():
287
288
  missing_amount_in_asset = _resolve_sub_portfolio_asset(
288
- asset_name, holdings, remaining_master_portfolio, resolved_content, forbidden_filling_assets
289
+ asset_name, holdings, remaining_master_portfolio, resolved_content,
290
+ sub_portfolio.locked_funds_by_asset.get(asset_name, constants.ZERO), forbidden_filling_assets
289
291
  )
290
292
  if missing_amount_in_asset > constants.ZERO:
291
293
  missing_amount_by_asset[asset_name] = missing_amount_in_asset
@@ -309,47 +311,80 @@ def _resolve_sub_portfolio(
309
311
 
310
312
 
311
313
  def _resolve_sub_portfolio_asset(
312
- asset_name, holdings, remaining_master_portfolio, resolved_content, forbidden_filling_assets
314
+ asset_name: str,
315
+ holdings: dict[str, decimal.Decimal],
316
+ remaining_master_portfolio: sub_portfolio_data.SubPortfolioData,
317
+ resolved_content: dict[str, dict[str, decimal.Decimal]],
318
+ locked_funds: decimal.Decimal,
319
+ forbidden_filling_assets: list[str]
313
320
  ) -> decimal.Decimal:
314
- required_amount = holdings[commons_constants.PORTFOLIO_TOTAL]
321
+ required_total_amount = holdings[commons_constants.PORTFOLIO_TOTAL]
322
+ required_available_amount = holdings[commons_constants.PORTFOLIO_TOTAL] - locked_funds
315
323
  missing_amount_in_asset = constants.ZERO
316
324
  if asset_name in remaining_master_portfolio.content and asset_name not in forbidden_filling_assets:
317
325
  remaining_master_holding = remaining_master_portfolio.content[asset_name]
318
- # for now only handle available value (ignore funds in orders)
326
+ # available = total - locked_funds
327
+ remaining_total = remaining_master_holding[commons_constants.PORTFOLIO_TOTAL]
319
328
  remaining_available = remaining_master_holding[commons_constants.PORTFOLIO_AVAILABLE]
320
- if remaining_available >= required_amount * (constants.ONE - constants.SUB_PORTFOLIO_ALLOWED_MISSING_RATIO):
321
- sub_portfolio_amount = min(remaining_available, required_amount)
329
+ allowed_missing_ratio_multiplier = constants.ONE - constants.SUB_PORTFOLIO_ALLOWED_MISSING_RATIO
330
+ if remaining_total < locked_funds * allowed_missing_ratio_multiplier:
331
+ # should never happen, log it in case it does
332
+ commons_logging.get_logger(__name__).error(
333
+ f"Unexpected missing locked {asset_name} funds in total portfolio {remaining_total=} {locked_funds=}"
334
+ )
335
+ # As orders are still open, their funds must be locked. Therefore, only consider available funds
336
+ if remaining_available >= required_available_amount * allowed_missing_ratio_multiplier:
337
+ if remaining_total < required_total_amount * allowed_missing_ratio_multiplier:
338
+ # should never happen, log it in case it does
339
+ commons_logging.get_logger(__name__).error(
340
+ f"Unexpected missing total {asset_name} value in portfolio: ensure order funds really locked"
341
+ )
342
+ sub_portfolio_total_amount = min(remaining_total, required_total_amount)
343
+ # Do not use remaining_available or remaining_available here to avoid side effects due to locked fees
344
+ # on some exchanges and not on others. Only compute from total holdings.
345
+ # ex: coinbase locks 101 USDC to buy for 100 USDC + 1 USDC fee,
346
+ # binance will just lock 100 and given less of the bought asset
347
+ sub_portfolio_available_amount = sub_portfolio_total_amount - locked_funds
322
348
  # assets are available in master portfolio: reduce it from master
323
349
  if asset_name in resolved_content:
324
- resolved_content[asset_name][commons_constants.PORTFOLIO_TOTAL] += sub_portfolio_amount
325
- resolved_content[asset_name][commons_constants.PORTFOLIO_AVAILABLE] += sub_portfolio_amount
350
+ resolved_content[asset_name][commons_constants.PORTFOLIO_TOTAL] += sub_portfolio_total_amount
351
+ resolved_content[asset_name][commons_constants.PORTFOLIO_AVAILABLE] += sub_portfolio_available_amount
326
352
  else:
327
353
  resolved_content[asset_name] = {
328
- commons_constants.PORTFOLIO_TOTAL: sub_portfolio_amount,
329
- commons_constants.PORTFOLIO_AVAILABLE: sub_portfolio_amount,
354
+ commons_constants.PORTFOLIO_TOTAL: sub_portfolio_total_amount,
355
+ commons_constants.PORTFOLIO_AVAILABLE: sub_portfolio_available_amount,
330
356
  }
331
- remaining_master_portfolio.content[asset_name][commons_constants.PORTFOLIO_TOTAL] -= sub_portfolio_amount
332
- remaining_master_portfolio.content[asset_name][commons_constants.PORTFOLIO_AVAILABLE] -= sub_portfolio_amount
357
+ remaining_master_portfolio.content[asset_name][commons_constants.PORTFOLIO_TOTAL] -= sub_portfolio_total_amount
358
+ # don't make remaining available negative
359
+ removed_portfolio_available_amount = min(remaining_available, sub_portfolio_available_amount)
360
+ remaining_master_portfolio.content[asset_name][commons_constants.PORTFOLIO_AVAILABLE] -= removed_portfolio_available_amount
333
361
  else:
334
- # not enough assets in master portfolio
362
+ # As orders are still open, their funds must be locked. Therefore, only consider available funds
363
+ # Not enough assets in master portfolio
364
+ usable_total = min(remaining_total, remaining_available + locked_funds)
335
365
  if asset_name in resolved_content:
336
- resolved_content[asset_name][commons_constants.PORTFOLIO_TOTAL] += remaining_available
366
+ resolved_content[asset_name][commons_constants.PORTFOLIO_TOTAL] += usable_total
337
367
  resolved_content[asset_name][commons_constants.PORTFOLIO_AVAILABLE] += remaining_available
338
368
  else:
339
369
  resolved_content[asset_name] = {
340
- commons_constants.PORTFOLIO_TOTAL: remaining_available,
370
+ commons_constants.PORTFOLIO_TOTAL: usable_total,
341
371
  commons_constants.PORTFOLIO_AVAILABLE: remaining_available,
342
372
  }
343
- missing_amount_in_asset = abs(remaining_available - required_amount)
344
- remaining_master_portfolio.content[asset_name][commons_constants.PORTFOLIO_TOTAL] -= remaining_available
373
+ missing_amount_in_asset = abs(remaining_available - required_available_amount)
374
+ remaining_master_portfolio.content[asset_name][commons_constants.PORTFOLIO_TOTAL] -= usable_total
345
375
  remaining_master_portfolio.content[asset_name][commons_constants.PORTFOLIO_AVAILABLE] -= remaining_available
346
376
  else:
377
+ if locked_funds > constants.ZERO:
378
+ # should never happen, log it in case it does
379
+ commons_logging.get_logger(__name__).error(
380
+ f"Unexpected missing {asset_name} value in portfolio but {locked_funds=}"
381
+ )
347
382
  resolved_content[asset_name] = {
348
383
  commons_constants.PORTFOLIO_TOTAL: constants.ZERO,
349
384
  commons_constants.PORTFOLIO_AVAILABLE: constants.ZERO,
350
385
  }
351
386
  # asset not in master portfolio (anymore):
352
- missing_amount_in_asset = required_amount
387
+ missing_amount_in_asset = required_available_amount
353
388
  return missing_amount_in_asset
354
389
 
355
390
 
@@ -392,7 +427,8 @@ def _fill_missing_assets_from_allowed_filling_assets(
392
427
  if filling_asset in funds_deltas:
393
428
  funds_deltas[filling_asset][commons_constants.PORTFOLIO_TOTAL] += funds_to_add_in_filling_asset
394
429
  funds_deltas[filling_asset][commons_constants.PORTFOLIO_AVAILABLE] += funds_to_add_in_filling_asset
395
- else:
430
+ elif funds_to_add_in_filling_asset != constants.ZERO:
431
+ # only add delta when delta is not 0
396
432
  funds_deltas[filling_asset] = {
397
433
  commons_constants.PORTFOLIO_TOTAL: funds_to_add_in_filling_asset,
398
434
  commons_constants.PORTFOLIO_AVAILABLE: funds_to_add_in_filling_asset
@@ -438,7 +474,7 @@ def get_portfolio_filled_orders_deltas(
438
474
  updated_portfolio_content: dict[str, dict[str, decimal.Decimal]],
439
475
  filled_orders: list[order_import.Order]
440
476
  ) -> (dict[str, dict[str, decimal.Decimal]], dict[str, dict[str, decimal.Decimal]]):
441
- orders_asset_deltas = _get_assets_delta_from_orders(filled_orders)
477
+ orders_asset_deltas, possible_fees_asset_deltas = _get_assets_delta_from_orders(filled_orders)
442
478
  portfolios_asset_deltas = _get_assets_delta_from_portfolio(previous_portfolio_content, updated_portfolio_content)
443
479
  # return portfolio asset deltas that can approximately be explained by given orders
444
480
  orders_linked_deltas = {}
@@ -467,13 +503,26 @@ def get_portfolio_filled_orders_deltas(
467
503
  # similar delta (+/- fees)
468
504
  # this delta is due to these orders: add it
469
505
  orders_linked_deltas[asset_name] = holdings_delta
506
+ elif (
507
+ # try while taking possible fees into account
508
+ # approx same value
509
+ asset_name in possible_fees_asset_deltas and (
510
+ abs(min_allowed_equivalent_total_holding)
511
+ < abs(order_asset_delta + possible_fees_asset_deltas[asset_name])
512
+ < abs(max_allowed_equivalent_total_holding)
513
+ )
514
+ ):
515
+ # similar delta considering fees
516
+ # this delta is due to these orders: add it
517
+ orders_linked_deltas[asset_name] = holdings_delta
470
518
  elif abs(order_asset_delta) > abs(max_allowed_equivalent_total_holding):
471
- # too little in portfolio delta to be from those orders: add it to ignored_deltas: there should be
472
- # something in delta but there is not, this is unexpected
519
+ # too little in portfolio delta to be from those orders
520
+ # As potential fees have already been taken into account, THIS IS UNEXPECTED.
521
+ # Add it to ignored_deltas
473
522
  ignored_deltas[asset_name] = holdings_delta
474
523
  elif abs(min_allowed_equivalent_total_holding) > abs(order_asset_delta):
475
524
  # too much in portfolio delta: only take what is linked to the orders deltas
476
- # todo: handle available assets when taking open orders into account (now set both available and total)
525
+ # => updates both total and available
477
526
  orders_linked_deltas[asset_name] = {
478
527
  key: order_asset_delta
479
528
  for key in holdings_delta
@@ -511,10 +560,14 @@ def _get_assets_delta_from_portfolio(
511
560
 
512
561
 
513
562
 
514
- def _get_assets_delta_from_orders(orders: list[order_import.Order]) -> dict[str, decimal.Decimal]:
563
+ def _get_assets_delta_from_orders(orders: list[order_import.Order]) -> (
564
+ dict[str, decimal.Decimal], dict[str, decimal.Decimal]
565
+ ):
515
566
  asset_deltas = {}
567
+ possible_fee_related_deltas = {}
516
568
  for order in orders:
517
569
  base, quote = symbol_util.parse_symbol(order.symbol).base_and_quote()
570
+ # order "expected" related deltas
518
571
  added_unit_and_amount = (
519
572
  (base, order.origin_quantity)
520
573
  if order.side is enums.TradeOrderSide.BUY else (quote, order.total_cost)
@@ -531,4 +584,12 @@ def _get_assets_delta_from_orders(orders: list[order_import.Order]) -> dict[str,
531
584
  asset_deltas[unit_and_amount[0]] = unit_and_amount[1] * multiplier
532
585
  else:
533
586
  asset_deltas[unit_and_amount[0]] += unit_and_amount[1] * multiplier
534
- return asset_deltas
587
+ # order "probable" related deltas (account for worse case fees)
588
+ forecasted_fees = order.get_computed_fee(use_origin_quantity_and_price=True)
589
+ for fee_asset in (base, quote):
590
+ if asset_amount := order_util.get_fees_for_currency(forecasted_fees, fee_asset):
591
+ if fee_asset not in possible_fee_related_deltas:
592
+ possible_fee_related_deltas[fee_asset] = -asset_amount
593
+ else:
594
+ possible_fee_related_deltas[fee_asset] += -asset_amount
595
+ return asset_deltas, possible_fee_related_deltas
@@ -18,8 +18,10 @@ import dataclasses
18
18
  import decimal
19
19
  import typing
20
20
 
21
+ import octobot_commons.logging as commons_logging
21
22
  import octobot_commons.constants as commons_constants
22
23
  import octobot_trading.personal_data as personal_data
24
+ import octobot_trading.constants as constants
23
25
 
24
26
 
25
27
  @dataclasses.dataclass
@@ -31,10 +33,17 @@ class SubPortfolioData:
31
33
  unit: typing.Optional[str]
32
34
  # deltas to be applied on top of the current content of the sub-portfolio from get_content_after_deltas()
33
35
  funds_deltas: dict[str, dict[str, decimal.Decimal]] = dataclasses.field(default_factory=dict)
36
+ # funds that are missing from this portfolio. Populated after portfolio has been resolved
34
37
  missing_funds: dict[str, decimal.Decimal] = dataclasses.field(default_factory=dict)
35
38
 
39
+ # funds that are locked (maybe in orders) from this portfolio
40
+ locked_funds_by_asset: dict[str, decimal.Decimal] = dataclasses.field(default_factory=dict)
41
+
36
42
 
37
43
  def get_content_after_deltas(self) -> dict[str, dict[str, decimal.Decimal]]:
44
+ """
45
+ Computes the updated portfolio from delta available and total
46
+ """
38
47
  updated_content = copy.deepcopy(self.content)
39
48
  for asset, delta_values in self.funds_deltas.items():
40
49
  if asset in updated_content:
@@ -51,6 +60,29 @@ class SubPortfolioData:
51
60
  }
52
61
  return updated_content
53
62
 
63
+ def get_content_from_total_deltas_and_locked_funds(self) -> dict[str, dict[str, decimal.Decimal]]:
64
+ """
65
+ Only uses PORTFOLIO_TOTAL deltas and computes available values from locked_funds_by_asset
66
+ """
67
+ updated_content = copy.deepcopy(self.content)
68
+ for asset, delta_values in self.funds_deltas.items():
69
+ if asset in updated_content:
70
+ updated_content[asset][commons_constants.PORTFOLIO_TOTAL] += (
71
+ delta_values[commons_constants.PORTFOLIO_TOTAL]
72
+ )
73
+ else:
74
+ updated_content[asset] = {
75
+ commons_constants.PORTFOLIO_TOTAL: delta_values[commons_constants.PORTFOLIO_TOTAL]
76
+ }
77
+ for asset, values in updated_content.items():
78
+ locked_funds = self.locked_funds_by_asset.get(asset, constants.ZERO)
79
+ if locked_funds > values[commons_constants.PORTFOLIO_TOTAL]:
80
+ commons_logging.get_logger(__name__).error(
81
+ f"Unexpected: negative {asset} available value after applying {locked_funds} locked funds to {values}"
82
+ )
83
+ values[commons_constants.PORTFOLIO_AVAILABLE] = values[commons_constants.PORTFOLIO_TOTAL] - locked_funds
84
+ return updated_content
85
+
54
86
  def is_similar_to(self, other) -> bool:
55
87
  return (
56
88
  other
@@ -71,22 +71,16 @@ class SpotPortfolio(portfolio_class.Portfolio):
71
71
  """
72
72
  multiplier = constants.ONE if is_new_order else -constants.ONE
73
73
 
74
- # take fees into account when in locked asset
75
- # ( a BTC/USDT order with USDT fees need to lock USDT fees to be able to pay them)
76
- forecasted_fees = order.get_computed_fee(use_origin_quantity_and_price=not order.is_filled())
77
- base_fees = order_util.get_fees_for_currency(forecasted_fees, order.currency)
78
- quote_fees = order_util.get_fees_for_currency(forecasted_fees, order.market)
79
-
80
74
  # when buy order
81
75
  if order.side == enums.TradeOrderSide.BUY:
82
- new_quantity = - (order.origin_quantity * order.origin_price + quote_fees) * multiplier
76
+ new_quantity = - order_util.get_order_locked_amount(order) * multiplier
83
77
  self._update_portfolio_data(order.market,
84
78
  available_value=new_quantity,
85
79
  total_value=constants.ZERO)
86
80
 
87
81
  # when sell order
88
82
  else:
89
- new_quantity = - (order.origin_quantity + base_fees) * multiplier
83
+ new_quantity = - order_util.get_order_locked_amount(order) * multiplier
90
84
  self._update_portfolio_data(order.currency,
91
85
  available_value=new_quantity,
92
86
  total_value=constants.ZERO)
@@ -19,7 +19,7 @@ import mock
19
19
  import trading_backend.exchanges
20
20
  import octobot_commons.constants as commons_constants
21
21
  import octobot_commons.configuration as commons_configuration
22
- import octobot_trading.constants as constants
22
+ import octobot_trading.enums as enums
23
23
  import octobot_trading.exchanges as exchanges
24
24
  import octobot_trading.exchanges.util.exchange_util as exchange_util
25
25
 
@@ -251,3 +251,44 @@ def test_is_error_on_this_type():
251
251
  assert exchange_util.is_error_on_this_type(Exception("api key doesn't exist"), errors) is True
252
252
  assert exchange_util.is_error_on_this_type(Exception("api"), errors) is False
253
253
  assert exchange_util.is_error_on_this_type(Exception("api"), errors) is False
254
+
255
+
256
+ def test_update_raw_order_from_raw_trade():
257
+ required_keys = [
258
+ enums.ExchangeConstantsOrderColumns.INFO,
259
+ enums.ExchangeConstantsOrderColumns.EXCHANGE_ID,
260
+ enums.ExchangeConstantsOrderColumns.SYMBOL,
261
+ enums.ExchangeConstantsOrderColumns.TYPE,
262
+ enums.ExchangeConstantsOrderColumns.AMOUNT,
263
+ enums.ExchangeConstantsOrderColumns.DATETIME,
264
+ enums.ExchangeConstantsOrderColumns.SIDE,
265
+ enums.ExchangeConstantsOrderColumns.TAKER_OR_MAKER,
266
+ enums.ExchangeConstantsOrderColumns.PRICE,
267
+ enums.ExchangeConstantsOrderColumns.TIMESTAMP,
268
+ enums.ExchangeConstantsOrderColumns.STATUS,
269
+ enums.ExchangeConstantsOrderColumns.FILLED,
270
+ enums.ExchangeConstantsOrderColumns.COST,
271
+ enums.ExchangeConstantsOrderColumns.REMAINING,
272
+ enums.ExchangeConstantsOrderColumns.FEE,
273
+ enums.ExchangeConstantsOrderColumns.TAG,
274
+ enums.ExchangeConstantsOrderColumns.REDUCE_ONLY,
275
+ ]
276
+ default_value = exchange_util.update_raw_order_from_raw_trade({}, {})
277
+ assert all(key.value in default_value for key in required_keys)
278
+ with_trade_values = exchange_util.update_raw_order_from_raw_trade(
279
+ {}, {**{k.value: k.name for k in required_keys}, **{
280
+ enums.ExchangeConstantsOrderColumns.ORDER.value: "EXCHANGE_ID",
281
+ enums.ExchangeConstantsOrderColumns.AMOUNT.value: "AMOUNT",
282
+ }}
283
+ )
284
+ for key in required_keys:
285
+ if key == enums.ExchangeConstantsOrderColumns.STATUS:
286
+ assert with_trade_values[key.value] == enums.OrderStatus.FILLED.value
287
+ elif key == enums.ExchangeConstantsOrderColumns.REMAINING:
288
+ assert with_trade_values[key.value] == 0
289
+ elif key == enums.ExchangeConstantsOrderColumns.FILLED:
290
+ assert with_trade_values[key.value] == "AMOUNT"
291
+ elif key == enums.ExchangeConstantsOrderColumns.EXCHANGE_ID:
292
+ assert with_trade_values[key.value] == "EXCHANGE_ID"
293
+ else:
294
+ assert with_trade_values[key.value] == key.name