wbfdm 1.43.2__tar.gz → 1.44.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 (358) hide show
  1. {wbfdm-1.43.2 → wbfdm-1.44.0}/PKG-INFO +3 -1
  2. {wbfdm-1.43.2 → wbfdm-1.44.0}/pyproject.toml +3 -0
  3. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/financial_analysis/utils.py +3 -1
  4. wbfdm-1.44.0/wbfdm/contrib/qa/dataloaders/adjustments.py +69 -0
  5. wbfdm-1.44.0/wbfdm/contrib/qa/dataloaders/corporate_actions.py +69 -0
  6. wbfdm-1.44.0/wbfdm/contrib/qa/dataloaders/market_data.py +142 -0
  7. wbfdm-1.44.0/wbfdm/contrib/qa/dataloaders/officers.py +74 -0
  8. wbfdm-1.44.0/wbfdm/contrib/qa/dataloaders/utils.py +22 -0
  9. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/dataloaders/protocols.py +11 -18
  10. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/dataloaders/proxies.py +1 -1
  11. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/dataloaders/types.py +3 -0
  12. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/enums.py +3 -3
  13. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/serializers/instruments/instruments.py +1 -0
  14. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/analysis/financial_analysis/test_statement_with_estimates.py +1 -1
  15. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/urls.py +1 -0
  16. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/buttons/instruments.py +1 -1
  17. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/__init__.py +1 -0
  18. wbfdm-1.44.0/wbfdm/viewsets/configs/display/financial_summary.py +133 -0
  19. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/instruments.py +11 -12
  20. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/financial_analysis/__init__.py +1 -0
  21. wbfdm-1.44.0/wbfdm/viewsets/financial_analysis/financial_summary.py +256 -0
  22. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/mixins.py +2 -0
  23. wbfdm-1.43.2/wbfdm/contrib/qa/dataloaders/adjustments.py +0 -56
  24. wbfdm-1.43.2/wbfdm/contrib/qa/dataloaders/corporate_actions.py +0 -59
  25. wbfdm-1.43.2/wbfdm/contrib/qa/dataloaders/market_data.py +0 -117
  26. wbfdm-1.43.2/wbfdm/contrib/qa/dataloaders/officers.py +0 -59
  27. {wbfdm-1.43.2 → wbfdm-1.44.0}/.gitignore +0 -0
  28. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/__init__.py +0 -0
  29. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/admin/__init__.py +0 -0
  30. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/admin/classifications.py +0 -0
  31. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/admin/esg.py +0 -0
  32. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/admin/exchanges.py +0 -0
  33. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/admin/instrument_lists.py +0 -0
  34. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/admin/instrument_prices.py +0 -0
  35. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/admin/instrument_requests.py +0 -0
  36. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/admin/instruments.py +0 -0
  37. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/admin/instruments_relationships.py +0 -0
  38. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/admin/options.py +0 -0
  39. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/__init__.py +0 -0
  40. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/esg/__init__.py +0 -0
  41. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/esg/enums.py +0 -0
  42. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/esg/esg_analysis.py +0 -0
  43. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/esg/utils.py +0 -0
  44. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/financial_analysis/__init__.py +0 -0
  45. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/financial_analysis/financial_metric_analysis.py +0 -0
  46. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/financial_analysis/financial_ratio_analysis.py +0 -0
  47. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/financial_analysis/financial_statistics_analysis.py +0 -0
  48. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/financial_analysis/statement_with_estimates.py +0 -0
  49. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/technical_analysis/__init__.py +0 -0
  50. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/technical_analysis/technical_analysis.py +0 -0
  51. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/technical_analysis/traces.py +0 -0
  52. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/analysis/utils.py +0 -0
  53. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/apps.py +0 -0
  54. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/backends/dto.py +0 -0
  55. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/__init__.py +0 -0
  56. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/dsws/__init__.py +0 -0
  57. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/dsws/client.py +0 -0
  58. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/dsws/dataloaders/market_data.py +0 -0
  59. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/internal/__init__.py +0 -0
  60. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/internal/dataloaders/__init__.py +0 -0
  61. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/internal/dataloaders/market_data.py +0 -0
  62. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/__init__.py +0 -0
  63. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/admin/__init__.py +0 -0
  64. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/admin/instruments.py +0 -0
  65. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/admin/metrics.py +0 -0
  66. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/apps.py +0 -0
  67. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/backends/__init__.py +0 -0
  68. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/backends/base.py +0 -0
  69. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/backends/performances.py +0 -0
  70. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/backends/statistics.py +0 -0
  71. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/decorators.py +0 -0
  72. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/dispatch.py +0 -0
  73. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/dto.py +0 -0
  74. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/exceptions.py +0 -0
  75. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/factories.py +0 -0
  76. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/filters.py +0 -0
  77. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/migrations/0001_initial.py +0 -0
  78. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/migrations/0002_remove_instrumentmetric_unique_instrument_metric_and_more.py +0 -0
  79. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/migrations/__init__.py +0 -0
  80. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/models.py +0 -0
  81. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/orchestrators.py +0 -0
  82. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/registry.py +0 -0
  83. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/serializers.py +0 -0
  84. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/tasks.py +0 -0
  85. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/tests/__init__.py +0 -0
  86. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/tests/backends/__init__.py +0 -0
  87. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/tests/backends/test_performances.py +0 -0
  88. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/tests/backends/test_statistics.py +0 -0
  89. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/tests/conftest.py +0 -0
  90. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/tests/test_dto.py +0 -0
  91. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/tests/test_models.py +0 -0
  92. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/tests/test_tasks.py +0 -0
  93. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/tests/test_viewsets.py +0 -0
  94. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/urls.py +0 -0
  95. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/viewsets/__init__.py +0 -0
  96. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/viewsets/configs/__init__.py +0 -0
  97. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/viewsets/configs/display.py +0 -0
  98. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/viewsets/configs/menus.py +0 -0
  99. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/viewsets/configs/utils.py +0 -0
  100. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/viewsets/mixins.py +0 -0
  101. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/metric/viewsets/viewsets.py +0 -0
  102. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/msci/__init__.py +0 -0
  103. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/msci/client.py +0 -0
  104. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/msci/dataloaders/__init__.py +0 -0
  105. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/msci/dataloaders/esg.py +0 -0
  106. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/msci/dataloaders/esg_controversies.py +0 -0
  107. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/msci/sync.py +0 -0
  108. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/msci/tests/__init__.py +0 -0
  109. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/msci/tests/conftest.py +0 -0
  110. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/msci/tests/test_client.py +0 -0
  111. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/__init__.py +0 -0
  112. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/apps.py +0 -0
  113. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/database_routers.py +0 -0
  114. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/dataloaders/__init__.py +0 -0
  115. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/dataloaders/financials.py +0 -0
  116. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/dataloaders/reporting_dates.py +0 -0
  117. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/dataloaders/statements.py +0 -0
  118. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/jinja2/qa/sql/companies.sql +0 -0
  119. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/base_estimates.sql +0 -0
  120. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/calendarized.sql +0 -0
  121. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/complete.sql +0 -0
  122. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/estimates.sql +0 -0
  123. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/financials.sql +0 -0
  124. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/jinja2/qa/sql/instruments.sql +0 -0
  125. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/jinja2/qa/sql/quotes.sql +0 -0
  126. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/sync/exchanges.py +0 -0
  127. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/sync/instruments.py +0 -0
  128. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/sync/utils.py +0 -0
  129. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/contrib/qa/tasks.py +0 -0
  130. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/dataloaders/__init__.py +0 -0
  131. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/dataloaders/cache.py +0 -0
  132. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/dynamic_preferences_registry.py +0 -0
  133. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/factories/__init__.py +0 -0
  134. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/factories/classifications.py +0 -0
  135. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/factories/controversies.py +0 -0
  136. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/factories/exchanges.py +0 -0
  137. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/factories/instrument_list.py +0 -0
  138. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/factories/instrument_prices.py +0 -0
  139. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/factories/instruments.py +0 -0
  140. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/factories/instruments_relationships.py +0 -0
  141. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/factories/options.py +0 -0
  142. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/figures/__init__.py +0 -0
  143. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/figures/financials/__init__.py +0 -0
  144. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/figures/financials/financial_analysis_charts.py +0 -0
  145. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/figures/financials/financials_charts.py +0 -0
  146. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/filters/__init__.py +0 -0
  147. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/filters/classifications.py +0 -0
  148. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/filters/exchanges.py +0 -0
  149. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/filters/financials.py +0 -0
  150. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/filters/financials_analysis.py +0 -0
  151. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/filters/instrument_prices.py +0 -0
  152. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/filters/instruments.py +0 -0
  153. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/filters/utils.py +0 -0
  154. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/__init__.py +0 -0
  155. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/__init__.py +0 -0
  156. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/cbinsights/__init__.py +0 -0
  157. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/cbinsights/deals.py +0 -0
  158. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/cbinsights/equities.py +0 -0
  159. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/cbinsights/mixin.py +0 -0
  160. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/cbinsights/utils/__init__.py +0 -0
  161. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/cbinsights/utils/classifications.py +0 -0
  162. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/cbinsights/utils/client.py +0 -0
  163. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/refinitiv/__init__.py +0 -0
  164. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/refinitiv/daily_fundamental.py +0 -0
  165. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/refinitiv/fiscal_period.py +0 -0
  166. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/refinitiv/forecast.py +0 -0
  167. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/refinitiv/fundamental.py +0 -0
  168. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/refinitiv/geographic_segment.py +0 -0
  169. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/refinitiv/instrument.py +0 -0
  170. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/refinitiv/instrument_price.py +0 -0
  171. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/refinitiv/mixin.py +0 -0
  172. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/refinitiv/utils/__init__.py +0 -0
  173. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/backends/refinitiv/utils/controller.py +0 -0
  174. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/handlers/__init__.py +0 -0
  175. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/handlers/instrument.py +0 -0
  176. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/handlers/instrument_list.py +0 -0
  177. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/handlers/instrument_price.py +0 -0
  178. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/handlers/option.py +0 -0
  179. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/handlers/private_equities.py +0 -0
  180. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/parsers/__init__.py +0 -0
  181. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/parsers/cbinsights/__init__.py +0 -0
  182. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/parsers/cbinsights/deals.py +0 -0
  183. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/parsers/cbinsights/equities.py +0 -0
  184. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/parsers/cbinsights/fundamentals.py +0 -0
  185. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/parsers/refinitiv/__init__.py +0 -0
  186. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/parsers/refinitiv/daily_fundamental.py +0 -0
  187. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/parsers/refinitiv/forecast.py +0 -0
  188. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/parsers/refinitiv/fundamental.py +0 -0
  189. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/parsers/refinitiv/geographic_segment.py +0 -0
  190. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/parsers/refinitiv/instrument.py +0 -0
  191. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/parsers/refinitiv/instrument_price.py +0 -0
  192. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/parsers/refinitiv/utils.py +0 -0
  193. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/resources/__init__.py +0 -0
  194. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/resources/classification.py +0 -0
  195. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/resources/instrument_prices.py +0 -0
  196. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/import_export/resources/instruments.py +0 -0
  197. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/jinja2.py +0 -0
  198. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/management/__init__.py +0 -0
  199. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/menu.py +0 -0
  200. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0001_initial.py +0 -0
  201. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0002_rename_statements_instrumentlookup_financials_and_more.py +0 -0
  202. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0003_instrument_estimate_backend_and_more.py +0 -0
  203. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0004_rename_financials_instrumentlookup_statements_and_more.py +0 -0
  204. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0005_instrument_corporate_action_backend.py +0 -0
  205. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0006_instrument_officer_backend.py +0 -0
  206. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0007_instrument_country_instrument_currency_and_more.py +0 -0
  207. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0008_controversy.py +0 -0
  208. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0009_alter_controversy_flag_alter_controversy_initiated_and_more.py +0 -0
  209. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0010_classification_classificationgroup_deal_exchange_and_more.py +0 -0
  210. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0011_delete_instrumentlookup_instrument_corporate_actions_and_more.py +0 -0
  211. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0012_instrumentprice_created_instrumentprice_modified.py +0 -0
  212. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0013_instrument_is_investable_universe_and_more.py +0 -0
  213. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0014_alter_controversy_instrument.py +0 -0
  214. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0015_instrument_instrument_investible_index.py +0 -0
  215. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0016_instrumenttype_name_repr.py +0 -0
  216. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0017_instrument_instrument_security_index.py +0 -0
  217. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0018_instrument_instrument_level_index.py +0 -0
  218. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0019_alter_controversy_source.py +0 -0
  219. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0020_optionaggregate_option_and_more.py +0 -0
  220. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0021_delete_instrumentdailystatistics.py +0 -0
  221. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0022_instrument_cusip_option_open_interest_20d_and_more.py +0 -0
  222. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0023_instrument_unique_ric_instrument_unique_rmc_and_more.py +0 -0
  223. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0024_option_open_interest_10d_option_volume_10d_and_more.py +0 -0
  224. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0025_instrument_is_primary_and_more.py +0 -0
  225. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0026_instrument_is_cash_equivalent.py +0 -0
  226. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0027_remove_instrument_unique_ric_and_more.py +0 -0
  227. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/0028_instrumentprice_annualized_daily_volatility.py +0 -0
  228. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/migrations/__init__.py +0 -0
  229. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/__init__.py +0 -0
  230. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/esg/__init__.py +0 -0
  231. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/esg/controversies.py +0 -0
  232. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/exchanges/__init__.py +0 -0
  233. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/exchanges/exchanges.py +0 -0
  234. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/fields.py +0 -0
  235. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/fk_fields.py +0 -0
  236. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/indicators.py +0 -0
  237. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/__init__.py +0 -0
  238. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/classifications.py +0 -0
  239. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/instrument_lists.py +0 -0
  240. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/instrument_prices.py +0 -0
  241. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/instrument_relationships.py +0 -0
  242. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/instrument_requests.py +0 -0
  243. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/instruments.py +0 -0
  244. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/llm/__init__.py +0 -0
  245. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/llm/create_instrument_news_relationships.py +0 -0
  246. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/mixin/__init__.py +0 -0
  247. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/mixin/financials_computed.py +0 -0
  248. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/mixin/financials_serializer_fields.py +0 -0
  249. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/mixin/instruments.py +0 -0
  250. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/options.py +0 -0
  251. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/private_equities.py +0 -0
  252. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/querysets.py +0 -0
  253. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/models/instruments/utils.py +0 -0
  254. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/preferences.py +0 -0
  255. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/serializers/__init__.py +0 -0
  256. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/serializers/esg.py +0 -0
  257. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/serializers/exchanges.py +0 -0
  258. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/serializers/instruments/__init__.py +0 -0
  259. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/serializers/instruments/classifications.py +0 -0
  260. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/serializers/instruments/instrument_lists.py +0 -0
  261. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/serializers/instruments/instrument_prices.py +0 -0
  262. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/serializers/instruments/instrument_relationships.py +0 -0
  263. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/serializers/instruments/instrument_requests.py +0 -0
  264. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/serializers/instruments/mixins.py +0 -0
  265. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/serializers/officers.py +0 -0
  266. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/signals.py +0 -0
  267. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/sync/__init__.py +0 -0
  268. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/sync/abstract.py +0 -0
  269. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/sync/runner.py +0 -0
  270. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tasks.py +0 -0
  271. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/__init__.py +0 -0
  272. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/analysis/__init__.py +0 -0
  273. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/analysis/financial_analysis/__init__.py +0 -0
  274. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/analysis/financial_analysis/test_utils.py +0 -0
  275. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/analysis/test_esg.py +0 -0
  276. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/conftest.py +0 -0
  277. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/dataloaders/__init__.py +0 -0
  278. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/dataloaders/test_cache.py +0 -0
  279. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/models/__init__.py +0 -0
  280. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/models/test_classifications.py +0 -0
  281. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/models/test_exchanges.py +0 -0
  282. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/models/test_instrument_list.py +0 -0
  283. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/models/test_instrument_prices.py +0 -0
  284. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/models/test_instruments.py +0 -0
  285. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/models/test_merge.py +0 -0
  286. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/models/test_options.py +0 -0
  287. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/test_tasks.py +0 -0
  288. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/tests/tests.py +0 -0
  289. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/utils.py +0 -0
  290. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/__init__.py +0 -0
  291. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/__init__.py +0 -0
  292. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/buttons/__init__.py +0 -0
  293. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/buttons/classifications.py +0 -0
  294. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/buttons/exchanges.py +0 -0
  295. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/buttons/instrument_prices.py +0 -0
  296. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/classifications.py +0 -0
  297. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/esg.py +0 -0
  298. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/exchanges.py +0 -0
  299. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/instrument_lists.py +0 -0
  300. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/instrument_prices.py +0 -0
  301. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/instrument_requests.py +0 -0
  302. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/instruments_relationships.py +0 -0
  303. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/monthly_performances.py +0 -0
  304. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/officers.py +0 -0
  305. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/prices.py +0 -0
  306. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/statement_with_estimates.py +0 -0
  307. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/display/statements.py +0 -0
  308. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/endpoints/__init__.py +0 -0
  309. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/endpoints/classifications.py +0 -0
  310. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/endpoints/esg.py +0 -0
  311. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/endpoints/exchanges.py +0 -0
  312. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/endpoints/financials_analysis.py +0 -0
  313. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/endpoints/instrument_lists.py +0 -0
  314. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/endpoints/instrument_prices.py +0 -0
  315. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/endpoints/instrument_requests.py +0 -0
  316. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/endpoints/instruments.py +0 -0
  317. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/endpoints/instruments_relationships.py +0 -0
  318. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/endpoints/statements.py +0 -0
  319. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/menus/__init__.py +0 -0
  320. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/menus/classifications.py +0 -0
  321. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/menus/exchanges.py +0 -0
  322. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/menus/instrument_lists.py +0 -0
  323. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/menus/instruments.py +0 -0
  324. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/menus/instruments_relationships.py +0 -0
  325. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/titles/__init__.py +0 -0
  326. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/titles/classifications.py +0 -0
  327. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/titles/esg.py +0 -0
  328. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/titles/exchanges.py +0 -0
  329. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/titles/financial_ratio_analysis.py +0 -0
  330. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/titles/financials_analysis.py +0 -0
  331. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/titles/instrument_prices.py +0 -0
  332. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/titles/instrument_requests.py +0 -0
  333. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/titles/instruments.py +0 -0
  334. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/titles/instruments_relationships.py +0 -0
  335. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/titles/market_data.py +0 -0
  336. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/titles/prices.py +0 -0
  337. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/configs/titles/statement_with_estimates.py +0 -0
  338. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/esg.py +0 -0
  339. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/exchanges.py +0 -0
  340. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/financial_analysis/financial_metric_analysis.py +0 -0
  341. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/financial_analysis/financial_ratio_analysis.py +0 -0
  342. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/financial_analysis/statement_with_estimates.py +0 -0
  343. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/instruments/__init__.py +0 -0
  344. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/instruments/classifications.py +0 -0
  345. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/instruments/financials_analysis.py +0 -0
  346. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/instruments/instrument_lists.py +0 -0
  347. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/instruments/instrument_prices.py +0 -0
  348. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/instruments/instrument_requests.py +0 -0
  349. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/instruments/instruments.py +0 -0
  350. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/instruments/instruments_relationships.py +0 -0
  351. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/instruments/utils.py +0 -0
  352. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/market_data.py +0 -0
  353. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/officers.py +0 -0
  354. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/prices.py +0 -0
  355. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/statements/__init__.py +0 -0
  356. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/statements/statements.py +0 -0
  357. {wbfdm-1.43.2 → wbfdm-1.44.0}/wbfdm/viewsets/technical_analysis/__init__.py +0 -0
  358. {wbfdm-1.43.2 → wbfdm-1.44.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.43.2
3
+ Version: 1.44.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: sentry-sdk==2.*
7
8
  Requires-Dist: stockstats==0.6.*
8
9
  Requires-Dist: wbcore
9
10
  Requires-Dist: wbnews
@@ -13,3 +14,4 @@ Requires-Dist: requests-cache==1.0.*; extra == 'dsws'
13
14
  Provides-Extra: qa
14
15
  Requires-Dist: jinjasql2==0.1.*; extra == 'qa'
15
16
  Requires-Dist: mssql-django==1.4.*; extra == 'qa'
17
+ Requires-Dist: pypika; extra == 'qa'
@@ -9,12 +9,14 @@ dependencies = [
9
9
  "wbnews",
10
10
  "stockstats == 0.6.*",
11
11
  "roman == 4.*",
12
+ "sentry-sdk == 2.*",
12
13
  ]
13
14
 
14
15
  [project.optional-dependencies]
15
16
  qa = [
16
17
  "mssql-django == 1.4.*",
17
18
  "jinjasql2 == 0.1.*",
19
+ "pypika",
18
20
  ]
19
21
  dsws = [
20
22
  "requests-cache == 1.0.*",
@@ -24,6 +26,7 @@ dsws = [
24
26
  [tool.uv.sources]
25
27
  wbcore = { workspace = true }
26
28
  wbnews = { workspace = true }
29
+ pypika = { git = "https://github.com/kayak/pypika.git" }
27
30
 
28
31
  [tool.uv]
29
32
  package = true
@@ -25,6 +25,7 @@ class Loader:
25
25
  calendar_type: CalendarType = CalendarType.FISCAL,
26
26
  market_data_values: list[MarketData] | None = None,
27
27
  statement_values: list[Financial] | None = None,
28
+ period_type: PeriodType = PeriodType.ALL,
28
29
  ):
29
30
  self.instrument = instrument
30
31
  self.calendar_type = calendar_type
@@ -35,6 +36,7 @@ class Loader:
35
36
  self.statement_values = (
36
37
  statement_values # specify if any extra statement needs to be merged into the dataframe
37
38
  )
39
+ self.period_type = period_type
38
40
  self.errors: dict[str, list[str]] = defaultdict(list)
39
41
 
40
42
  def load(self) -> pd.DataFrame:
@@ -54,9 +56,9 @@ class Loader:
54
56
  df = pd.DataFrame(
55
57
  Instrument.objects.filter(id=self.instrument.id).dl.financials(
56
58
  values=self.values,
57
- period_type=PeriodType.ALL,
58
59
  from_year=date.today().year - 5,
59
60
  calendar_type=self.calendar_type,
61
+ period_type=self.period_type,
60
62
  )
61
63
  )
62
64
  if df.empty:
@@ -0,0 +1,69 @@
1
+ from contextlib import suppress
2
+ from datetime import date
3
+ from itertools import batched
4
+ from typing import Iterator
5
+
6
+ from django.db import ProgrammingError, connections
7
+ from wbcore.contrib.dataloader.dataloaders import Dataloader
8
+ from wbcore.contrib.dataloader.utils import dictfetchall
9
+ from wbfdm.contrib.qa.dataloaders.utils import SOURCE_DS2
10
+ from wbfdm.dataloaders.protocols import AdjustmentsProtocol
11
+ from wbfdm.dataloaders.types import AdjustmentDataDict
12
+
13
+ import pypika as pk
14
+ from pypika import functions as fn
15
+ from pypika.enums import SqlTypes, Order
16
+ from pypika.terms import LiteralValue
17
+
18
+
19
+ class DatastreamAdjustmentsDataloader(AdjustmentsProtocol, Dataloader):
20
+ def adjustments(self, from_date: date | None = None, to_date: date | None = None) -> Iterator[AdjustmentDataDict]:
21
+ lookup = {k: v for k, v in self.entities.values_list("dl_parameters__adjustments__parameters", "id")}
22
+
23
+ adj = pk.Table("DS2Adj")
24
+ adj_date = fn.Cast(adj.AdjDate, SqlTypes.DATE).as_("adjustment_date")
25
+ adj_end_date = fn.Cast(adj.EndAdjDate, SqlTypes.DATE).as_("adjustment_end_date")
26
+
27
+ infocode = pk.Table("#ds2infocode")
28
+
29
+ query = (
30
+ pk.MSSQLQuery.select(
31
+ adj.InfoCode.as_("external_identifier"),
32
+ fn.Concat(adj.InfoCode, "_", adj_date).as_("id"),
33
+ adj_date,
34
+ adj_end_date,
35
+ SOURCE_DS2,
36
+ adj.AdjFactor.as_("adjustment_factor"),
37
+ adj.CumAdjFactor.as_("cumulative_adjustement_factor"),
38
+ )
39
+ .from_(adj)
40
+ .where(adj.AdjType == 2)
41
+ .where(adj.InfoCode.isin([LiteralValue("select infocode from #ds2infocode")]))
42
+ .orderby(adj.AdjDate, order=Order.desc)
43
+ )
44
+
45
+ if from_date:
46
+ query = query.where(adj.AdjDate >= from_date)
47
+
48
+ if to_date:
49
+ query = query.where(adj.AdjDate <= to_date)
50
+
51
+ with connections["qa"].cursor() as cursor:
52
+ # we suppress an error here, because if the temporary table already exists
53
+ # then we do not want to fail. It should not fail, but if a previous run did
54
+ # not clean up the table properly, then at least we do not get stuck here
55
+ with suppress(ProgrammingError):
56
+ cursor.execute(
57
+ pk.MSSQLQuery.create_table(infocode).columns(pk.Column("infocode", SqlTypes.INTEGER)).get_sql()
58
+ )
59
+ for batch in batched(lookup.keys(), 1000):
60
+ cursor.execute(f"insert into #ds2infocode values {",".join(map(lambda x: f"({x})", batch))};")
61
+
62
+ cursor.execute(query.get_sql())
63
+
64
+ for row in dictfetchall(cursor, AdjustmentDataDict):
65
+ row["instrument_id"] = lookup[row["external_identifier"]]
66
+ yield row
67
+
68
+ # here we remove the temporary table again to avoid data spillage
69
+ # cursor.execute(pk.MSSQLQuery.drop_table(infocode).get_sql())
@@ -0,0 +1,69 @@
1
+ from contextlib import suppress
2
+ from datetime import date
3
+ from itertools import batched
4
+ from typing import Iterator
5
+
6
+ from django.db import ProgrammingError, connections
7
+ from wbcore.contrib.dataloader.dataloaders import Dataloader
8
+ from wbcore.contrib.dataloader.utils import dictfetchall
9
+ from wbfdm.contrib.qa.dataloaders.utils import SOURCE_DS2
10
+ from wbfdm.dataloaders.protocols import CorporateActionsProtocol
11
+ from wbfdm.dataloaders.types import CorporateActionDataDict
12
+
13
+ import pypika as pk
14
+ from pypika import functions as fn
15
+ from pypika.enums import SqlTypes
16
+ from pypika.terms import LiteralValue
17
+
18
+
19
+ class DatastreamCorporateActionsDataloader(CorporateActionsProtocol, Dataloader):
20
+ def corporate_actions(
21
+ self,
22
+ from_date: date | None = None,
23
+ to_date: date | None = None,
24
+ ) -> Iterator[CorporateActionDataDict]:
25
+ lookup = {k: v for k, v in self.entities.values_list("dl_parameters__corporate_actions__parameters", "id")}
26
+
27
+ cap_event = pk.Table("Ds2CapEvent")
28
+ effective_date = fn.Cast(cap_event.EffectiveDate, SqlTypes.DATE)
29
+ infocode = pk.Table("#ds2infocode")
30
+
31
+ query = (
32
+ pk.MSSQLQuery.select(
33
+ cap_event.InfoCode.as_("external_identifier"),
34
+ fn.Concat(cap_event.InfoCode, "_", effective_date).as_("id"),
35
+ effective_date.as_("valuation_date"),
36
+ SOURCE_DS2,
37
+ cap_event.ActionTypeCode.as_("action_code"),
38
+ cap_event.EventStatusCode.as_("event_code"),
39
+ cap_event.NumOldShares.as_("old_shares"),
40
+ cap_event.NumNewShares.as_("new_shares"),
41
+ cap_event.ISOCurrCode.as_("currency"),
42
+ )
43
+ .from_(cap_event)
44
+ .where(cap_event.InfoCode.isin([LiteralValue("select infocode from #ds2infocode")]))
45
+ .orderby(cap_event.EffectiveDate, order=pk.Order.desc)
46
+ )
47
+
48
+ if from_date:
49
+ query = query.where(cap_event.EffectiveDate >= from_date)
50
+
51
+ if to_date:
52
+ query = query.where(cap_event.EffectiveDate <= to_date)
53
+
54
+ with connections["qa"].cursor() as cursor:
55
+ # Create temporary table if it doesn't exist
56
+ with suppress(ProgrammingError):
57
+ cursor.execute(
58
+ pk.MSSQLQuery.create_table(infocode).columns(pk.Column("infocode", SqlTypes.INTEGER)).get_sql()
59
+ )
60
+ for batch in batched(lookup.keys(), 1000):
61
+ cursor.execute(f"insert into #ds2infocode values {','.join(map(lambda x: f'({x})', batch))};")
62
+
63
+ cursor.execute(query.get_sql())
64
+ for row in dictfetchall(cursor, CorporateActionDataDict):
65
+ row["instrument_id"] = lookup[row["external_identifier"]]
66
+ yield row
67
+
68
+ # Clean up temporary table
69
+ cursor.execute(pk.MSSQLQuery.drop_table(infocode).get_sql())
@@ -0,0 +1,142 @@
1
+ from contextlib import suppress
2
+ from functools import reduce
3
+ from itertools import batched
4
+ from datetime import date
5
+ from enum import Enum
6
+ from typing import Iterator
7
+ import pypika as pk
8
+ from pypika import Column, MSSQLQuery, functions as fn
9
+ from pypika.enums import SqlTypes, Order
10
+ from pypika.terms import ValueWrapper, LiteralValue
11
+
12
+ from django.db import ProgrammingError, connections
13
+ from wbcore.contrib.dataloader.dataloaders import Dataloader
14
+ from wbcore.contrib.dataloader.utils import dictfetchall
15
+ from wbfdm.dataloaders.protocols import MarketDataProtocol
16
+ from wbfdm.contrib.qa.dataloaders.utils import create_table
17
+ from wbfdm.dataloaders.types import MarketDataDict
18
+ from wbfdm.enums import Frequency, MarketData
19
+
20
+
21
+ class DS2MarketData(Enum):
22
+ OPEN = ("Open_", None)
23
+ CLOSE = ("Close_", None)
24
+ HIGH = ("High", None)
25
+ LOW = ("Low", None)
26
+ BID = ("Bid", None)
27
+ ASK = ("Ask", None)
28
+ VWAP = ("VWAP", None)
29
+ VOLUME = ("Volume", None)
30
+ MARKET_CAPITALIZATION = ("ConsolMktVal", 1_000_000)
31
+ SHARES_OUTSTANDING = ("ConsolNumShrs", 1_000)
32
+
33
+
34
+ class DatastreamMarketDataDataloader(MarketDataProtocol, Dataloader):
35
+ def market_data(
36
+ self,
37
+ values: list[MarketData] | None = [MarketData.CLOSE],
38
+ from_date: date | None = None,
39
+ to_date: date | None = None,
40
+ exact_date: date | None = None,
41
+ frequency: Frequency = Frequency.DAILY,
42
+ target_currency: str | None = None,
43
+ **kwargs,
44
+ ) -> Iterator[MarketDataDict]:
45
+ """Get market data for instruments.
46
+
47
+ Args:
48
+ queryset (QuerySet["Instrument"]): The queryset of instruments.
49
+ values (list[MarketData]): List of values to include in the results.
50
+ from_date (date | None): The starting date for filtering prices. Defaults to None.
51
+ to_date (date | None): The ending date for filtering prices. Defaults to None.
52
+ frequency (Frequency): The frequency of the requested data
53
+
54
+ Returns:
55
+ Iterator[MarketDataDict]: An iterator of dictionaries conforming to the DailyValuationDict.
56
+ """
57
+
58
+ lookup = {
59
+ f"{k[0]},{k[1]}": v for k, v in self.entities.values_list("dl_parameters__market_data__parameters", "id")
60
+ }
61
+ value_mapping = [(DS2MarketData[x.name].value, x.value) for x in values or []]
62
+
63
+ # Define tables
64
+ pricing = pk.Table("vw_DS2Pricing")
65
+ market_val = pk.Table("DS2MktVal")
66
+ fx_code = pk.Table("DS2FxCode")
67
+ fx = pk.Table("DS2FxRate")
68
+
69
+ mapping, create_mapping_table = create_table(
70
+ "#ds2infoexchcode", Column("InfoCode", SqlTypes.INTEGER), Column("ExchIntCode", SqlTypes.INTEGER)
71
+ )
72
+
73
+ # Base query to get data we always need unconditionally
74
+ query = (
75
+ pk.MSSQLQuery.from_(pricing)
76
+ .select(
77
+ fn.Concat(pricing.InfoCode, ",", pricing.ExchIntCode).as_("external_identifier"),
78
+ fn.Concat(
79
+ pricing.InfoCode, ",", pricing.ExchIntCode, "_", fn.Cast(pricing.MarketDate, SqlTypes.DATE)
80
+ ).as_("id"),
81
+ fn.Cast(pricing.MarketDate, SqlTypes.DATE).as_("valuation_date"),
82
+ ValueWrapper("qa-ds2").as_("source"),
83
+ )
84
+ .left_join(market_val)
85
+ .on((pricing.InfoCode == market_val.InfoCode) & (pricing.MarketDate == market_val.ValDate))
86
+ # We join on _codes, which removes all instruments not in _codes - implicit where
87
+ .join(mapping)
88
+ .on((pricing.InfoCode == mapping.InfoCode) & (pricing.ExchIntCode == mapping.ExchIntCode))
89
+ .where(pricing.AdjType == 2)
90
+ .orderby(pricing.MarketDate, order=Order.desc)
91
+ )
92
+
93
+ # If we need to convert to a target currency, we need the fx rate table and multiply all values with the fx rate
94
+ if target_currency:
95
+ query = (
96
+ query.select(
97
+ ValueWrapper(target_currency).as_("currency"),
98
+ *[
99
+ (LiteralValue(value[0][0]) * fn.Coalesce(fx.midrate, 1)).as_(value[1])
100
+ for value in value_mapping
101
+ ],
102
+ )
103
+ .left_join(fx_code)
104
+ .on(
105
+ (fx_code.FromCurrCode == target_currency)
106
+ & (fx_code.ToCurrCode == pricing.Currency)
107
+ & (fx_code.RateTypeCode == "SPOT")
108
+ )
109
+ .left_join(fx)
110
+ .on((fx_code.ExRateIntCode == fx.ExRateIntCode) & (fx.ExRateDate == pricing.MarketDate))
111
+ )
112
+ else:
113
+ query = query.select(
114
+ pricing.Currency.as_("currency"),
115
+ *[LiteralValue(value[0][0]).as_(value[1]) for value in value_mapping],
116
+ )
117
+
118
+ # Add conditional where clauses
119
+ if from_date:
120
+ query = query.where(pricing.MarketDate >= from_date)
121
+
122
+ if to_date:
123
+ query = query.where(pricing.MarketDate <= to_date)
124
+
125
+ if exact_date:
126
+ query = query.where(pricing.MarketDate == exact_date)
127
+
128
+ with connections["qa"].cursor() as cursor:
129
+ with suppress(ProgrammingError):
130
+ cursor.execute(create_mapping_table.get_sql())
131
+ for batch in batched(
132
+ self.entities.values_list("dl_parameters__market_data__parameters", flat=True), 1000
133
+ ):
134
+ cursor.execute(reduce(lambda x, y: x.insert(y), batch, MSSQLQuery.into(mapping)).get_sql())
135
+
136
+ cursor.execute(query.get_sql())
137
+
138
+ for row in dictfetchall(cursor, MarketDataDict):
139
+ row["instrument_id"] = lookup[row["external_identifier"]]
140
+ yield row
141
+
142
+ cursor.execute(MSSQLQuery.drop_table(mapping).get_sql())
@@ -0,0 +1,74 @@
1
+ from typing import Iterator
2
+
3
+ from django.db import connections, ProgrammingError
4
+ from wbcore.contrib.dataloader.dataloaders import Dataloader
5
+ from wbcore.contrib.dataloader.utils import dictfetchall
6
+ from wbfdm.dataloaders.protocols import OfficersProtocol
7
+ from wbfdm.dataloaders.types import OfficerDataDict
8
+ from itertools import batched
9
+ from contextlib import suppress
10
+
11
+ import pypika as pk
12
+ from pypika import functions as fn
13
+ from pypika.enums import SqlTypes
14
+ from pypika.terms import LiteralValue
15
+
16
+
17
+ from pypika.analytics import RowNumber
18
+
19
+
20
+ class RKDOfficersDataloader(OfficersProtocol, Dataloader):
21
+ def officers(
22
+ self,
23
+ ) -> Iterator[OfficerDataDict]:
24
+ lookup = {k: v for k, v in self.entities.values_list("dl_parameters__officers__parameters", "id")}
25
+
26
+ # Define tables
27
+ designation = pk.Table("RKDFndCmpOffTitleChg")
28
+ officer = pk.Table("RKDFndCmpOfficer")
29
+ temp_codes = pk.Table("#rkd_codes")
30
+
31
+ # Build the query
32
+ query = (
33
+ pk.MSSQLQuery.select(
34
+ fn.Concat(designation.Code, "-", RowNumber().orderby(officer.OfficerRank)).as_("id"),
35
+ designation.Code.as_("external_identifier"),
36
+ designation.Title.as_("position"),
37
+ fn.Concat(
38
+ officer.Prefix,
39
+ " ",
40
+ officer.FirstName,
41
+ " ",
42
+ officer.LastName,
43
+ pk.Case().when(officer.Suffix.isnull(), "").else_(fn.Concat(", ", officer.Suffix)),
44
+ ).as_("name"),
45
+ officer.Age.as_("age"),
46
+ officer.Sex.as_("sex"),
47
+ fn.Cast(designation.DesgStartDt, SqlTypes.DATE).as_("start"),
48
+ )
49
+ .from_(designation)
50
+ .join(officer)
51
+ .on((designation.Code == officer.Code) & (designation.OfficerID == officer.Officerid))
52
+ .where(designation.Code.isin([LiteralValue("select code from #rkd_codes")]))
53
+ .where(designation.DesgEndDt.isnull())
54
+ .orderby(officer.OfficerRank)
55
+ )
56
+
57
+ with connections["qa"].cursor() as cursor:
58
+ # Create and populate temporary table
59
+ with suppress(ProgrammingError):
60
+ cursor.execute(
61
+ pk.MSSQLQuery.create_table(temp_codes).columns(pk.Column("code", SqlTypes.INTEGER)).get_sql()
62
+ )
63
+ for batch in batched(lookup.keys(), 1000):
64
+ placeholders = ",".join(map(lambda x: f"('{x}')", batch))
65
+ cursor.execute(f"insert into #rkd_codes values {placeholders};")
66
+
67
+ cursor.execute(query.get_sql())
68
+
69
+ for row in dictfetchall(cursor, OfficerDataDict):
70
+ row["instrument_id"] = lookup[row["external_identifier"]]
71
+ yield row
72
+
73
+ # Clean up temporary table
74
+ cursor.execute(pk.MSSQLQuery.drop_table(temp_codes).get_sql())
@@ -0,0 +1,22 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from pypika.terms import ValueWrapper
4
+ from pypika import Column, MSSQLQuery, Table
5
+
6
+ if TYPE_CHECKING:
7
+ from pypika.terms import Term
8
+ from pypika.queries import CreateQueryBuilder
9
+
10
+
11
+ def compile_source(source: str) -> "Term":
12
+ return ValueWrapper(source).as_("source")
13
+
14
+
15
+ SOURCE_DS2 = compile_source("qa-ds2")
16
+ SOURCE_RKD = compile_source("qa-rkd")
17
+ SOURCE_IBES = compile_source("qa-ibes")
18
+
19
+
20
+ def create_table(tablename: "str", *columns: "Column") -> tuple[Table, "CreateQueryBuilder"]:
21
+ table = Table(tablename)
22
+ return table, MSSQLQuery.create_table(table).columns(*columns)
@@ -27,13 +27,13 @@ from wbfdm.enums import (
27
27
 
28
28
 
29
29
  class ReportDateProtocol(Protocol):
30
- def reporting_dates(self, only_next: bool = True) -> Iterator[ReportDateDataDict]:
31
- ...
30
+ def reporting_dates(self, only_next: bool = True) -> Iterator[ReportDateDataDict]: ...
32
31
 
33
32
 
34
33
  class AdjustmentsProtocol(Protocol):
35
- def adjustments(self, from_date: date, to_date: date) -> Iterator[AdjustmentDataDict]:
36
- ...
34
+ def adjustments(
35
+ self, from_date: date | None = None, to_date: date | None = None
36
+ ) -> Iterator[AdjustmentDataDict]: ...
37
37
 
38
38
 
39
39
  class MarketDataProtocol(Protocol):
@@ -45,20 +45,17 @@ class MarketDataProtocol(Protocol):
45
45
  exact_date: date | None = None,
46
46
  frequency: Frequency = Frequency.DAILY,
47
47
  target_currency: str | None = None,
48
- ) -> Iterator[MarketDataDict]:
49
- ...
48
+ ) -> Iterator[MarketDataDict]: ...
50
49
 
51
50
 
52
51
  class CorporateActionsProtocol(Protocol):
53
52
  def corporate_actions(
54
53
  self, from_date: date | None = None, to_date: date | None = None
55
- ) -> Iterator[CorporateActionDataDict]:
56
- ...
54
+ ) -> Iterator[CorporateActionDataDict]: ...
57
55
 
