pfund 0.0.1.dev3__tar.gz → 0.0.1.dev4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/PKG-INFO +4 -3
  2. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/README.md +1 -0
  3. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/__init__.py +3 -2
  4. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/cli/commands/config.py +4 -10
  5. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/cli/commands/docker_compose.py +1 -1
  6. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/cli/main.py +2 -4
  7. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config_handler.py +16 -5
  8. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/engines/backtest_engine.py +1 -2
  9. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/engines/base_engine.py +3 -2
  10. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/mixins/backtest.py +14 -9
  11. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/plogging/__init__.py +10 -10
  12. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/plogging/config.py +1 -2
  13. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pyproject.toml +11 -7
  14. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/LICENSE +0 -0
  15. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/accounts/__init__.py +0 -0
  16. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/accounts/account_base.py +0 -0
  17. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/accounts/account_crypto.py +0 -0
  18. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/accounts/account_ib.py +0 -0
  19. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/adapter.py +0 -0
  20. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/balances/__init__.py +0 -0
  21. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/balances/balance_base.py +0 -0
  22. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/balances/balance_crypto.py +0 -0
  23. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/balances/balance_ib.py +0 -0
  24. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/brokers/__init__.py +0 -0
  25. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/brokers/broker_backtest.py +0 -0
  26. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/brokers/broker_base.py +0 -0
  27. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/brokers/broker_crypto.py +0 -0
  28. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/brokers/broker_live.py +0 -0
  29. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/brokers/ib/__init__.py +0 -0
  30. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/brokers/ib/broker_ib.py +0 -0
  31. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/brokers/ib/ib_api.py +0 -0
  32. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/brokers/ib/ib_client.py +0 -0
  33. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/brokers/ib/ib_wrapper.py +0 -0
  34. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/cli/__init__.py +0 -0
  35. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/cli/commands/__init__.py +0 -0
  36. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/bybit/config.yml +0 -0
  37. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/bybit/lot_sizes_inverse.yml +0 -0
  38. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/bybit/lot_sizes_linear.yml +0 -0
  39. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/bybit/lot_sizes_option.yml +0 -0
  40. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/bybit/lot_sizes_spot.yml +0 -0
  41. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/bybit/pdt_matchings_inverse.yml +0 -0
  42. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/bybit/pdt_matchings_linear.yml +0 -0
  43. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/bybit/pdt_matchings_option.yml +0 -0
  44. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/bybit/pdt_matchings_spot.yml +0 -0
  45. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/bybit/tick_sizes_inverse.yml +0 -0
  46. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/bybit/tick_sizes_linear.yml +0 -0
  47. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/bybit/tick_sizes_option.yml +0 -0
  48. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/bybit/tick_sizes_spot.yml +0 -0
  49. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/configuration.py +0 -0
  50. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/ib/config.yml +0 -0
  51. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/config/logging.yml +0 -0
  52. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/const/__init__.py +0 -0
  53. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/const/_zmq_routes.py +0 -0
  54. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/const/commons.py +0 -0
  55. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/const/paths.py +0 -0
  56. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/data_tools/data_tool_base.py +0 -0
  57. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/data_tools/data_tool_pandas.py +0 -0
  58. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/datas/__init__.py +0 -0
  59. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/datas/data_bar.py +0 -0
  60. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/datas/data_base.py +0 -0
  61. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/datas/data_quote.py +0 -0
  62. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/datas/data_tick.py +0 -0
  63. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/datas/data_time_based.py +0 -0
  64. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/datas/resolution.py +0 -0
  65. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/datas/timeframe.py +0 -0
  66. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/engines/__init__.py +0 -0
  67. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/engines/test_engine.py +0 -0
  68. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/engines/trade_engine.py +0 -0
  69. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/engines/train_engine.py +0 -0
  70. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/errors.py +0 -0
  71. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/__init__.py +0 -0
  72. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/bybit/__init__.py +0 -0
  73. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/bybit/exchange.py +0 -0
  74. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/bybit/rest_api.py +0 -0
  75. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/bybit/rest_api_samples/get_markets_result_inverse +0 -0
  76. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/bybit/rest_api_samples/get_markets_result_linear +0 -0
  77. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/bybit/rest_api_samples/get_markets_result_option +0 -0
  78. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/bybit/rest_api_samples/get_markets_result_spot +0 -0
  79. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/bybit/rest_api_samples/get_markets_return_inverse +0 -0
  80. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/bybit/rest_api_samples/get_markets_return_linear +0 -0
  81. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/bybit/rest_api_samples/get_markets_return_option +0 -0
  82. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/bybit/rest_api_samples/get_markets_return_spot +0 -0
  83. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/bybit/types.py +0 -0
  84. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/bybit/ws_api.py +0 -0
  85. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/exchange_base.py +0 -0
  86. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/rest_api_base.py +0 -0
  87. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/exchanges/ws_api_base.py +0 -0
  88. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/__init__.py +0 -0
  89. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/account_summary_tags.py +0 -0
  90. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/client.py +0 -0
  91. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/comm.py +0 -0
  92. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/commission_report.py +0 -0
  93. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/common.py +0 -0
  94. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/connection.py +0 -0
  95. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/contract.py +0 -0
  96. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/decoder.py +0 -0
  97. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/enum_implem.py +0 -0
  98. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/errors.py +0 -0
  99. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/execution.py +0 -0
  100. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/ibapi.pyproj +0 -0
  101. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/message.py +0 -0
  102. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/news.py +0 -0
  103. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/object_implem.py +0 -0
  104. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/order.py +0 -0
  105. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/order_condition.py +0 -0
  106. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/order_state.py +0 -0
  107. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/orderdecoder.py +0 -0
  108. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/reader.py +0 -0
  109. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/scanner.py +0 -0
  110. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/server_versions.py +0 -0
  111. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/softdollartier.py +0 -0
  112. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/tag_value.py +0 -0
  113. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/ticktype.py +0 -0
  114. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/utils.py +0 -0
  115. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/externals/ibapi/wrapper.py +0 -0
  116. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/indicators/__init__.py +0 -0
  117. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/indicators/indicator_base.py +0 -0
  118. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/indicators/ta_indicator.py +0 -0
  119. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/indicators/talib_indicator.py +0 -0
  120. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/main.py +0 -0
  121. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/managers/__init__.py +0 -0
  122. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/managers/base_manager.py +0 -0
  123. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/managers/connection_manager.py +0 -0
  124. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/managers/data_manager.py +0 -0
  125. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/managers/order_manager.py +0 -0
  126. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/managers/portfolio_manager.py +0 -0
  127. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/managers/risk_manager.py +0 -0
  128. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/managers/strategy_manager.py +0 -0
  129. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/models/__init__.py +0 -0
  130. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/models/model_backtest.py +0 -0
  131. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/models/model_base.py +0 -0
  132. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/models/model_meta.py +0 -0
  133. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/models/pytorch_model.py +0 -0
  134. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/models/sklearn_model.py +0 -0
  135. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/orders/__init__.py +0 -0
  136. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/orders/order_base.py +0 -0
  137. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/orders/order_crypto.py +0 -0
  138. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/orders/order_ib.py +0 -0
  139. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/orders/order_statuses.py +0 -0
  140. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/orders/order_time_in_force.py +0 -0
  141. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/plogging/filters.py +0 -0
  142. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/plogging/formatter.py +0 -0
  143. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/plogging/handlers.py +0 -0
  144. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/portfolio.py +0 -0
  145. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/positions/__init__.py +0 -0
  146. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/positions/position_base.py +0 -0
  147. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/positions/position_crypto.py +0 -0
  148. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/positions/position_ib.py +0 -0
  149. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/products/__init__.py +0 -0
  150. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/products/product_base.py +0 -0
  151. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/products/product_crypto.py +0 -0
  152. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/products/product_ib.py +0 -0
  153. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/risk_monitor.py +0 -0
  154. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/strategies/__init__.py +0 -0
  155. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/strategies/strategy_backtest.py +0 -0
  156. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/strategies/strategy_base.py +0 -0
  157. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/strategies/strategy_meta.py +0 -0
  158. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/utils/aliases.py +0 -0
  159. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/utils/envs.py +0 -0
  160. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/utils/utils.py +0 -0
  161. {pfund-0.0.1.dev3 → pfund-0.0.1.dev4}/pfund/zeromq.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pfund
