pfund 0.0.1.dev11__tar.gz → 0.0.1.dev12__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 (187) hide show
  1. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/PKG-INFO +1 -1
  2. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/analyzer.py +10 -5
  3. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/brokers/ib/broker_ib.py +4 -2
  4. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/const/commons.py +3 -1
  5. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/engines/backtest_engine.py +37 -11
  6. pfund-0.0.1.dev12/pfund/git_controller.py +60 -0
  7. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/models/model_base.py +39 -1
  8. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/strategies/strategy_base.py +39 -1
  9. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/templates/notebooks/pfund-overview.ipynb +17 -11
  10. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/types/common_literals.py +3 -1
  11. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/utils/utils.py +12 -3
  12. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pyproject.toml +8 -7
  13. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/LICENSE +0 -0
  14. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/README.md +0 -0
  15. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/CONTRIBUTING.md +0 -0
  16. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/__init__.py +0 -0
  17. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/accounts/__init__.py +0 -0
  18. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/accounts/account_base.py +0 -0
  19. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/accounts/account_crypto.py +0 -0
  20. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/accounts/account_ib.py +0 -0
  21. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/adapter.py +0 -0
  22. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/balances/__init__.py +0 -0
  23. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/balances/balance_base.py +0 -0
  24. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/balances/balance_crypto.py +0 -0
  25. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/balances/balance_ib.py +0 -0
  26. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/brokers/__init__.py +0 -0
  27. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/brokers/broker_backtest.py +0 -0
  28. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/brokers/broker_base.py +0 -0
  29. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/brokers/broker_crypto.py +0 -0
  30. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/brokers/broker_live.py +0 -0
  31. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/brokers/ib/__init__.py +0 -0
  32. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/brokers/ib/ib_api.py +0 -0
  33. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/brokers/ib/ib_client.py +0 -0
  34. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/brokers/ib/ib_wrapper.py +0 -0
  35. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/cli/__init__.py +0 -0
  36. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/cli/commands/__init__.py +0 -0
  37. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/cli/commands/config.py +0 -0
  38. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/cli/commands/docker_compose.py +0 -0
  39. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/cli/main.py +0 -0
  40. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/binance/linear/config.yml +0 -0
  41. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/binance/linear/lot_sizes_linear.yml +0 -0
  42. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/binance/linear/pdt_matchings_linear.yml +0 -0
  43. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/binance/linear/tick_sizes_linear.yml +0 -0
  44. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/bybit/config.yml +0 -0
  45. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/bybit/lot_sizes_inverse.yml +0 -0
  46. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/bybit/lot_sizes_linear.yml +0 -0
  47. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/bybit/lot_sizes_option.yml +0 -0
  48. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/bybit/lot_sizes_spot.yml +0 -0
  49. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/bybit/pdt_matchings_inverse.yml +0 -0
  50. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/bybit/pdt_matchings_linear.yml +0 -0
  51. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/bybit/pdt_matchings_option.yml +0 -0
  52. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/bybit/pdt_matchings_spot.yml +0 -0
  53. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/bybit/tick_sizes_inverse.yml +0 -0
  54. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/bybit/tick_sizes_linear.yml +0 -0
  55. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/bybit/tick_sizes_option.yml +0 -0
  56. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/bybit/tick_sizes_spot.yml +0 -0
  57. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/configuration.py +0 -0
  58. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/ib/config.yml +0 -0
  59. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config/logging.yml +0 -0
  60. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/config_handler.py +0 -0
  61. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/const/__init__.py +0 -0
  62. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/const/_zmq_routes.py +0 -0
  63. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/const/paths.py +0 -0
  64. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/data_tools/data_tool_base.py +0 -0
  65. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/data_tools/data_tool_pandas.py +0 -0
  66. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/datas/__init__.py +0 -0
  67. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/datas/data_bar.py +0 -0
  68. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/datas/data_base.py +0 -0
  69. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/datas/data_quote.py +0 -0
  70. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/datas/data_tick.py +0 -0
  71. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/datas/data_time_based.py +0 -0
  72. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/datas/resolution.py +0 -0
  73. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/datas/timeframe.py +0 -0
  74. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/engines/__init__.py +0 -0
  75. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/engines/base_engine.py +0 -0
  76. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/engines/test_engine.py +0 -0
  77. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/engines/trade_engine.py +0 -0
  78. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/engines/train_engine.py +0 -0
  79. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/errors.py +0 -0
  80. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/__init__.py +0 -0
  81. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/binance/__init__.py +0 -0
  82. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/binance/exchange.py +0 -0
  83. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/binance/linear/exchange.py +0 -0
  84. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/binance/rest_api.py +0 -0
  85. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/binance/ws_api.py +0 -0
  86. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/bybit/__init__.py +0 -0
  87. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/bybit/exchange.py +0 -0
  88. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/bybit/rest_api.py +0 -0
  89. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/bybit/rest_api_samples/get_markets_result_inverse +0 -0
  90. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/bybit/rest_api_samples/get_markets_result_linear +0 -0
  91. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/bybit/rest_api_samples/get_markets_result_option +0 -0
  92. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/bybit/rest_api_samples/get_markets_result_spot +0 -0
  93. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/bybit/rest_api_samples/get_markets_return_inverse +0 -0
  94. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/bybit/rest_api_samples/get_markets_return_linear +0 -0
  95. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/bybit/rest_api_samples/get_markets_return_option +0 -0
  96. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/bybit/rest_api_samples/get_markets_return_spot +0 -0
  97. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/bybit/ws_api.py +0 -0
  98. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/exchange_base.py +0 -0
  99. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/rest_api_base.py +0 -0
  100. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/exchanges/ws_api_base.py +0 -0
  101. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/__init__.py +0 -0
  102. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/account_summary_tags.py +0 -0
  103. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/client.py +0 -0
  104. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/comm.py +0 -0
  105. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/commission_report.py +0 -0
  106. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/common.py +0 -0
  107. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/connection.py +0 -0
  108. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/contract.py +0 -0
  109. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/decoder.py +0 -0
  110. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/enum_implem.py +0 -0
  111. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/errors.py +0 -0
  112. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/execution.py +0 -0
  113. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/ibapi.pyproj +0 -0
  114. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/message.py +0 -0
  115. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/news.py +0 -0
  116. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/object_implem.py +0 -0
  117. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/order.py +0 -0
  118. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/order_condition.py +0 -0
  119. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/order_state.py +0 -0
  120. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/orderdecoder.py +0 -0
  121. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/reader.py +0 -0
  122. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/scanner.py +0 -0
  123. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/server_versions.py +0 -0
  124. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/softdollartier.py +0 -0
  125. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/tag_value.py +0 -0
  126. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/ticktype.py +0 -0
  127. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/utils.py +0 -0
  128. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/externals/ibapi/wrapper.py +0 -0
  129. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/indicators/__init__.py +0 -0
  130. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/indicators/indicator_base.py +0 -0
  131. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/indicators/ta_indicator.py +0 -0
  132. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/indicators/talib_indicator.py +0 -0
  133. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/investment_profile.py +0 -0
  134. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/main.py +0 -0
  135. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/managers/__init__.py +0 -0
  136. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/managers/base_manager.py +0 -0
  137. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/managers/connection_manager.py +0 -0
  138. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/managers/data_manager.py +0 -0
  139. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/managers/order_manager.py +0 -0
  140. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/managers/portfolio_manager.py +0 -0
  141. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/managers/risk_manager.py +0 -0
  142. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/managers/strategy_manager.py +0 -0
  143. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/mixins/backtest.py +0 -0
  144. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/models/__init__.py +0 -0
  145. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/models/model_backtest.py +0 -0
  146. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/models/model_meta.py +0 -0
  147. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/models/pytorch_model.py +0 -0
  148. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/models/sklearn_model.py +0 -0
  149. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/orders/__init__.py +0 -0
  150. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/orders/order_base.py +0 -0
  151. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/orders/order_crypto.py +0 -0
  152. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/orders/order_ib.py +0 -0
  153. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/orders/order_statuses.py +0 -0
  154. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/orders/order_time_in_force.py +0 -0
  155. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/plogging/__init__.py +0 -0
  156. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/plogging/config.py +0 -0
  157. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/plogging/filters.py +0 -0
  158. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/plogging/formatter.py +0 -0
  159. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/plogging/handlers.py +0 -0
  160. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/portfolio.py +0 -0
  161. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/positions/__init__.py +0 -0
  162. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/positions/position_base.py +0 -0
  163. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/positions/position_crypto.py +0 -0
  164. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/positions/position_ib.py +0 -0
  165. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/products/__init__.py +0 -0
  166. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/products/product_base.py +0 -0
  167. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/products/product_crypto.py +0 -0
  168. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/products/product_ib.py +0 -0
  169. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/risk_monitor.py +0 -0
  170. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/strategies/__init__.py +0 -0
  171. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/strategies/allocation_strategy.py +0 -0
  172. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/strategies/diversification_strategy.py +0 -0
  173. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/strategies/hedging_strategy.py +0 -0
  174. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/strategies/optimization_strategy.py +0 -0
  175. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/strategies/portfolio_strategy.py +0 -0
  176. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/strategies/rebalancing_strategy.py +0 -0
  177. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/strategies/strategy_backtest.py +0 -0
  178. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/strategies/strategy_meta.py +0 -0
  179. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/templates/dashboards/pfund-overview.streamlit.py +0 -0
  180. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/templates/notebooks/pfund-analytics.ipynb +0 -0
  181. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/types/backtest.py +0 -0
  182. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/types/bybit.py +0 -0
  183. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/types/core.py +0 -0
  184. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/universe.py +0 -0
  185. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/utils/aliases.py +0 -0
  186. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/utils/envs.py +0 -0
  187. {pfund-0.0.1.dev11 → pfund-0.0.1.dev12}/pfund/zeromq.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pfund