58
56
 
59
57
  class OfficersProtocol(Protocol):
60
- def officers(self) -> Iterator[OfficerDataDict]:
61
- ...
58
+ def officers(self) -> Iterator[OfficerDataDict]: ...
62
59
 
63
60
 
64
61
  class StatementsProtocol(Protocol):
@@ -73,8 +70,7 @@ class StatementsProtocol(Protocol):
73
70
  data_type: DataType = DataType.STANDARDIZED,
74
71
  financials: list[Financial] | None = None,
75
72
  target_currency: str | None = None,
76
- ) -> Iterator[StatementDataDict]:
77
- ...
73
+ ) -> Iterator[StatementDataDict]: ...
78
74
 
79
75
 
80
76
  class FinancialsProtocol(Protocol):
@@ -95,18 +91,15 @@ class FinancialsProtocol(Protocol):
95
91
  data_type: DataType = DataType.STANDARDIZED,
96
92
  estimate_type: EstimateType = EstimateType.VALID,
97
93
  target_currency: str | None = None,
98
- ) -> Iterator[FinancialDataDict]:
99
- ...
94
+ ) -> Iterator[FinancialDataDict]: ...
100
95
 
101
96
 
102
97
  class ESGControversyProtocol(Protocol):
103
- def esg_controversies(self) -> Iterator[ESGControversyDataDict]:
104
- ...
98
+ def esg_controversies(self) -> Iterator[ESGControversyDataDict]: ...
105
99
 