3
- Version: 0.0.1.dev3
3
+ Version: 0.0.1.dev4
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
@@ -13,9 +13,9 @@ Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Requires-Dist: click (>=8.1.7,<9.0.0)
16
- Requires-Dist: orjson (>=3.9.12,<4.0.0)
16
+ Requires-Dist: orjson (>=3.9.14,<4.0.0)
17
17
  Requires-Dist: pandas (>=2.2.0,<3.0.0)
18
- Requires-Dist: pfeed (>=0.0.1.dev3,<0.0.2)
18
+ Requires-Dist: pfeed (>=0.0.1.dev4,<0.0.2)
19
19
  Requires-Dist: platformdirs (>=4.2.0,<5.0.0)
20
20
  Requires-Dist: psutil (>=5.9.8,<6.0.0)
21
21
  Requires-Dist: python-telegram-bot (>=20.7,<21.0)
@@ -33,6 +33,7 @@ Description-Content-Type: text/markdown
33
33
 
34
34
  # PFund: Algo-Trading Framework for Machine Learning, TradFi, CeFi and DeFi ready.
35
35
 
36
+ [![Jupyter Book Badge](docs/images/jupyterbook.svg)](https://jupyterbook.org)
36
37
  [![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/)
37
38
  [![PyPI](https://img.shields.io/pypi/v/pfund.svg)](https://pypi.org/project/pfund)
38
39
  ![PyPI - Support Python Versions](https://img.shields.io/pypi/pyversions/pfund)
@@ -1,5 +1,6 @@
1
1
  # PFund: Algo-Trading Framework for Machine Learning, TradFi, CeFi and DeFi ready.
2
2
 
3
+ [![Jupyter Book Badge](docs/images/jupyterbook.svg)](https://jupyterbook.org)
3
4
  [![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/)
4
5
  [![PyPI](https://img.shields.io/pypi/v/pfund.svg)](https://pypi.org/project/pfund)
5
6
  ![PyPI - Support Python Versions](https://img.shields.io/pypi/pyversions/pfund)
@@ -1,3 +1,5 @@
1
+ from importlib.metadata import version
2
+
1
3
  from pfund.config_handler import configure
2
4
  from pfund.engines import BacktestEngine, TrainEngine, TestEngine, TradeEngine
3
5
  from pfund.strategies import Strategy
@@ -11,7 +13,6 @@ try:
11
13
  except ImportError:
12
14
  pass
13
15
  from pfund.indicators import TAIndicator, TALibIndicator
14
- from importlib.metadata import version
15
16
 
16
17
 
17
18
  __version__ = version('pfund')
@@ -23,4 +24,4 @@ __all__ = (
23
24
  'BacktestEngine', 'TrainEngine', 'TestEngine', 'TradeEngine',
24
25
  'Strategy', 'Model', 'PyTorchModel', 'SKLearnModel',
25
26
  'Feature', 'TAIndicator', 'TALibIndicator',
26
- )
27
+ )
@@ -9,14 +9,6 @@ from pfund.const.paths import USER_CONFIG_FILE_PATH
9
9
  from pfund.config_handler import ConfigHandler
10
10
 
11
11
 
12
- def load_config(config_file_path: str | Path):
13
- config_file_path = Path(config_file_path)
14
- if config_file_path.is_file():
15
- with open(config_file_path, 'r') as f:
16
- return yaml.safe_load(f) or {}
17
- return {}
18
-
19
-
20
12
  def save_config(config: ConfigHandler, config_file_path: str | Path):
21
13
  with open(config_file_path, 'w') as f:
22
14
  yaml.dump(config.__dict__, f, default_flow_style=False)
@@ -48,14 +40,16 @@ def config(ctx, **kwargs):
48
40
  if kwargs.get('list'): # Check if --list was used
49
41
  del provided_options['list']
50
42
  assert not provided_options, "No options should be provided with --list"
51
- click.echo(f"PFund's config:\n{pformat(config.__dict__)}")
43
+ config_dict = config.__dict__
44
+ config_dict.update({'config_file_path': USER_CONFIG_FILE_PATH})
45
+ click.echo(f"PFund's config:\n{pformat(config_dict)}")
52
46
  return
53
47
 
54
48
  if kwargs.get('reset'): # Check if --reset was used
55
49
  del provided_options['reset']
56
50
  assert not provided_options, "No options should be provided with --reset"
57
51
  remove_config(USER_CONFIG_FILE_PATH)
58
- click.echo("PFund;s config successfully reset.")
52
+ click.echo("PFund's config successfully reset.")
59
53
  return
60
54
 
61
55
  # prints out current config if no options are provided
@@ -20,7 +20,7 @@ def docker_compose(ctx, env_file_path, docker_file_path):
20
20
  if not env_file_path:
21
21
  env_file_path = find_dotenv(usecwd=True, raise_error_if_not_found=True)
22
22
  click.echo(f'.env file path is not specified, using env file in "{env_file_path}"')
23
- load_dotenv(env_file_path)
23
+ load_dotenv(env_file_path, override=True)
24
24
  if not docker_file_path:
25
25
  package_dir = Path(importlib.resources.files(PROJ_NAME)).resolve().parents[0]
26
26
  docker_file_path = package_dir / 'docker-compose.yml'
@@ -1,9 +1,8 @@
1
1
  import click
2
2
 
3
3
  from pfund.config_handler import ConfigHandler
4
- from pfund.const.paths import USER_CONFIG_FILE_PATH
5
4
  from pfund.cli.commands.docker_compose import docker_compose
6
- from pfund.cli.commands.config import config, load_config
5
+ from pfund.cli.commands.config import config
7
6
 
8
7
 
9
8
  @click.group(context_settings={"help_option_names": ["-h", "--help"]})
@@ -12,8 +11,7 @@ from pfund.cli.commands.config import config, load_config
12
11
  def pfund_group(ctx):
13
12
  """pfund's CLI"""
14
13
  ctx.ensure_object(dict)
15
- config: dict = load_config(USER_CONFIG_FILE_PATH)
16
- ctx.obj['config'] = ConfigHandler(**config)
14
+ ctx.obj['config'] = ConfigHandler.load_config()
17
15
 
18
16
 
19
17
  pfund_group.add_command(docker_compose)
@@ -6,13 +6,14 @@ import logging
6
6
  from types import TracebackType
7
7
  from dataclasses import dataclass
8
8
 
9
+ import yaml
9
10
  # from rich.traceback import install
10
11
 
11
- from pfund.const.paths import PROJ_NAME, PROJ_PATH, LOG_PATH, PROJ_CONFIG_PATH, DATA_PATH
12
+ from pfund.const.paths import PROJ_NAME, PROJ_PATH, LOG_PATH, PROJ_CONFIG_PATH, DATA_PATH, USER_CONFIG_FILE_PATH
13
+
12
14
  # add python path so that for files like "ibapi" (official python code from IB)
13
15
  # can find their modules
14
16
  sys.path.append(f'{PROJ_PATH}/externals')
15
-
16
17
  # install(show_locals=False) # rich will set its own sys.excepthook
17
18
  # rich_excepthook = sys.excepthook # get rich's excepthook
18
19
 
@@ -50,19 +51,29 @@ def import_strategies_models_features_or_indicators(path: str):
50
51
 
51
52
  @dataclass
52
53
  class ConfigHandler:
53
- data_path: str = str(DATA_PATH),
54
+ data_path: str = str(DATA_PATH)
54
55
  log_path: str = str(LOG_PATH)
55
56
  logging_config_file_path: str = f'{PROJ_CONFIG_PATH}/logging.yml'
56
57
  logging_config: dict | None = None
57
58
  use_fork_process: bool = True
58
59
  use_custom_excepthook: bool = True
59
60
 
61
+ @classmethod
62
+ def load_config(cls):
63
+ config_file_path = USER_CONFIG_FILE_PATH
64
+ if config_file_path.is_file():
65
+ with open(config_file_path, 'r') as f:
66
+ config = yaml.safe_load(f) or {}
67
+ else:
68
+ config = {}
69
+ return cls(**config)
70
+
60
71
  def __post_init__(self):
61
72
  self.logging_config = self.logging_config or {}
62
73
 
63
74
  strategy_path, model_path = f'{self.data_path}/strategies', f'{self.data_path}/models'
64
75
  feature_path, indicator_path = f'{self.data_path}/features', f'{self.data_path}/indicators'
65
- for path in (strategy_path, model_path, feature_path, indicator_path):
76
+ for path in [strategy_path, model_path, feature_path, indicator_path]:
66
77
  if not os.path.exists(path):
67
78
  os.makedirs(path)
68
79
  print(f'created {path}')
@@ -74,7 +85,7 @@ class ConfigHandler:
74
85
 
75
86
  if self.use_custom_excepthook:
76
87
  sys.excepthook = _custom_excepthook
77
-
88
+
78
89
 
79
90
  def configure(
80
91
  data_path: str = str(DATA_PATH),
@@ -79,8 +79,7 @@ class BacktestEngine(BaseEngine):
79
79
  continue
80
80
  if not hasattr(strategy, 'backtest'):
81
81
  raise Exception(f'Strategy {strat} does not have backtest() method, cannot run vectorized backtesting')
82
- df = strategy.get_df()
83
- strategy.backtest(df.copy(deep=True))
82
+ strategy.backtest()
84
83
  elif self.mode == 'event_driven':
85
84
  for strat, strategy in self.strategy_manager.strategies.items():
86
85
  if strat == '_dummy':
@@ -12,6 +12,7 @@ from pfund.managers.strategy_manager import StrategyManager
12
12
  from pfund.const.commons import *
13
13
  from pfund.config_handler import ConfigHandler
14
14
  from pfund.plogging import set_up_loggers
15
+ from pfund.plogging.config import LoggingDictConfigurator
15
16
 
16
17
 
17
18
  ENV_COLORS = {
@@ -43,10 +44,10 @@ class BaseEngine(Singleton):
43
44
  if not hasattr(cls, 'settings'):
44
45
  cls.settings = settings
45
46
  if not hasattr(cls, 'config'):
46
- cls.config = config if config else ConfigHandler()
47
+ cls.config = config if config else ConfigHandler.load_config()
47
48
  log_path = f'{cls.config.log_path}/{cls.env}'
48
49
  logging_config_file_path = cls.config.logging_config_file_path
49
- set_up_loggers(log_path, logging_config_file_path, user_logging_config=cls.config.logging_config)
50
+ cls.logging_configurator: LoggingDictConfigurator = set_up_loggers(log_path, logging_config_file_path, user_logging_config=cls.config.logging_config)
50
51
  return super().__new__(cls)
51
52
 
52
53
  def __init__(self, env, data_tool: DataTool='pandas', config: ConfigHandler | None=None, **settings):
@@ -12,7 +12,6 @@ if TYPE_CHECKING:
12
12
 
13
13
  from pfund.managers.data_manager import get_resolutions_from_kwargs
14
14
  from pfund.models.model_backtest import BacktestModel
15
- from pfund.strategies.strategy_base import BaseStrategy
16
15
  from pfund.models.model_base import BaseModel
17
16
 
18
17
 
@@ -25,7 +24,7 @@ class BacktestMixin:
25
24
  backtest_kwargs, train_kwargs = backtest or {}, train or {}
26
25
 
27
26
  if backtest_kwargs:
28
- data_source = self._get_data_source(backtest_kwargs)
27
+ data_source = self._get_data_source(trading_venue, backtest_kwargs)
29
28
  feed = self.get_feed(data_source)
30
29
  kwargs = self._prepare_kwargs(feed, kwargs)
31
30
 
@@ -45,11 +44,15 @@ class BacktestMixin:
45
44
  model = BacktestModel(type(model), model.ml_model, *model._args, **model._kwargs)
46
45
  return super().add_model(model, name=name, model_path=model_path, is_load=is_load)
47
46
 
48
- def _get_data_source(self, backtest_kwargs: dict):
47
+ def _get_data_source(self, trading_venue: str, backtest_kwargs: dict):
49
48
  from pfeed.const.commons import SUPPORTED_DATA_FEEDS
49
+ trading_venue = trading_venue.upper()
50
+ # if data_source is not defined, use trading_venue as data_source
51
+ if trading_venue in SUPPORTED_DATA_FEEDS and 'data_source' not in backtest_kwargs:
52
+ backtest_kwargs['data_source'] = trading_venue
50
53
  assert 'data_source' in backtest_kwargs, f"data_source must be defined"
51
54
  data_source = backtest_kwargs['data_source'].upper()
52
- assert backtest_kwargs['data_source'] in SUPPORTED_DATA_FEEDS, f"{data_source=} not in {SUPPORTED_DATA_FEEDS}"
55
+ assert data_source in SUPPORTED_DATA_FEEDS, f"{data_source=} not in {SUPPORTED_DATA_FEEDS}"
53
56
  return data_source
54
57
 
55
58
  def _prepare_kwargs(self, feed: BaseFeed, kwargs: dict):
@@ -99,10 +102,12 @@ class BacktestMixin:
99
102
 
100
103
  @staticmethod
101
104
  def get_feed(data_source: str) -> BaseFeed:
102
- import pfeed as dd
105
+ from pfeed.feeds import YahooFinanceFeed, BybitFeed
103
106
  data_source = data_source.upper()
104
107
  if data_source == 'YAHOO_FINANCE':
105
- feed = dd.YahooFinanceFeed()
108
+ feed = YahooFinanceFeed()
109
+ elif data_source == 'BYBIT':
110
+ feed = BybitFeed()
106
111
  # TODO: other feeds
107
112
  else:
108
113
  raise NotImplementedError
@@ -123,9 +128,9 @@ class BacktestMixin:
123
128
  continue
124
129
  product = data.product
125
130
  resolution = data.resolution
126
- symbol = product.symbol
127
- df = feed.get_historical_data(symbol, rollback_period=rollback_period, start_date=start_date, end_date=end_date, resolution=repr(resolution), **backtest_kwargs)
128
- assert not df.empty, f"dataframe is empty for {symbol=}"
131
+ pdt_or_symbol = product.symbol if feed.name == 'YAHOO_FINANCE' else product.pdt
132
+ df = feed.get_historical_data(pdt_or_symbol, rollback_period=rollback_period, start_date=start_date, end_date=end_date, resolution=repr(resolution), **backtest_kwargs)
133
+ assert not df.empty, f"dataframe is empty for {pdt_or_symbol=}"
129
134
  df.reset_index(inplace=True)
130
135
  latest_date = str(df['ts'][0])
131
136
  if feed.name == 'YAHOO_FINANCE' and latest_date == utcnow_date:
@@ -1,11 +1,10 @@
1
1
  import os
2
2
  import logging
3
- from pathlib import Path
4
3
 
5
4
  from typing import Literal
6
5
 
7
6
  from pfund.plogging.config import LoggingDictConfigurator
8
- from pfund.utils.utils import load_yaml_file
7
+ from pfund.utils.utils import load_yaml_file, get_engine_class
9
8
 
10
9
 
11
10
  def print_all_loggers():
@@ -14,7 +13,7 @@ def print_all_loggers():
14
13
  print(name, logger, logger.handlers)
15
14
 
16
15
 
17
- def set_up_loggers(log_path, logging_config_file_path, user_logging_config: dict | None=None):
16
+ def set_up_loggers(log_path, logging_config_file_path, user_logging_config: dict | None=None) -> LoggingDictConfigurator:
18
17
  def deep_update(default_dict, override_dict, raise_if_key_not_exist=False):
19
18
  '''Updates a default dictionary with an override dictionary, supports nested dictionaries.'''
20
19
  for key, value in override_dict.items():
@@ -33,9 +32,8 @@ def set_up_loggers(log_path, logging_config_file_path, user_logging_config: dict
33
32
  else:
34
33
  # Update the key with the override value
35
34
  default_dict[key] = value
36
- print('Setting up loggers...')
37
- log_path, logging_config_file_path = Path(log_path), Path(logging_config_file_path)
38
- if not log_path.exists():
35
+ # print('Setting up loggers...')
36
+ if not os.path.exists(log_path):
39
37
  os.makedirs(log_path)
40
38
  print(f'created {str(log_path)}')
41
39
  logging_config: dict = load_yaml_file(logging_config_file_path)
@@ -43,8 +41,10 @@ def set_up_loggers(log_path, logging_config_file_path, user_logging_config: dict
43
41
  deep_update(logging_config, user_logging_config)
44
42
  logging_config['log_path'] = log_path
45
43
  # ≈ logging.config.dictConfig(logging_config) with a custom configurator
46
- LoggingDictConfigurator(logging_config).configure()
47
-
44
+ logging_configurator = LoggingDictConfigurator(logging_config)
45
+ logging_configurator.configure()
46
+ return logging_configurator
47
+
48
48
 
49
49
  # TODO: support 'feature', 'indicator'
50
50
  def create_dynamic_logger(name: str, type_: Literal['strategy', 'model', 'manager']):
@@ -57,8 +57,8 @@ def create_dynamic_logger(name: str, type_: Literal['strategy', 'model', 'manage
57
57
  assert name, "logger name cannot be empty/None"
58
58
  assert type_ in ['strategy', 'model', 'manager'], f"Unsupported {type_=}"
59
59
 
60
- # NOTE: LoggingDictConfigurator is a singleton, since it has already configured in set_up_loggers(), no need to pass in config to it
61
- config = LoggingDictConfigurator(config=None)
60
+ Engine = get_engine_class()
61
+ config = Engine.logging_configurator
62
62
 
63
63
  logging_config = config.config_orig
64
64
  loggers_config = logging_config['loggers']
@@ -4,7 +4,6 @@ import copy
4
4
  import logging
5
5
  from logging.config import DictConfigurator
6
6
 
7
- from pfund.utils.utils import Singleton
8
7
  from pfund.plogging.filters import FullPathFilter
9
8
  from pfund.plogging.formatter import ColoredFormatter
10
9
 
@@ -19,7 +18,7 @@ LEVELS = {
19
18
 
20
19
 
21
20
  # override logging's DictConfigurator as it doesn't pass in logger names to file handlers to create filenames
22
- class LoggingDictConfigurator(Singleton, DictConfigurator):
21
+ class LoggingDictConfigurator(DictConfigurator):
23
22
  _MANUALLY_CONFIGURED_HANDLERS = [
24
23
  'file_handler',
25
24
  'compressed_timed_rotating_file_handler',
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pfund"
3
- version = "0.0.1.dev3"
3
+ version = "0.0.1.dev4"
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>"]
@@ -12,11 +12,11 @@ keywords = ["trading", "algo-trading", "stocks", "cryptos", "cryptocurrencies",
12
12
 
13
13
  [tool.poetry.dependencies]
14
14
  python = "^3.10 <3.12"
15
- pfeed = "^0.0.1.dev3"
15
+ pfeed = "^0.0.1.dev4"
16
16
  pyzmq = "^25.1.2"
17
17
  pyyaml = "^6.0.1"
18
18
  psutil = "^5.9.8"
19
- orjson = "^3.9.12"
19
+ orjson = "^3.9.14"
20
20
  rich = "^13.7.0"
21
21
  schedule = "^1.2.1"
22
22
  websocket-client = "^1.7.0"
@@ -39,14 +39,18 @@ pfeed = {path = "../pfeed", develop = true}
39
39
  pybit = "^5.6.2"
40
40
  ta-lib = "^0.4.28"
41
41
  pytest = "^8.0.0"
42
- sphinx = "^7.2.6"
43
- autodocsumm = {git = "https://github.com/Chilipp/autodocsumm.git"}
44
- sphinxcontrib-napoleon = "^0.7"
45
- pre-commit = "^3.6.0"
42
+ pre-commit = "^3.6.1"
46
43
  bandit = "^1.7.7"
47
44
  ruff = "^0.1.15"
48
45
  pyright = "^1.1.349"
49
46
 
47
+ [tool.poetry.group.doc]
48
+ optional = true
49
+
50
+ [tool.poetry.group.doc.dependencies]
51
+ jupyter-book = "^1.0.0"
52
+ notebook = "^7.1.0"
53
+
50
54
  [build-system]
51
55
  requires = ["poetry-core"]
52
56
  build-backend = "poetry.core.masonry.api"
File without changes
File without changes
File without changes
File without changes
File without changes