wbfdm 1.51.7__tar.gz → 1.52.0__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.

Potentially problematic release.


This version of wbfdm might be problematic. Click here for more details.

Files changed (363) hide show
  1. {wbfdm-1.51.7 → wbfdm-1.52.0}/PKG-INFO +2 -1
  2. {wbfdm-1.51.7 → wbfdm-1.52.0}/pyproject.toml +1 -0
  3. wbfdm-1.52.0/wbfdm/analysis/financial_analysis/change_point_detection.py +88 -0
  4. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/instruments.py +76 -0
  5. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/querysets.py +9 -4
  6. {wbfdm-1.51.7 → wbfdm-1.52.0}/.gitignore +0 -0
  7. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/__init__.py +0 -0
  8. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/admin/__init__.py +0 -0
  9. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/admin/classifications.py +0 -0
  10. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/admin/esg.py +0 -0
  11. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/admin/exchanges.py +0 -0
  12. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/admin/instrument_lists.py +0 -0
  13. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/admin/instrument_prices.py +0 -0
  14. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/admin/instrument_requests.py +0 -0
  15. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/admin/instruments.py +0 -0
  16. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/admin/instruments_relationships.py +0 -0
  17. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/admin/options.py +0 -0
  18. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/__init__.py +0 -0
  19. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/esg/__init__.py +0 -0
  20. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/esg/enums.py +0 -0
  21. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/esg/esg_analysis.py +0 -0
  22. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/esg/utils.py +0 -0
  23. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/financial_analysis/__init__.py +0 -0
  24. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/financial_analysis/financial_metric_analysis.py +0 -0
  25. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/financial_analysis/financial_ratio_analysis.py +0 -0
  26. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/financial_analysis/financial_statistics_analysis.py +0 -0
  27. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/financial_analysis/statement_with_estimates.py +0 -0
  28. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/financial_analysis/utils.py +0 -0
  29. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/technical_analysis/__init__.py +0 -0
  30. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/technical_analysis/technical_analysis.py +0 -0
  31. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/technical_analysis/traces.py +0 -0
  32. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/analysis/utils.py +0 -0
  33. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/apps.py +0 -0
  34. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/backends/dto.py +0 -0
  35. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/__init__.py +0 -0
  36. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/dsws/__init__.py +0 -0
  37. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/dsws/client.py +0 -0
  38. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/dsws/dataloaders/market_data.py +0 -0
  39. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/internal/__init__.py +0 -0
  40. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/internal/dataloaders/__init__.py +0 -0
  41. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/internal/dataloaders/market_data.py +0 -0
  42. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/__init__.py +0 -0
  43. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/admin/__init__.py +0 -0
  44. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/admin/instruments.py +0 -0
  45. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/admin/metrics.py +0 -0
  46. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/apps.py +0 -0
  47. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/backends/__init__.py +0 -0
  48. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/backends/base.py +0 -0
  49. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/backends/performances.py +0 -0
  50. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/backends/statistics.py +0 -0
  51. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/backends/utils.py +0 -0
  52. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/decorators.py +0 -0
  53. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/dispatch.py +0 -0
  54. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/dto.py +0 -0
  55. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/exceptions.py +0 -0
  56. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/factories.py +0 -0
  57. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/filters.py +0 -0
  58. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/migrations/0001_initial.py +0 -0
  59. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/migrations/0002_remove_instrumentmetric_unique_instrument_metric_and_more.py +0 -0
  60. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/migrations/__init__.py +0 -0
  61. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/models.py +0 -0
  62. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/orchestrators.py +0 -0
  63. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/registry.py +0 -0
  64. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/serializers.py +0 -0
  65. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/tasks.py +0 -0
  66. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/tests/__init__.py +0 -0
  67. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/tests/backends/__init__.py +0 -0
  68. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/tests/backends/test_performances.py +0 -0
  69. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/tests/backends/test_statistics.py +0 -0
  70. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/tests/conftest.py +0 -0
  71. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/tests/test_dto.py +0 -0
  72. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/tests/test_models.py +0 -0
  73. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/tests/test_tasks.py +0 -0
  74. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/tests/test_viewsets.py +0 -0
  75. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/urls.py +0 -0
  76. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/viewsets/__init__.py +0 -0
  77. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/viewsets/configs/__init__.py +0 -0
  78. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/viewsets/configs/display.py +0 -0
  79. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/viewsets/configs/menus.py +0 -0
  80. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/viewsets/configs/utils.py +0 -0
  81. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/viewsets/mixins.py +0 -0
  82. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/metric/viewsets/viewsets.py +0 -0
  83. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/msci/__init__.py +0 -0
  84. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/msci/client.py +0 -0
  85. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/msci/dataloaders/__init__.py +0 -0
  86. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/msci/dataloaders/esg.py +0 -0
  87. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/msci/dataloaders/esg_controversies.py +0 -0
  88. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/msci/sync.py +0 -0
  89. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/msci/tests/__init__.py +0 -0
  90. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/msci/tests/conftest.py +0 -0
  91. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/msci/tests/test_client.py +0 -0
  92. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/__init__.py +0 -0
  93. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/apps.py +0 -0
  94. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/database_routers.py +0 -0
  95. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/dataloaders/__init__.py +0 -0
  96. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/dataloaders/adjustments.py +0 -0
  97. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/dataloaders/corporate_actions.py +0 -0
  98. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/dataloaders/financials.py +0 -0
  99. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/dataloaders/market_data.py +0 -0
  100. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/dataloaders/officers.py +0 -0
  101. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/dataloaders/reporting_dates.py +0 -0
  102. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/dataloaders/statements.py +0 -0
  103. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/dataloaders/utils.py +0 -0
  104. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/jinja2/qa/sql/companies.sql +0 -0
  105. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/base_estimates.sql +0 -0
  106. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/calendarized.sql +0 -0
  107. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/complete.sql +0 -0
  108. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/estimates.sql +0 -0
  109. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/financials.sql +0 -0
  110. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/jinja2/qa/sql/instruments.sql +0 -0
  111. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/jinja2/qa/sql/quotes.sql +0 -0
  112. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/sync/exchanges.py +0 -0
  113. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/sync/instruments.py +0 -0
  114. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/sync/utils.py +0 -0
  115. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/contrib/qa/tasks.py +0 -0
  116. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/dataloaders/__init__.py +0 -0
  117. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/dataloaders/cache.py +0 -0
  118. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/dataloaders/protocols.py +0 -0
  119. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/dataloaders/proxies.py +0 -0
  120. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/dataloaders/types.py +0 -0
  121. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/dynamic_preferences_registry.py +0 -0
  122. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/enums.py +0 -0
  123. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/factories/__init__.py +0 -0
  124. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/factories/classifications.py +0 -0
  125. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/factories/controversies.py +0 -0
  126. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/factories/exchanges.py +0 -0
  127. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/factories/instrument_list.py +0 -0
  128. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/factories/instrument_prices.py +0 -0
  129. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/factories/instruments.py +0 -0
  130. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/factories/instruments_relationships.py +0 -0
  131. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/factories/options.py +0 -0
  132. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/figures/__init__.py +0 -0
  133. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/figures/financials/__init__.py +0 -0
  134. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/figures/financials/financial_analysis_charts.py +0 -0
  135. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/figures/financials/financials_charts.py +0 -0
  136. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/filters/__init__.py +0 -0
  137. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/filters/classifications.py +0 -0
  138. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/filters/exchanges.py +0 -0
  139. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/filters/financials.py +0 -0
  140. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/filters/financials_analysis.py +0 -0
  141. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/filters/instrument_prices.py +0 -0
  142. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/filters/instruments.py +0 -0
  143. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/filters/utils.py +0 -0
  144. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/__init__.py +0 -0
  145. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/__init__.py +0 -0
  146. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/cbinsights/__init__.py +0 -0
  147. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/cbinsights/deals.py +0 -0
  148. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/cbinsights/equities.py +0 -0
  149. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/cbinsights/mixin.py +0 -0
  150. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/cbinsights/utils/__init__.py +0 -0
  151. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/cbinsights/utils/classifications.py +0 -0
  152. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/cbinsights/utils/client.py +0 -0
  153. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/refinitiv/__init__.py +0 -0
  154. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/refinitiv/daily_fundamental.py +0 -0
  155. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/refinitiv/fiscal_period.py +0 -0
  156. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/refinitiv/forecast.py +0 -0
  157. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/refinitiv/fundamental.py +0 -0
  158. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/refinitiv/geographic_segment.py +0 -0
  159. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/refinitiv/instrument.py +0 -0
  160. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/refinitiv/instrument_price.py +0 -0
  161. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/refinitiv/mixin.py +0 -0
  162. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/refinitiv/utils/__init__.py +0 -0
  163. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/backends/refinitiv/utils/controller.py +0 -0
  164. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/handlers/__init__.py +0 -0
  165. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/handlers/instrument.py +0 -0
  166. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/handlers/instrument_list.py +0 -0
  167. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/handlers/instrument_price.py +0 -0
  168. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/handlers/option.py +0 -0
  169. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/handlers/private_equities.py +0 -0
  170. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/parsers/__init__.py +0 -0
  171. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/parsers/cbinsights/__init__.py +0 -0
  172. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/parsers/cbinsights/deals.py +0 -0
  173. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/parsers/cbinsights/equities.py +0 -0
  174. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/parsers/cbinsights/fundamentals.py +0 -0
  175. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/parsers/refinitiv/__init__.py +0 -0
  176. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/parsers/refinitiv/daily_fundamental.py +0 -0
  177. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/parsers/refinitiv/forecast.py +0 -0
  178. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/parsers/refinitiv/fundamental.py +0 -0
  179. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/parsers/refinitiv/geographic_segment.py +0 -0
  180. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/parsers/refinitiv/instrument.py +0 -0
  181. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/parsers/refinitiv/instrument_price.py +0 -0
  182. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/parsers/refinitiv/utils.py +0 -0
  183. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/resources/__init__.py +0 -0
  184. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/resources/classification.py +0 -0
  185. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/resources/instrument_prices.py +0 -0
  186. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/import_export/resources/instruments.py +0 -0
  187. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/jinja2.py +0 -0
  188. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/locale/de/LC_MESSAGES/django.mo +0 -0
  189. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/locale/de/LC_MESSAGES/django.po +0 -0
  190. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/locale/en/LC_MESSAGES/django.mo +0 -0
  191. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/locale/en/LC_MESSAGES/django.po +0 -0
  192. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/locale/fr/LC_MESSAGES/django.mo +0 -0
  193. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/locale/fr/LC_MESSAGES/django.po +0 -0
  194. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/management/__init__.py +0 -0
  195. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0001_initial.py +0 -0
  196. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0002_rename_statements_instrumentlookup_financials_and_more.py +0 -0
  197. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0003_instrument_estimate_backend_and_more.py +0 -0
  198. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0004_rename_financials_instrumentlookup_statements_and_more.py +0 -0
  199. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0005_instrument_corporate_action_backend.py +0 -0
  200. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0006_instrument_officer_backend.py +0 -0
  201. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0007_instrument_country_instrument_currency_and_more.py +0 -0
  202. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0008_controversy.py +0 -0
  203. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0009_alter_controversy_flag_alter_controversy_initiated_and_more.py +0 -0
  204. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0010_classification_classificationgroup_deal_exchange_and_more.py +0 -0
  205. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0011_delete_instrumentlookup_instrument_corporate_actions_and_more.py +0 -0
  206. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0012_instrumentprice_created_instrumentprice_modified.py +0 -0
  207. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0013_instrument_is_investable_universe_and_more.py +0 -0
  208. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0014_alter_controversy_instrument.py +0 -0
  209. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0015_instrument_instrument_investible_index.py +0 -0
  210. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0016_instrumenttype_name_repr.py +0 -0
  211. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0017_instrument_instrument_security_index.py +0 -0
  212. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0018_instrument_instrument_level_index.py +0 -0
  213. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0019_alter_controversy_source.py +0 -0
  214. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0020_optionaggregate_option_and_more.py +0 -0
  215. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0021_delete_instrumentdailystatistics.py +0 -0
  216. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0022_instrument_cusip_option_open_interest_20d_and_more.py +0 -0
  217. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0023_instrument_unique_ric_instrument_unique_rmc_and_more.py +0 -0
  218. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0024_option_open_interest_10d_option_volume_10d_and_more.py +0 -0
  219. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0025_instrument_is_primary_and_more.py +0 -0
  220. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0026_instrument_is_cash_equivalent.py +0 -0
  221. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0027_remove_instrument_unique_ric_and_more.py +0 -0
  222. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0028_instrumentprice_annualized_daily_volatility.py +0 -0
  223. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0029_alter_instrumentprice_volume.py +0 -0
  224. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/0030_alter_relatedinstrumentthroughmodel_related_type.py +0 -0
  225. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/migrations/__init__.py +0 -0
  226. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/__init__.py +0 -0
  227. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/esg/__init__.py +0 -0
  228. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/esg/controversies.py +0 -0
  229. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/exchanges/__init__.py +0 -0
  230. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/exchanges/exchanges.py +0 -0
  231. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/fields.py +0 -0
  232. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/fk_fields.py +0 -0
  233. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/indicators.py +0 -0
  234. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/__init__.py +0 -0
  235. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/classifications.py +0 -0
  236. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/instrument_lists.py +0 -0
  237. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/instrument_prices.py +0 -0
  238. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/instrument_relationships.py +0 -0
  239. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/instrument_requests.py +0 -0
  240. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/llm/__init__.py +0 -0
  241. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/llm/create_instrument_news_relationships.py +0 -0
  242. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/mixin/__init__.py +0 -0
  243. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/mixin/financials_computed.py +0 -0
  244. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/mixin/financials_serializer_fields.py +0 -0
  245. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/mixin/instruments.py +0 -0
  246. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/options.py +0 -0
  247. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/private_equities.py +0 -0
  248. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/models/instruments/utils.py +0 -0
  249. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/preferences.py +0 -0
  250. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/serializers/__init__.py +0 -0
  251. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/serializers/esg.py +0 -0
  252. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/serializers/exchanges.py +0 -0
  253. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/serializers/instruments/__init__.py +0 -0
  254. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/serializers/instruments/classifications.py +0 -0
  255. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/serializers/instruments/instrument_lists.py +0 -0
  256. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/serializers/instruments/instrument_prices.py +0 -0
  257. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/serializers/instruments/instrument_relationships.py +0 -0
  258. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/serializers/instruments/instrument_requests.py +0 -0
  259. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/serializers/instruments/instruments.py +0 -0
  260. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/serializers/instruments/mixins.py +0 -0
  261. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/serializers/officers.py +0 -0
  262. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/signals.py +0 -0
  263. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/sync/__init__.py +0 -0
  264. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/sync/abstract.py +0 -0
  265. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/sync/runner.py +0 -0
  266. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tasks.py +0 -0
  267. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/__init__.py +0 -0
  268. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/analysis/__init__.py +0 -0
  269. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/analysis/financial_analysis/__init__.py +0 -0
  270. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/analysis/financial_analysis/test_statement_with_estimates.py +0 -0
  271. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/analysis/financial_analysis/test_utils.py +0 -0
  272. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/analysis/test_esg.py +0 -0
  273. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/conftest.py +0 -0
  274. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/dataloaders/__init__.py +0 -0
  275. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/dataloaders/test_cache.py +0 -0
  276. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/models/__init__.py +0 -0
  277. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/models/test_classifications.py +0 -0
  278. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/models/test_exchanges.py +0 -0
  279. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/models/test_instrument_list.py +0 -0
  280. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/models/test_instrument_prices.py +0 -0
  281. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/models/test_instruments.py +0 -0
  282. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/models/test_merge.py +0 -0
  283. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/models/test_options.py +0 -0
  284. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/test_tasks.py +0 -0
  285. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/tests/tests.py +0 -0
  286. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/urls.py +0 -0
  287. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/utils.py +0 -0
  288. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/__init__.py +0 -0
  289. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/__init__.py +0 -0
  290. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/buttons/__init__.py +0 -0
  291. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/buttons/classifications.py +0 -0
  292. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/buttons/exchanges.py +0 -0
  293. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/buttons/instrument_prices.py +0 -0
  294. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/buttons/instruments.py +0 -0
  295. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/__init__.py +0 -0
  296. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/classifications.py +0 -0
  297. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/esg.py +0 -0
  298. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/exchanges.py +0 -0
  299. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/financial_summary.py +0 -0
  300. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/instrument_lists.py +0 -0
  301. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/instrument_prices.py +0 -0
  302. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/instrument_requests.py +0 -0
  303. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/instruments.py +0 -0
  304. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/instruments_relationships.py +0 -0
  305. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/monthly_performances.py +0 -0
  306. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/officers.py +0 -0
  307. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/prices.py +0 -0
  308. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/statement_with_estimates.py +0 -0
  309. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/display/statements.py +0 -0
  310. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/endpoints/__init__.py +0 -0
  311. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/endpoints/classifications.py +0 -0
  312. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/endpoints/esg.py +0 -0
  313. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/endpoints/exchanges.py +0 -0
  314. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/endpoints/financials_analysis.py +0 -0
  315. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/endpoints/instrument_lists.py +0 -0
  316. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/endpoints/instrument_prices.py +0 -0
  317. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/endpoints/instrument_requests.py +0 -0
  318. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/endpoints/instruments.py +0 -0
  319. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/endpoints/instruments_relationships.py +0 -0
  320. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/endpoints/statements.py +0 -0
  321. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/menus/__init__.py +0 -0
  322. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/menus/classifications.py +0 -0
  323. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/menus/exchanges.py +0 -0
  324. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/menus/instrument_lists.py +0 -0
  325. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/menus/instruments.py +0 -0
  326. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/menus/instruments_relationships.py +0 -0
  327. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/titles/__init__.py +0 -0
  328. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/titles/classifications.py +0 -0
  329. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/titles/esg.py +0 -0
  330. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/titles/exchanges.py +0 -0
  331. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/titles/financial_ratio_analysis.py +0 -0
  332. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/titles/financials_analysis.py +0 -0
  333. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/titles/instrument_prices.py +0 -0
  334. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/titles/instrument_requests.py +0 -0
  335. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/titles/instruments.py +0 -0
  336. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/titles/instruments_relationships.py +0 -0
  337. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/titles/market_data.py +0 -0
  338. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/titles/prices.py +0 -0
  339. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/configs/titles/statement_with_estimates.py +0 -0
  340. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/esg.py +0 -0
  341. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/exchanges.py +0 -0
  342. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/financial_analysis/__init__.py +0 -0
  343. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/financial_analysis/financial_metric_analysis.py +0 -0
  344. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/financial_analysis/financial_ratio_analysis.py +0 -0
  345. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/financial_analysis/financial_summary.py +0 -0
  346. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/financial_analysis/statement_with_estimates.py +0 -0
  347. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/instruments/__init__.py +0 -0
  348. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/instruments/classifications.py +0 -0
  349. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/instruments/financials_analysis.py +0 -0
  350. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/instruments/instrument_lists.py +0 -0
  351. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/instruments/instrument_prices.py +0 -0
  352. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/instruments/instrument_requests.py +0 -0
  353. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/instruments/instruments.py +0 -0
  354. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/instruments/instruments_relationships.py +0 -0
  355. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/instruments/utils.py +0 -0
  356. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/market_data.py +0 -0
  357. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/mixins.py +0 -0
  358. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/officers.py +0 -0
  359. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/prices.py +0 -0
  360. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/statements/__init__.py +0 -0
  361. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/statements/statements.py +0 -0
  362. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/technical_analysis/__init__.py +0 -0
  363. {wbfdm-1.51.7 → wbfdm-1.52.0}/wbfdm/viewsets/technical_analysis/monthly_performances.py +0 -0