3
- Version: 0.0.1.dev11
3
+ Version: 0.0.1.dev12
4
4
  Summary: A Complete Algo-Trading Framework for Machine Learning, enabling trading across TradFi, CeFi and DeFi. Supports Vectorized and Event-Driven Backtesting, Paper and Live Trading
5
5
  Home-page: https://pfund.ai
6
6
  License: Apache-2.0
@@ -1,7 +1,11 @@
1
+ from __future__ import annotations
2
+
1
3
  import os
2
4
  from pathlib import Path
3
5
 
4
- from typing import Literal
6
+ from typing import TYPE_CHECKING
7
+ if TYPE_CHECKING:
8
+ from pfund.types.common_literals import tSUPPORTED_CODE_EDITORS, tSUPPORTED_TEMPLATE_TYPES
5
9
 
6
10
  from pfund.utils import utils
7
11
  from pfund.config_handler import ConfigHandler
@@ -30,7 +34,7 @@ class Analyzer:
30
34
  return False
31
35
 
32
36
  @staticmethod
33
- def _derive_template_type(template: str) -> Literal['notebook', 'spreadsheet', 'dashboard']:
37
+ def _derive_template_type(template: str) -> tSUPPORTED_TEMPLATE_TYPES:
34
38
  if '.ipynb' in template:
35
39
  template_type = 'notebook'
36
40
  elif '.grid' in template:
@@ -56,7 +60,7 @@ class Analyzer:
56
60
  else:
57
61
  raise FileNotFoundError(f"Template {template} not found in pfund's templates or user's templates")
58
62
 
59
- def _get_editor_cmd(self, editor: Literal['vscode', 'pycharm']) -> str:
63
+ def _get_editor_cmd(self, editor: tSUPPORTED_CODE_EDITORS) -> str:
60
64
  if editor == 'vscode':
61
65
  cmd = 'code'
62
66
  if utils.is_command_available(cmd):
@@ -82,7 +86,7 @@ class Analyzer:
82
86
  show_results_only: bool=True,
83
87
  open_outputs: bool=False,
84
88
  outputs_path: str | None=None,
85
- editor: Literal['vscode', 'pycharm']='vscode'
89
+ editor: tSUPPORTED_CODE_EDITORS='vscode'
86
90
  ) -> None:
87
91
  '''
88
92
  Args:
@@ -183,7 +187,8 @@ class Analyzer:
183
187
  for process in voila_processes:
184
188
  process.terminate()
185
189
  process.wait()
186
-
190
+
191
+ # TODO:
187
192
  def run_spreadsheets(
188
193
  self,
189
194
  spreadsheets: list[str] | str
@@ -5,6 +5,7 @@ from collections import defaultdict
5
5
 
6
6
  from pfund.adapter import Adapter
7
7
  from pfund.config.configuration import Configuration
8
+ from pfund.const.paths import PROJ_CONFIG_PATH
8
9
  from pfund.const.commons import SUPPORTED_PRODUCT_TYPES
9
10
  from pfund.products import IBProduct
10
11
  from pfund.accounts import IBAccount
@@ -19,8 +20,9 @@ from pfund.brokers.ib.ib_api import IBApi
19
20
  class IBBroker(LiveBroker):
20
21
  def __init__(self, env, **configs):
21
22
  super().__init__(env, 'IB', **configs)
22
- self.configs = Configuration(self.bkr, 'config')
23
- self.adapter = Adapter(self.bkr, self.configs.load_config_section('adapter'))
23
+ config_path = f'{PROJ_CONFIG_PATH}/{self.bkr.lower()}'
24
+ self.configs = Configuration(config_path, 'config')
25
+ self.adapter = Adapter(config_path, self.configs.load_config_section('adapter'))
24
26
  self.account = None
25
27
 
26
28
  # API
@@ -20,4 +20,6 @@ SUPPORTED_TIMEFRAMES = [
20
20
  ]
21
21
  SUPPORTED_DATA_CHANNELS = ['orderbook', 'tradebook', 'kline']
22
22
  SUPPORTED_BACKTEST_MODES = ['vectorized', 'event_driven']
23
- SUPPORTED_DATA_TOOLS = ['pandas']
23
+ SUPPORTED_DATA_TOOLS = ['pandas']
24
+ SUPPORTED_CODE_EDITORS = ['vscode', 'pycharm']
25
+ SUPPORTED_TEMPLATE_TYPES = ['notebook', 'spreadsheet', 'dashboard']
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import hashlib
4
+ import inspect
4
5
  import os
5
6
  import time
6
7
  import datetime
@@ -13,6 +14,7 @@ if TYPE_CHECKING:
13
14
  from pfund.types.core import tStrategy, tModel, tFeature, tIndicator
14
15
 
15
16
  import pfund as pf
17
+ from pfund.git_controller import GitController
16
18
  from pfund.engines.base_engine import BaseEngine
17
19
  from pfund.brokers.broker_backtest import BacktestBroker
18
20
  from pfund.strategies.strategy_base import BaseStrategy
@@ -23,7 +25,7 @@ from pfund.mixins.backtest import BacktestMixin
23
25
 
24
26
 
25
27
  class BacktestEngine(BaseEngine):
26
- def __new__(cls, *, env: str='BACKTEST', data_tool: tSUPPORTED_DATA_TOOLS='pandas', mode: tSUPPORTED_BACKTEST_MODES='vectorized', append_to_strategy_df=False, use_prepared_signals=True, config: ConfigHandler | None=None, **settings):
28
+ def __new__(cls, *, env: str='BACKTEST', data_tool: tSUPPORTED_DATA_TOOLS='pandas', mode: tSUPPORTED_BACKTEST_MODES='vectorized', append_to_strategy_df=False, use_prepared_signals=True, config: ConfigHandler | None=None, auto_git_commit=False, **settings):
27
29
  if not hasattr(cls, 'mode'):
28
30
  cls.mode = mode.lower()
29
31
  if not hasattr(cls, 'append_to_strategy_df'):
@@ -32,13 +34,18 @@ class BacktestEngine(BaseEngine):
32
34
  # instead of recalculating the signals. This will make event-driven backtesting faster but less consistent with live trading
33
35
  if not hasattr(cls, 'use_prepared_signals'):
34
36
  cls.use_prepared_signals = use_prepared_signals
37
+ if not hasattr(cls, 'auto_git_commit'):
38
+ cls.auto_git_commit = auto_git_commit
35
39
  return super().__new__(cls, env, data_tool=data_tool, config=config, **settings)
36
40
 
37
- def __init__(self, *, env: str='BACKTEST', data_tool: tSUPPORTED_DATA_TOOLS='pandas', mode: tSUPPORTED_BACKTEST_MODES='vectorized', append_to_strategy_df=False, use_prepared_signals=True, config: ConfigHandler | None=None, **settings):
38
- super().__init__(env, data_tool=data_tool)
41
+ def __init__(self, *, env: str='BACKTEST', data_tool: tSUPPORTED_DATA_TOOLS='pandas', mode: tSUPPORTED_BACKTEST_MODES='vectorized', append_to_strategy_df=False, use_prepared_signals=True, config: ConfigHandler | None=None, auto_git_commit=False, **settings):
39
42
  # avoid re-initialization to implement singleton class correctly
40
- # if not hasattr(self, '_initialized'):
41
- # pass
43
+ if not hasattr(self, '_initialized'):
44
+ # Get the current frame and then the outer frame (where the engine instance is created)
45
+ caller_frame = inspect.currentframe().f_back
46
+ file_path = caller_frame.f_code.co_filename # Extract the file path from the frame
47
+ self._git = GitController(os.path.abspath(file_path))
48
+ super().__init__(env, data_tool=data_tool)
42
49
 
43
50
  # HACK: since python doesn't support dynamic typing, true return type should be subclass of BacktestMixin and tStrategy
44
51
  # write -> BacktestMixin | tStrategy for better intellisense in IDEs
@@ -131,23 +138,35 @@ class BacktestEngine(BaseEngine):
131
138
  except:
132
139
  self.logger.exception(f"Error writing to {file_path}:")
133
140
 
134
- def _generate_backtest_iteration(self, strategy: BaseStrategy) -> int:
141
+ def _generate_backtest_iteration(self, backtest_hash: str) -> int:
135
142
  '''Generate backtest iteration number for the same backtest_hash.