106
100
 
107
101
  class ESGProtocol(Protocol):
108
102
  def esg(
109
103
  self,
110
104
  values: list[ESG],
111
- ) -> Iterator[ESGDataDict]:
112
- ...
105
+ ) -> Iterator[ESGDataDict]: ...
@@ -67,7 +67,7 @@ class InstrumentDataloaderProxy(
67
67
  for dl in self.iterate_dataloaders("reporting_dates"):
68
68
  yield from dl.reporting_dates(only_next=only_next)
69
69
 
70
- def adjustments(self, from_date: date, to_date: date) -> Iterator[AdjustmentDataDict]:
70
+ def adjustments(self, from_date: date | None = None, to_date: date | None = None) -> Iterator[AdjustmentDataDict]:
71
71
  for dl in self.iterate_dataloaders("adjustments"):
72
72
  yield from dl.adjustments(from_date=from_date, to_date=to_date)
73
73
 
@@ -33,6 +33,8 @@ class MarketDataDict(BaseDict):
33
33
  Attributes:
34
34
  valuation_date: date
35
35
  The date of valuation.
36
+ external_identifier: str
37
+ The external identifier of the instrument
36
38
  open: float | None
37
39
  The opening value (if available).
38
40
  close: float | None
@@ -52,6 +54,7 @@ class MarketDataDict(BaseDict):
52
54
  """
53
55
 
54
56
  valuation_date: date
57
+ external_identifier: str
55
58
 
56
59
  open: NotRequired[float]
57
60
  close: NotRequired[float]
@@ -50,12 +50,12 @@ class Financial(ChoiceEnum):
50
50
  NET_INCOME_BEFORE_TAXES = "pbt"
51
51
  NET_INCOME = "net_income"
52
52
  EPS = "eps"
53
- FREE_CASH_FLOW = "fcf"
53
+ FREE_CASH_FLOW = "free_cash_flow"
54
54
  EBITDA = "ebitda"
55
55
  EBITDA_PER_SHARE = "ebitda_sh"
56
56
  NET_DEBT = "net_debt"
57
57
  ENTERPRISE_VALUE = "ev"
58
- SHARES_OUTSTANDING = "outstanding_shares"
58
+ SHARES_OUTSTANDING = "shares_outstanding"
59
59
  COST_OF_GOODS_SOLD = "cogs"
60
60
  GROSS_PROFIT_MARGIN = "gross_profit_margin"
61
61
  SELLING_MARKETING_EXPENSES = "selling_marketing_expenses"
@@ -79,7 +79,7 @@ class Financial(ChoiceEnum):
79
79
  CASH_FLOW_FROM_OPERATIONS = "cash_flow_from_operations"
80
80
  CAPEX = "capex"
81
81
  CASH_FLOW_FROM_INVESTING = "cash_flow_from_investing"
82
- FREE_CASH_FLOW_PER_SHARE = "fcf_per_share"
82
+ FREE_CASH_FLOW_PER_SHARE = "free_cash_flow_per_share"
83
83
  TOTAL_DIVIDENDS = "total_dividends"
84
84
  CASH_FLOW_FROM_FINANCING = "cash_flow_from_financing"
85
85
  CASH_FLOW_PER_SHARE = "cash_flow_per_share"
@@ -192,6 +192,7 @@ class InstrumentModelSerializer(InstrumentAdditionalResourcesMixin, InstrumentMo
192
192
  if not instance.is_managed:
193
193
  res.update(
194
194
  {
195
+ "fin-summary": reverse("wbfdm:financial-summary-list", args=[instance.id], request=request),
195
196
  "swe-income-statement": reverse(
196
197
  "wbfdm:statementwithestimates-list", args=[instance.id, "income"], request=request
197
198
  ),
@@ -380,7 +380,7 @@ class TestStatementWithEstimates:
380
380
  "employees",
381
381
  "stock_compensation_employee_ratio",
382
382
  "capex",
383
- "outstanding_shares",
383
+ "shares_outstanding",
384
384
  "market_capitalization",
385
385
  "close",
386
386
  "market_capitalization",
@@ -195,6 +195,7 @@ instrument_router.register(
195
195
  )
196
196
  instrument_router.register(r"valuation_ratios", viewsets.ValuationRatioChartViewSet, basename="valuation_ratios")
197
197
  instrument_router.register(r"prices", viewsets.InstrumentPriceViewSet, basename="prices")
198
+ instrument_router.register(r"financial-summary", viewsets.FinancialSummary, basename="financial-summary")
198
199
 
199
200
  instrument_statement_router = WBCoreRouter()
200
201
  instrument_statement_router.register(
@@ -232,7 +232,7 @@ class InstrumentButtonViewConfig(ButtonViewConfig):
232
232
  key="pai",
233
233
  ),
234
234
  ],
235
- )
235
+ ),
236
236
  # bt.DropDownButton(
237
237
  # label="Financial Analysis (Old)",
238
238
  # weight=3,
@@ -20,3 +20,4 @@ from .instruments_relationships import (
20
20
  from .exchanges import ExchangeDisplayConfig
21
21
  from .monthly_performances import MonthlyPerformancesInstrumentDisplayViewConfig
22
22
  from .esg import InstrumentESGPAIDisplayViewConfig, InstrumentESGControversyDisplayViewConfig
23
+ from .financial_summary import FinancialSummaryDisplayViewConfig