@@ -1,9 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wbfdm
3
- Version: 1.51.7
3
+ Version: 1.52.0
4
4
  Summary: The workbench module ensures rapid access to diverse financial data (market, fundamental, forecasts, ESG), with features for storing instruments, classifying them, and conducting financial analysis.
5
5
  Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
6
6
  Requires-Dist: roman==4.*
7
+ Requires-Dist: ruptures==1.1.*
7
8
  Requires-Dist: sentry-sdk==2.*
8
9
  Requires-Dist: stockstats==0.6.*
9
10
  Requires-Dist: wbcore
@@ -10,6 +10,7 @@ dependencies = [
10
10
  "stockstats == 0.6.*",
11
11
  "roman == 4.*",
12
12
  "sentry-sdk == 2.*",
13
+ "ruptures == 1.1.*",
13
14
  ]
14
15
 
15
16
  [project.optional-dependencies]
@@ -0,0 +1,88 @@
1
+ import pandas as pd
2
+ import ruptures as rpt
3
+
4
+
5
+ def outlier_detection(series, z_threshold=3, window=11) -> pd.Series:
6
+ """
7
+ Enhanced detection with volatility-adjusted thresholds and trend validation
8
+ """
9
+ # Compute rolling volatility metrics
10
+ series = series.sort_index().dropna()
11
+
12
+ returns = series.pct_change()
13
+ series = series[returns != 0]
14
+ series = series[series > 0.1] # we exclude penny stock
15
+ rolling_mean = series.rolling(window, center=True).mean()
16
+ rolling_std = series.rolling(window, center=True).std()
17
+ # Calculate Z-scores
18
+ z_scores = (series - rolling_mean) / rolling_std
19
+ candidates = z_scores.abs() > z_threshold
20
+
21
+ return series[candidates]
22
+
23
+
24
+ def statistical_change_point_detection(
25
+ df: pd.Series,
26
+ pen: int = 10,
27
+ model: str = "l2",
28
+ threshold: float = 0.7,
29
+ min_size: int = 30,
30
+ min_threshold: float = 1.0,
31
+ ) -> pd.Series:
32
+ """Detects abnormal changes in a time series using Pelt change point detection.
33
+
34
+ Analyzes a pandas Series using ruptures' Pelt algorithm to identify statistical
35
+ change points, then validates them using percentage change and minimum value thresholds.
36
+
37
+ Args:
38
+ df: Input time series as pandas Series. Should be numeric and ordered by time.
39
+ pen: Penalty value for change point detection (higher values reduce sensitivity).
40
+ Default: 5.
41
+ model: Cost function model for change point detection. Supported values:
42
+ 'l1' (least absolute deviation), 'l2' (least squared deviation).
43
+ Default: 'l1'.
44
+ threshold: Minimum percentage change (0-1) between consecutive segments to
45
+ consider as abnormal. Default: 0.7 (70%).
46
+ min_size: Minimum number of samples between change points. Default: 30.
47
+ min_threshold: Minimum mean value required in both segments to validate
48
+ a change point (avoids flagging low-value fluctuations). Default: 1.0.
49
+
50
+ Returns:
51
+ tuple[bool, list[int]]: Contains:
52
+ - bool: True if any validated abnormal changes detected
53
+ - list[int]: Indices of validated change points (empty if none)
54
+
55
+ Example:
56
+ >>> ts = pd.Series([1.0, 1.1, 1.2, 3.0, 3.1, 3.2])
57
+ >>> detected, points = detect_abnormal_changes(ts, threshold=0.5)
58
+ >>> print(detected, points)
59
+ True [3]
60
+
61
+ Note:
62
+ Base on https://medium.com/@enginsorhun/decoding-market-shifts-detecting-structural-breaks-ii-2b77bdafd064.
63
+ """
64
+ changes = []
65
+
66
+ if len(df) < min_size:
67
+ return df.iloc[changes]
68
+
69
+ df = df.sort_index()
70
+
71
+ # Initialize and fit Pelt model
72
+ algo = rpt.Pelt(model=model, min_size=min_size).fit(df.values)
73
+ change_points = algo.predict(pen=pen)
74
+
75
+ # If no changes detected
76
+ if len(change_points) == 0:
77
+ return (False, [])
78
+
79
+ # Calculate percentage changes between segments
80
+ segments = [1] + change_points
81
+
82
+ for i in range(1, len(segments) - 1):
83
+ previous_segment = df.iloc[segments[i - 1] : segments[i] - 1].mean()
84
+ next_segment = df.iloc[segments[i] : segments[i + 1] - 1].mean()
85
+ pct_change = abs(next_segment - previous_segment) / previous_segment
86
+ if next_segment > min_threshold and previous_segment > min_threshold and pct_change > threshold:
87
+ changes.append(segments[i])
88
+ return df.iloc[changes]
@@ -1,8 +1,10 @@
1
+ import logging
1
2
  import re