136
143
  Read the existing backtest.json file to get the iteration number for the same strategy hash
137
144
  If the backtest hash is not found, create a new entry with iteration number 1
138
145
  else increment the iteration number by 1.
139
146
  '''
140
- backtest_hash = self._generate_backtest_hash(strategy)
141
147
  file_name = 'backtest.json'
142
148
  backtest_json = self.read_json(file_name)
143
149
  backtest_json[backtest_hash] = backtest_json.get(backtest_hash, 0) + 1
144
150
  self._write_json(file_name, backtest_json)
145
151
  return backtest_json[backtest_hash]
146
152
 
147
- def _output_backtest_results(self, strat: str, df, start_time: float, end_time: float):
153
+ def _commit_strategy(self, strategy: BaseStrategy) -> str | None:
154
+ engine_name = self.__class__.__name__
155
+ strat = strategy.name
156
+ commit_hash: str | None = self._git.commit(strategy._file_path, f'[PFund] {engine_name}: auto-commit strategy "{strat}"')
157
+ if commit_hash:
158
+ self.logger.debug(f"Strategy {strat} committed. {commit_hash=}")
159
+ else:
160
+ commit_hash = self._git.get_last_n_commit(n=1)[0]
161
+ self.logger.debug(f"Strategy {strat} has no changes to commit, return the last {commit_hash=}")
162
+ return commit_hash
163
+
164
+ def _output_backtest_results(self, strat: str, df, start_time: float, end_time: float, commit_hash: str | None):
148
165
  strategy = self.get_strategy(strat)
149
166
  backtest_id = self._generate_backtest_id()
167
+ backtest_hash = self._generate_backtest_hash(strategy)
150
168
  backtest_name = self._create_backtest_name(strat, backtest_id)
169
+ backtest_iter = self._generate_backtest_iteration(backtest_hash)
151
170
  local_tz = utils.get_local_timezone()
152
171
  duration = end_time - start_time
153
172
  df_file_path = os.path.join(self.config.backtest_path, f'{backtest_name}.parquet')
@@ -155,7 +174,10 @@ class BacktestEngine(BaseEngine):
155
174
  'metadata': {
156
175
  'pfund_version': pf.__version__,
157
176
  'backtest_id': backtest_id,
158
- 'backtest_iteration': self._generate_backtest_iteration(strategy),
177
+ 'backtest_hash': backtest_hash,
178
+ 'backtest_name': backtest_name,
179
+ 'backtest_iteration': backtest_iter,
180
+ 'commit_hash': commit_hash,
159
181
  'duration': f'{duration:.2f}s' if duration > 1 else f'{duration*1000:.2f}ms',
160
182
  'start_time': datetime.datetime.fromtimestamp(start_time, tz=local_tz).strftime('%Y-%m-%dT%H:%M:%S%z'),
161
183
  'end_time': datetime.datetime.fromtimestamp(end_time, tz=local_tz).strftime('%Y-%m-%dT%H:%M:%S%z'),
@@ -167,7 +189,7 @@ class BacktestEngine(BaseEngine):
167
189
  self.data_tool.output_df_to_parquet(df, df_file_path)
168
190
  self._write_json(f'{backtest_name}.json', backtest_history)
169
191
  return backtest_history
170
-
192
+
171
193
  def run(self):
172
194
  for broker in self.brokers.values():
173
195
  broker.start()
@@ -181,11 +203,15 @@ class BacktestEngine(BaseEngine):
181
203
  continue
182
204
  if not hasattr(strategy, 'backtest'):
183
205
  raise Exception(f'Strategy {strat} does not have backtest() method, cannot run vectorized backtesting')
206
+ if self.auto_git_commit and self._git.is_git_repo():
207
+ commit_hash = self._commit_strategy(strategy)
208
+ else:
209
+ commit_hash = None
184
210
  start_time = time.time()
185
211
  strategy.backtest()
186
212
  end_time = time.time()
187
213
  df = strategy.get_df()
188
- backtest_history: dict = self._output_backtest_results(strat, df, start_time, end_time)
214
+ backtest_history: dict = self._output_backtest_results(strat, df, start_time, end_time, commit_hash)
189
215
  backtests[strat] = backtest_history
190
216
  elif self.mode == 'event_driven':
191
217
  for strat, strategy in self.strategy_manager.strategies.items():
@@ -0,0 +1,60 @@
1
+ import os
2
+
3
+ from git import Repo, InvalidGitRepositoryError, NoSuchPathError, Commit
4
+
5
+
6
+ class GitController:
7
+ def __init__(self, file_path: str):
8
+ # find the root directory of the Git repository that contains the given file
9
+ try:
10
+ self._repo = Repo(file_path, search_parent_directories=True)
11
+ self._repo_path = self._repo.git.rev_parse("--show-toplevel")
12
+ except (InvalidGitRepositoryError, NoSuchPathError):
13
+ self._repo = self._repo_path = None
14
+ print(f'{file_path} is not a git repository')
15
+
16
+ def is_git_repo(self):
17
+ return self._repo is not None
18
+
19
+ def get_last_n_commit(self, n=1) -> list[str]:
20
+ if not self._repo:
21
+ raise ValueError('No git repository found')
22
+ commits: list[Commit] = list(self._repo.iter_commits(paths=self._repo_path, max_count=n))
23
+ return [commit.hexsha for commit in commits]
24
+
25
+ def commit(self, file_path: str, commit_message: str) -> str | None:
26
+ if not os.path.exists(file_path):
27
+ raise FileNotFoundError(f'{file_path} not found')
28
+ if not self._repo:
29
+ raise ValueError('No git repository found')
30
+ try:
31
+ file_relpath = os.path.relpath(file_path, self._repo_path)
32
+ changed_files = [d.a_path for d in self._repo.index.diff(None)]
33
+ if file_relpath in self._repo.untracked_files or file_relpath in changed_files:
34
+ self._repo.index.add([file_relpath]) # Stage the file
35
+ commit = self._repo.index.commit(commit_message) # Commit the changes
36
+ return commit.hexsha # Return the commit hash
37
+ else:
38
+ print(f"No changes detected in {file_path}.")
39
+ return None
40
+ except Exception as e:
41
+ print(f"Error committing {file_path}: {e}")
42
+ return None
43
+
44
+ # e.g. git checkout <commit_hash> -- strategy._file_path
45
+ # and git checkout HEAD -- strategy._file_path
46
+ def checkout_file_from_commit(self, commit_hash, file_path):
47
+ """Check out a specific file from a specific commit into the working directory."""
48
+ try:
49
+ commit = self._repo.commit(commit_hash) # Get the specific commit
50
+ file_relpath = os.path.relpath(file_path, self._repo_path)
51
+ # Access the blob (file content) for the file at the specified commit
52
+ blob = commit.tree / file_relpath
53
+ # Write the content of the blob to the file in the working directory
54
+ with open(file_path, 'wb') as file:
55
+ blob.stream_data(file)
56
+ print(f"File {file_path} has been successfully checked out from commit {commit_hash}.")
57
+ except KeyError:
58
+ print(f"File {file_path} not found in commit {commit_hash}.")
59
+ except Exception as e:
60
+ print(f"Failed to checkout commit {commit_hash}: {e}")
@@ -2,7 +2,9 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  import os
5
+ import sys
5
6
  import importlib
7
+ from pathlib import Path
6
8
  from abc import ABC, abstractmethod
7
9
  from collections import defaultdict
8
10
 
@@ -41,11 +43,42 @@ if TYPE_CHECKING:
41
43
  from pfund.const.paths import MODEL_PATH
42
44
  from pfund.models.model_meta import MetaModel
43
45
  from pfund.products.product_base import BaseProduct
44
- from pfund.utils.utils import short_path, get_engine_class
46
+ from pfund.utils.utils import short_path, get_engine_class, load_yaml_file
45
47
  from pfund.plogging import create_dynamic_logger
46
48
 
47
49
 
48
50
  class BaseModel(ABC, metaclass=MetaModel):
51
+
52
+ _file_path: Path | None = None # Get the file path where the model was defined
53
+ config = {}
54
+
55
+ @classmethod
56
+ def load_config(cls, config: dict | None=None):
57
+ if config:
58
+ cls.config = config
59
+ elif cls._file_path:
60
+ for file_name in ['config.yml', 'config.yaml']:
61
+ if config := load_yaml_file(cls._file_path.parent / file_name):
62
+ cls.config = config
63
+ break
64
+
65
+ def load_params(self, params: dict | None=None):
66
+ if params:
67
+ self.params = params
68
+ elif self._file_path:
69
+ for file_name in ['params.yml', 'params.yaml']:
70
+ if params := load_yaml_file(self._file_path.parent / file_name):
71
+ self.params = params
72
+ break
73
+
74
+ def __new__(cls, *args, **kwargs):
75
+ if not cls._file_path:
76
+ module = sys.modules[cls.__module__]
77
+ if strategy_file_path := getattr(module, '__file__', None):
78
+ cls._file_path = Path(strategy_file_path)
79
+ cls.load_config()
80
+ return super().__new__(cls)
81
+
49
82
  def __init__(self, ml_model: MachineLearningModel, *args, **kwargs):
50
83
  self._args = args
51
84
  self._kwargs = kwargs
@@ -73,6 +106,9 @@ class BaseModel(ABC, metaclass=MetaModel):
73
106
  self.models = {}
74
107
  self.predictions = {}
75
108
  self.data = None # last data
109
+
110
+ self.params = {}
111
+ self.load_params()
76
112
 
77
113
  @abstractmethod
78
114
  def predict(self, *args, **kwargs) -> pd.DataFrame | torch.Tensor | np.ndarray:
@@ -92,6 +128,8 @@ class BaseModel(ABC, metaclass=MetaModel):
92
128
  return {
93
129
  'class': self.__class__.__name__,
94
130
  'name': self.name,
131
+ 'config': self.config,
132
+ 'params': self.params,
95
133
  'ml_model': self.ml_model,
96
134
  'datas': [repr(data) for product in self.datas for data in self.datas[product].values()],
97
135
  'models': [model.to_dict() for model in self.models.values()],
@@ -2,9 +2,11 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  import os
5
+ import sys
5
6
  import time
6
7
  import importlib
7
8
  import datetime
9
+ from pathlib import Path
8
10
  from collections import defaultdict, deque
9
11
  from abc import ABC
10
12
 
@@ -24,11 +26,42 @@ from pfund.zeromq import ZeroMQ
24
26
  from pfund.risk_monitor import RiskMonitor
25
27
  from pfund.const.commons import SUPPORTED_CRYPTO_EXCHANGES
26
28
  from pfund.strategies.strategy_meta import MetaStrategy
27
- from pfund.utils.utils import convert_to_uppercases, get_engine_class
29
+ from pfund.utils.utils import convert_to_uppercases, get_engine_class, load_yaml_file
28
30
  from pfund.plogging import create_dynamic_logger
29
31
 
30
32
 
31
33
  class BaseStrategy(ABC, metaclass=MetaStrategy):
34
+
35
+ _file_path: Path | None = None # Get the file path where the strategy was defined
36
+ config = {}
37
+
38
+ @classmethod
39
+ def load_config(cls, config: dict | None=None):
40
+ if config:
41
+ cls.config = config
42
+ elif cls._file_path:
43
+ for file_name in ['config.yml', 'config.yaml']:
44
+ if config := load_yaml_file(cls._file_path.parent / file_name):
45
+ cls.config = config
46
+ break
47
+
48
+ def load_params(self, params: dict | None=None):
49
+ if params:
50
+ self.params = params
51
+ elif self._file_path:
52
+ for file_name in ['params.yml', 'params.yaml']:
53
+ if params := load_yaml_file(self._file_path.parent / file_name):
54
+ self.params = params
55
+ break
56
+
57
+ def __new__(cls, *args, **kwargs):
58
+ if not cls._file_path:
59
+ module = sys.modules[cls.__module__]
60
+ if strategy_file_path := getattr(module, '__file__', None):
61
+ cls._file_path = Path(strategy_file_path)
62
+ cls.load_config()
63
+ return super().__new__(cls)
64
+
32
65
  def __init__(self, *args, **kwargs):
33
66
  self._args = args
34
67
  self._kwargs = kwargs
@@ -66,6 +99,9 @@ class BaseStrategy(ABC, metaclass=MetaStrategy):
66
99
  self.strategies = {}
67
100
  self.predictions = {}
68
101
  self.data = None # last data
102
+
103
+ self.params = {}
104
+ self.load_params()
69
105
 
70
106
  def __getattr__(self, attr):
71
107
  '''gets triggered only when the attribute is not found'''
@@ -96,6 +132,8 @@ class BaseStrategy(ABC, metaclass=MetaStrategy):
96
132
  return {
97
133
  'class': self.__class__.__name__,
98
134
  'name': self.name,
135
+ 'config': self.config,
136
+ 'params': self.params,
99
137
  'accounts': [repr(account) for trading_venue in self.accounts for account in self.accounts[trading_venue].values()],
100
138
  'datas': [repr(data) for product in self.datas for data in self.datas[product].values()],
101
139
  'strategies': [strategy.to_dict() for strategy in self.strategies.values()],
@@ -2,19 +2,25 @@
2
2
  "cells": [
3
3
  {
4
4
  "cell_type": "code",
5
- "execution_count": 1,
5
+ "execution_count": 2,
6
6
  "metadata": {},
7
- "outputs": [
8
- {
9
- "name": "stdout",
10
- "output_type": "stream",
11
- "text": [
12
- "testing pfund-overview.ipynb\n"
13
- ]
14
- }
15
- ],
7
+ "outputs": [],
8
+ "source": [
9
+ "%load_ext autoreload\n",
10
+ "# Reload all modules (except those excluded by %aimport) every time before executing the Python code typed.\n",
11
+ "%autoreload 2\n",
12
+ "\n",
13
+ "import pfund as pf\n",
14
+ "import pfolio as po"
15
+ ]
16
+ },
17
+ {
18
+ "cell_type": "code",
19
+ "execution_count": 3,
20
+ "metadata": {},
21
+ "outputs": [],
16
22
  "source": [
17
- "print('testing pfund-overview.ipynb')"
23
+ "import quantstats"
18
24
  ]
19
25
  },
20
26
  {
@@ -22,4 +22,6 @@ tSUPPORTED_TIMEFRAMES = Literal[
22
22
  ]
23
23
  tSUPPORTED_DATA_CHANNELS = Literal['orderbook', 'tradebook', 'kline']
24
24
  tSUPPORTED_BACKTEST_MODES = Literal['vectorized', 'event_driven']
25
- tSUPPORTED_DATA_TOOLS = Literal['pandas']
25
+ tSUPPORTED_DATA_TOOLS = Literal['pandas']
26
+ tSUPPORTED_CODE_EDITORS = Literal['vscode', 'pycharm']
27
+ tSUPPORTED_TEMPLATE_TYPES = Literal['notebook', 'spreadsheet', 'dashboard']
@@ -64,9 +64,18 @@ def lowercase(func):
64
64
  return wrapper
65
65
 
66
66
 
67
- def load_yaml_file(file_path):
68
- with open(file_path, 'r') as f:
69
- return yaml.safe_load(f)
67
+ def load_yaml_file(file_path) -> dict | list[dict]:
68
+ if os.path.exists(file_path):
69
+ with open(file_path, 'r') as f:
70
+ contents = list(yaml.safe_load_all(f))
71
+ if not contents:
72
+ return {}
73
+ elif len(contents) == 1:
74
+ return contents[0]
75
+ else:
76
+ return contents
77
+ else:
78
+ return {}
70
79
 
71
80
 
72
81
  def flatten_dict(d, parent_key='', sep='.'):
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pfund"
3
- version = "0.0.1.dev11"
3
+ version = "0.0.1.dev12"
4
4
  description = "A Complete Algo-Trading Framework for Machine Learning, enabling trading across TradFi, CeFi and DeFi. Supports Vectorized and Event-Driven Backtesting, Paper and Live Trading"
5
5
  license = "Apache-2.0"
6
6
  authors = ["Stephen Yau <softwareentrepreneer+pfund@gmail.com>"]
@@ -47,26 +47,27 @@ optional = true
47
47
 
48
48
  [tool.poetry.group.dev.dependencies]
49
49
  # pfeed = { path = "../pfeed", develop = true, extras = ["df", "data", "boost"] }
50
- # pfolio = { path = "../pfolio", develop = true, extras = ["bayesian", "data", "portfolio", "temporary"] }
50
+ pfolio = { path = "../pfolio", develop = true, extras = ["bayesian", "data", "portfolio", "temporary"] }
51
51
  pybit = "^5.6.2"
52
52
  ta-lib = "^0.4.28"
53
53
 
54
54
  [tool.poetry.group.test.dependencies]
55
55
  pytest = "^8.0.0"
56
+ pytest-mock = "^3.14.0"
57
+ pytest-cov = "^5.0.0"
58
+ pytest-xdist = "^3.5.0"
59
+ tox = "^4.14.2"
60
+ faker = "^24.4.0"
56
61
  pre-commit = "^3.6.1"
57
62
  bandit = "^1.7.7"
58
63
  grayskull = "^2.5.3"
59
- pytest-xdist = "^3.5.0"
60
- faker = "^24.4.0"
61
- tox = "^4.14.2"
62
64
  mypy = "^1.9.0"
63
65
  ruff = "^0.3.5"
64
- pytest-mock = "^3.14.0"
65
- pytest-cov = "^5.0.0"
66
66
 
67
67
  [tool.poetry.group.doc.dependencies]
68
68
  jupyter-book = "^1.0.0"
69
69
  notebook = "^7.1.2"
70
+ sphinxawesome-theme = "^5.1.1"
70
71
 
71
72
  [build-system]
72
73
  requires = ["poetry-core"]
File without changes
File without changes