2
3
  from contextlib import suppress
3
4
  from datetime import date, timedelta
4
5
  from typing import Any, Generator, Iterator, Self, TypeVar
5
6
 
7
+ import pandas as pd
6
8
  from celery import shared_task
7
9
  from colorfield.fields import ColorField
8
10
  from django.contrib import admin
@@ -44,14 +46,18 @@ from wbfdm.preferences import get_default_classification_group
44
46
  from wbfdm.signals import (
45
47
  add_instrument_to_investable_universe,
46
48
  instrument_price_imported,
49
+ investable_universe_updated,
47
50
  )
48
51
 
52
+ from ...analysis.financial_analysis.change_point_detection import outlier_detection, statistical_change_point_detection
49
53
  from ...dataloaders.proxies import InstrumentDataloaderProxy
50
54
  from .instrument_relationships import RelatedInstrumentThroughModel
51
55
  from .mixin.instruments import InstrumentPMSMixin
52
56
  from .querysets import InstrumentQuerySet
53
57
  from .utils import re_bloomberg, re_isin, re_mnemonic, re_ric
54
58
 
59
+ logger = logging.getLogger("pms")
60
+
55
61
 
56
62
  class InstrumentManager(TreeManager):
57
63
  def __init__(self, with_annotation: bool = False, *args, **kwargs):
@@ -1007,3 +1013,73 @@ class Equity(Instrument):
1007
1013
  @receiver(create_news_relationships, sender="wbnews.News")
1008
1014
  def get_news_relationships_for_instruments_task(sender: type, instance: "News", **kwargs) -> shared_task:
1009
1015
  return run_company_extraction_llm.s(instance.title, instance.description, instance.summary)
1016
+
1017
+
1018
+ @shared_task(queue="pms")
1019
+ def detect_and_correct_financial_timeseries(
1020
+ max_days_interval: int | None = None,
1021
+ check_date: date | None = None,
1022
+ with_pelt: bool = False,
1023
+ detect_only: bool = False,
1024
+ full_reimport: bool = False,
1025
+ debug: bool = False,
1026
+ ):
1027
+ """Detects and corrects anomalies in financial time series data for instruments.
1028
+
1029
+ Analyzes price data using statistical methods to identify outliers and change points,
1030
+ then triggers price reimport for affected date ranges when corrections are needed.
1031
+
1032
+ Args:
1033
+ max_days_interval: Maximum lookback window in days for analysis (None = all history)
1034
+ check_date: Reference date for analysis (defaults to current date)
1035
+ with_pelt: Enable Pelt's change point detection alongside basic z-score outlier detection
1036
+ detect_only: Run detection without performing data correction/reimport
1037
+ full_reimport: Reimport entire price history when corruption detected (requires max_days_interval=None)
1038
+ debug: Show progress bar during instrument processing
1039
+
1040
+ """
1041
+ if not check_date:
1042
+ check_date = date.today()
1043
+ gen = (
1044
+ Instrument.investable_universe.filter(is_managed=False)
1045
+ .filter_active_at_date(check_date)
1046
+ .exclude(source="dsws")
1047
+ )
1048
+ if debug:
1049
+ gen = tqdm(gen, total=gen.count())
1050
+ for instrument in gen:
1051
+ prices = instrument.valuations.all()
1052
+ if max_days_interval:
1053
+ prices = prices.filter(date__gte=check_date - timedelta(days=max_days_interval))
1054
+ # construct the price timeseries
1055
+ prices_series = (
1056
+ pd.DataFrame(
1057
+ prices.filter_only_valid_prices().values_list("date", "net_value"), columns=["date", "net_value"]
1058
+ )
1059
+ .set_index("date")["net_value"]
1060
+ .astype(float)
1061
+ .sort_index()
1062
+ )
1063
+ if not prices_series.empty:
1064
+ outliers = outlier_detection(prices_series).index.tolist()
1065
+ # if pelt enable, add the outliers found by the PELT model
1066
+ if with_pelt:
1067
+ outliers.extend(statistical_change_point_detection(prices_series).index.tolist())
1068
+ if outliers:
1069
+ logger.info(f"Abnormal change point detected for {instrument} at {outliers}.")
1070
+ if not detect_only:
1071
+ # for a full reimport, we delete the whole existing price series and reimport since inception
1072
+ if full_reimport and not max_days_interval:
1073
+ start_import_date = instrument.inception_date
1074
+ end_import_date = check_date
1075
+ instrument.prices.filter(assets__isnull=True).delete()
1076
+ else:
1077
+ start_import_date = min(outliers) - timedelta(days=7)
1078
+ end_import_date = max(outliers) + timedelta(days=7)
1079
+ logger.info(f"Reimporting price from {start_import_date} to {end_import_date}...")
1080
+ instrument.import_prices(start=start_import_date, end=end_import_date)
1081
+
1082
+
1083
+ @receiver(investable_universe_updated, sender="wbfdm.Instrument")
1084
+ def investable_universe_change_point_detection(*args, end_date: date | None = None, **kwargs):
1085
+ detect_and_correct_financial_timeseries.delay(check_date=end_date, max_days_interval=365)
@@ -5,7 +5,7 @@ from decimal import Decimal
5
5
 
6
6
  import numpy as np
7
7
  import pandas as pd
8
- from django.core.exceptions import ValidationError
8
+ from django.core.exceptions import MultipleObjectsReturned, ValidationError
9
9
  from django.core.validators import DecimalValidator
10
10
  from django.db.models import (
11
11
  AutoField,
@@ -103,9 +103,12 @@ class InstrumentQuerySet(QuerySet):
103
103
  validator(close)
104
104
  try:
105
105
  try:
106
- p = InstrumentPrice.objects.get(instrument=instrument, date=price_date, calculated=False)
107
- except InstrumentPrice.DoesNotExist:
108
- p = InstrumentPrice.objects.get(instrument=instrument, date=price_date, calculated=True)
106
+ InstrumentPrice.objects.get(instrument=instrument, date=price_date)
107
+ except MultipleObjectsReturned:
108
+ InstrumentPrice.objects.get(
109
+ instrument=instrument, date=price_date, calculated=False
110
+ ).delete()
111
+ p = InstrumentPrice.objects.get(instrument=instrument, date=price_date)
109
112
  p.net_value = close
110
113
  p.gross_value = close
111
114
  p.calculated = row["calculated"]
@@ -160,11 +163,13 @@ class InstrumentQuerySet(QuerySet):
160
163
  )
161
164
 
162
165
  dff = dff.reindex(pd.date_range(dff.index.min(), dff.index.max(), freq="B"))
166
+
163
167
  dff[["close", "market_capitalization"]] = dff[["close", "market_capitalization"]].astype(float).ffill()
164
168
  dff.volume = dff.volume.astype(float).fillna(0)
165
169
  dff.calculated = dff.calculated.astype(bool).fillna(
166
170
  True
167
171
  ) # we do not ffill calculated but set the to True to mark them as "estimated"/"not real"
172
+
168
173
  dff = dff.reset_index(names="date").dropna(subset=["close"])
169
174
  dff = dff.replace([np.inf, -np.inf, np.nan], None)
170
175
  instrument = self.get(id=instrument_id)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes