wbfdm 1.55.9__tar.gz → 1.55.10rc0__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 (369) hide show
  1. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/PKG-INFO +1 -1
  2. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/dsws/client.py +3 -3
  3. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/dsws/dataloaders/market_data.py +1 -1
  4. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/internal/dataloaders/market_data.py +1 -1
  5. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/backends/base.py +2 -2
  6. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/backends/statistics.py +2 -2
  7. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/exceptions.py +1 -1
  8. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/models.py +6 -0
  9. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/orchestrators.py +4 -4
  10. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/viewsets/mixins.py +6 -6
  11. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/msci/client.py +3 -0
  12. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/database_routers.py +1 -1
  13. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/dataloaders/adjustments.py +2 -1
  14. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/dataloaders/corporate_actions.py +2 -1
  15. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/dataloaders/market_data.py +1 -1
  16. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/dataloaders/officers.py +1 -1
  17. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/sync/utils.py +4 -2
  18. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/dataloaders/protocols.py +1 -1
  19. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/figures/financials/financial_analysis_charts.py +2 -8
  20. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/filters/instruments.py +1 -1
  21. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/cbinsights/utils/client.py +8 -8
  22. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/refinitiv/utils/controller.py +1 -1
  23. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/handlers/instrument.py +2 -2
  24. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/parsers/cbinsights/equities.py +2 -3
  25. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/jinja2.py +2 -1
  26. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/esg/controversies.py +3 -0
  27. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/fields.py +2 -2
  28. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/fk_fields.py +3 -3
  29. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/instrument_relationships.py +3 -0
  30. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/instruments.py +6 -6
  31. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/mixin/instruments.py +2 -2
  32. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/options.py +6 -0
  33. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/private_equities.py +3 -0
  34. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/analysis/financial_analysis/test_statement_with_estimates.py +0 -1
  35. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/instruments_relationships.py +3 -1
  36. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/titles/instrument_prices.py +2 -1
  37. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/esg.py +2 -2
  38. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/financial_analysis/financial_metric_analysis.py +2 -2
  39. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/financial_analysis/financial_ratio_analysis.py +1 -1
  40. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/financial_analysis/financial_summary.py +6 -6
  41. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/instruments/financials_analysis.py +8 -11
  42. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/market_data.py +1 -1
  43. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/.gitignore +0 -0
  44. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/pyproject.toml +0 -0
  45. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/__init__.py +0 -0
  46. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/admin/__init__.py +0 -0
  47. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/admin/classifications.py +0 -0
  48. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/admin/esg.py +0 -0
  49. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/admin/exchanges.py +0 -0
  50. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/admin/instrument_lists.py +0 -0
  51. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/admin/instrument_prices.py +0 -0
  52. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/admin/instrument_requests.py +0 -0
  53. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/admin/instruments.py +0 -0
  54. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/admin/instruments_relationships.py +0 -0
  55. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/admin/options.py +0 -0
  56. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/__init__.py +0 -0
  57. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/esg/__init__.py +0 -0
  58. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/esg/enums.py +0 -0
  59. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/esg/esg_analysis.py +0 -0
  60. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/esg/utils.py +0 -0
  61. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/financial_analysis/__init__.py +0 -0
  62. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/financial_analysis/change_point_detection.py +0 -0
  63. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/financial_analysis/financial_metric_analysis.py +0 -0
  64. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/financial_analysis/financial_ratio_analysis.py +0 -0
  65. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/financial_analysis/financial_statistics_analysis.py +0 -0
  66. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/financial_analysis/statement_with_estimates.py +0 -0
  67. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/financial_analysis/utils.py +0 -0
  68. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/technical_analysis/__init__.py +0 -0
  69. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/technical_analysis/technical_analysis.py +0 -0
  70. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/technical_analysis/traces.py +0 -0
  71. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/analysis/utils.py +0 -0
  72. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/apps.py +0 -0
  73. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/backends/dto.py +0 -0
  74. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/__init__.py +0 -0
  75. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/dsws/__init__.py +0 -0
  76. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/internal/__init__.py +0 -0
  77. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/internal/dataloaders/__init__.py +0 -0
  78. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/__init__.py +0 -0
  79. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/admin/__init__.py +0 -0
  80. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/admin/instruments.py +0 -0
  81. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/admin/metrics.py +0 -0
  82. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/apps.py +0 -0
  83. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/backends/__init__.py +0 -0
  84. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/backends/performances.py +0 -0
  85. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/backends/utils.py +0 -0
  86. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/decorators.py +0 -0
  87. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/dispatch.py +0 -0
  88. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/dto.py +0 -0
  89. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/factories.py +0 -0
  90. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/filters.py +0 -0
  91. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/migrations/0001_initial.py +0 -0
  92. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/migrations/0002_remove_instrumentmetric_unique_instrument_metric_and_more.py +0 -0
  93. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/migrations/__init__.py +0 -0
  94. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/registry.py +0 -0
  95. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/serializers.py +0 -0
  96. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/signals.py +0 -0
  97. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/tasks.py +0 -0
  98. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/tests/__init__.py +0 -0
  99. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/tests/backends/__init__.py +0 -0
  100. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/tests/backends/test_performances.py +0 -0
  101. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/tests/backends/test_statistics.py +0 -0
  102. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/tests/conftest.py +0 -0
  103. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/tests/test_dto.py +0 -0
  104. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/tests/test_models.py +0 -0
  105. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/tests/test_tasks.py +0 -0
  106. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/tests/test_viewsets.py +0 -0
  107. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/urls.py +0 -0
  108. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/viewsets/__init__.py +0 -0
  109. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/viewsets/configs/__init__.py +0 -0
  110. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/viewsets/configs/display.py +0 -0
  111. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/viewsets/configs/menus.py +0 -0
  112. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/viewsets/configs/utils.py +0 -0
  113. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/metric/viewsets/viewsets.py +0 -0
  114. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/msci/__init__.py +0 -0
  115. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/msci/dataloaders/__init__.py +0 -0
  116. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/msci/dataloaders/esg.py +0 -0
  117. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/msci/dataloaders/esg_controversies.py +0 -0
  118. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/msci/sync.py +0 -0
  119. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/msci/tests/__init__.py +0 -0
  120. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/msci/tests/conftest.py +0 -0
  121. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/msci/tests/test_client.py +0 -0
  122. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/__init__.py +0 -0
  123. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/apps.py +0 -0
  124. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/dataloaders/__init__.py +0 -0
  125. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/dataloaders/financials.py +0 -0
  126. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/dataloaders/fx_rates.py +0 -0
  127. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/dataloaders/reporting_dates.py +0 -0
  128. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/dataloaders/statements.py +0 -0
  129. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/dataloaders/utils.py +0 -0
  130. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/jinja2/qa/sql/companies.sql +0 -0
  131. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/base_estimates.sql +0 -0
  132. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/calendarized.sql +0 -0
  133. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/complete.sql +0 -0
  134. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/estimates.sql +0 -0
  135. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/jinja2/qa/sql/ibes/financials.sql +0 -0
  136. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/jinja2/qa/sql/instruments.sql +0 -0
  137. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/jinja2/qa/sql/quotes.sql +0 -0
  138. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/sync/exchanges.py +0 -0
  139. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/sync/instruments.py +0 -0
  140. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/contrib/qa/tasks.py +0 -0
  141. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/dataloaders/__init__.py +0 -0
  142. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/dataloaders/cache.py +0 -0
  143. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/dataloaders/proxies.py +0 -0
  144. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/dataloaders/types.py +0 -0
  145. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/dynamic_preferences_registry.py +0 -0
  146. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/enums.py +0 -0
  147. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/factories/__init__.py +0 -0
  148. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/factories/classifications.py +0 -0
  149. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/factories/controversies.py +0 -0
  150. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/factories/exchanges.py +0 -0
  151. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/factories/instrument_list.py +0 -0
  152. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/factories/instrument_prices.py +0 -0
  153. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/factories/instruments.py +0 -0
  154. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/factories/instruments_relationships.py +0 -0
  155. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/factories/options.py +0 -0
  156. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/figures/__init__.py +0 -0
  157. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/figures/financials/__init__.py +0 -0
  158. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/figures/financials/financials_charts.py +0 -0
  159. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/filters/__init__.py +0 -0
  160. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/filters/classifications.py +0 -0
  161. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/filters/exchanges.py +0 -0
  162. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/filters/financials.py +0 -0
  163. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/filters/financials_analysis.py +0 -0
  164. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/filters/instrument_prices.py +0 -0
  165. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/filters/utils.py +0 -0
  166. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/__init__.py +0 -0
  167. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/__init__.py +0 -0
  168. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/cbinsights/__init__.py +0 -0
  169. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/cbinsights/deals.py +0 -0
  170. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/cbinsights/equities.py +0 -0
  171. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/cbinsights/mixin.py +0 -0
  172. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/cbinsights/utils/__init__.py +0 -0
  173. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/cbinsights/utils/classifications.py +0 -0
  174. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/refinitiv/__init__.py +0 -0
  175. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/refinitiv/daily_fundamental.py +0 -0
  176. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/refinitiv/fiscal_period.py +0 -0
  177. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/refinitiv/forecast.py +0 -0
  178. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/refinitiv/fundamental.py +0 -0
  179. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/refinitiv/geographic_segment.py +0 -0
  180. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/refinitiv/instrument.py +0 -0
  181. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/refinitiv/instrument_price.py +0 -0
  182. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/refinitiv/mixin.py +0 -0
  183. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/backends/refinitiv/utils/__init__.py +0 -0
  184. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/handlers/__init__.py +0 -0
  185. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/handlers/instrument_list.py +0 -0
  186. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/handlers/instrument_price.py +0 -0
  187. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/handlers/option.py +0 -0
  188. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/handlers/private_equities.py +0 -0
  189. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/parsers/__init__.py +0 -0
  190. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/parsers/cbinsights/__init__.py +0 -0
  191. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/parsers/cbinsights/deals.py +0 -0
  192. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/parsers/cbinsights/fundamentals.py +0 -0
  193. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/parsers/refinitiv/__init__.py +0 -0
  194. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/parsers/refinitiv/daily_fundamental.py +0 -0
  195. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/parsers/refinitiv/forecast.py +0 -0
  196. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/parsers/refinitiv/fundamental.py +0 -0
  197. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/parsers/refinitiv/geographic_segment.py +0 -0
  198. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/parsers/refinitiv/instrument.py +0 -0
  199. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/parsers/refinitiv/instrument_price.py +0 -0
  200. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/parsers/refinitiv/utils.py +0 -0
  201. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/resources/__init__.py +0 -0
  202. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/resources/classification.py +0 -0
  203. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/resources/instrument_prices.py +0 -0
  204. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/import_export/resources/instruments.py +0 -0
  205. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/locale/de/LC_MESSAGES/django.mo +0 -0
  206. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/locale/de/LC_MESSAGES/django.po +0 -0
  207. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/locale/en/LC_MESSAGES/django.mo +0 -0
  208. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/locale/en/LC_MESSAGES/django.po +0 -0
  209. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/locale/fr/LC_MESSAGES/django.mo +0 -0
  210. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/locale/fr/LC_MESSAGES/django.po +0 -0
  211. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/management/__init__.py +0 -0
  212. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0001_initial.py +0 -0
  213. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0002_rename_statements_instrumentlookup_financials_and_more.py +0 -0
  214. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0003_instrument_estimate_backend_and_more.py +0 -0
  215. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0004_rename_financials_instrumentlookup_statements_and_more.py +0 -0
  216. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0005_instrument_corporate_action_backend.py +0 -0
  217. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0006_instrument_officer_backend.py +0 -0
  218. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0007_instrument_country_instrument_currency_and_more.py +0 -0
  219. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0008_controversy.py +0 -0
  220. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0009_alter_controversy_flag_alter_controversy_initiated_and_more.py +0 -0
  221. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0010_classification_classificationgroup_deal_exchange_and_more.py +0 -0
  222. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0011_delete_instrumentlookup_instrument_corporate_actions_and_more.py +0 -0
  223. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0012_instrumentprice_created_instrumentprice_modified.py +0 -0
  224. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0013_instrument_is_investable_universe_and_more.py +0 -0
  225. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0014_alter_controversy_instrument.py +0 -0
  226. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0015_instrument_instrument_investible_index.py +0 -0
  227. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0016_instrumenttype_name_repr.py +0 -0
  228. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0017_instrument_instrument_security_index.py +0 -0
  229. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0018_instrument_instrument_level_index.py +0 -0
  230. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0019_alter_controversy_source.py +0 -0
  231. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0020_optionaggregate_option_and_more.py +0 -0
  232. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0021_delete_instrumentdailystatistics.py +0 -0
  233. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0022_instrument_cusip_option_open_interest_20d_and_more.py +0 -0
  234. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0023_instrument_unique_ric_instrument_unique_rmc_and_more.py +0 -0
  235. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0024_option_open_interest_10d_option_volume_10d_and_more.py +0 -0
  236. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0025_instrument_is_primary_and_more.py +0 -0
  237. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0026_instrument_is_cash_equivalent.py +0 -0
  238. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0027_remove_instrument_unique_ric_and_more.py +0 -0
  239. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0028_instrumentprice_annualized_daily_volatility.py +0 -0
  240. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0029_alter_instrumentprice_volume.py +0 -0
  241. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0030_alter_relatedinstrumentthroughmodel_related_type.py +0 -0
  242. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0031_exchange_apply_round_lot_size_and_more.py +0 -0
  243. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0032_alter_instrumentprice_outstanding_shares.py +0 -0
  244. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/0033_alter_controversy_review.py +0 -0
  245. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/migrations/__init__.py +0 -0
  246. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/__init__.py +0 -0
  247. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/esg/__init__.py +0 -0
  248. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/exchanges/__init__.py +0 -0
  249. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/exchanges/exchanges.py +0 -0
  250. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/indicators.py +0 -0
  251. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/__init__.py +0 -0
  252. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/classifications.py +0 -0
  253. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/instrument_lists.py +0 -0
  254. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/instrument_prices.py +0 -0
  255. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/instrument_requests.py +0 -0
  256. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/llm/__init__.py +0 -0
  257. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/llm/create_instrument_news_relationships.py +0 -0
  258. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/mixin/__init__.py +0 -0
  259. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/mixin/financials_computed.py +0 -0
  260. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/mixin/financials_serializer_fields.py +0 -0
  261. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/querysets.py +0 -0
  262. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/models/instruments/utils.py +0 -0
  263. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/preferences.py +0 -0
  264. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/serializers/__init__.py +0 -0
  265. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/serializers/esg.py +0 -0
  266. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/serializers/exchanges.py +0 -0
  267. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/serializers/instruments/__init__.py +0 -0
  268. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/serializers/instruments/classifications.py +0 -0
  269. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/serializers/instruments/instrument_lists.py +0 -0
  270. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/serializers/instruments/instrument_prices.py +0 -0
  271. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/serializers/instruments/instrument_relationships.py +0 -0
  272. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/serializers/instruments/instrument_requests.py +0 -0
  273. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/serializers/instruments/instruments.py +0 -0
  274. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/serializers/instruments/mixins.py +0 -0
  275. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/serializers/officers.py +0 -0
  276. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/signals.py +0 -0
  277. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/sync/__init__.py +0 -0
  278. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/sync/abstract.py +0 -0
  279. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/sync/runner.py +0 -0
  280. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tasks.py +0 -0
  281. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/__init__.py +0 -0
  282. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/analysis/__init__.py +0 -0
  283. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/analysis/financial_analysis/__init__.py +0 -0
  284. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/analysis/financial_analysis/test_utils.py +0 -0
  285. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/analysis/test_esg.py +0 -0
  286. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/conftest.py +0 -0
  287. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/dataloaders/__init__.py +0 -0
  288. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/dataloaders/test_cache.py +0 -0
  289. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/models/__init__.py +0 -0
  290. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/models/test_classifications.py +0 -0
  291. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/models/test_exchanges.py +0 -0
  292. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/models/test_instrument_list.py +0 -0
  293. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/models/test_instrument_prices.py +0 -0
  294. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/models/test_instruments.py +0 -0
  295. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/models/test_merge.py +0 -0
  296. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/models/test_options.py +0 -0
  297. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/models/test_queryset.py +0 -0
  298. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/test_tasks.py +0 -0
  299. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/tests/tests.py +0 -0
  300. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/urls.py +0 -0
  301. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/utils.py +0 -0
  302. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/__init__.py +0 -0
  303. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/__init__.py +0 -0
  304. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/buttons/__init__.py +0 -0
  305. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/buttons/classifications.py +0 -0
  306. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/buttons/exchanges.py +0 -0
  307. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/buttons/instrument_prices.py +0 -0
  308. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/buttons/instruments.py +0 -0
  309. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/__init__.py +0 -0
  310. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/classifications.py +0 -0
  311. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/esg.py +0 -0
  312. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/exchanges.py +0 -0
  313. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/financial_summary.py +0 -0
  314. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/instrument_lists.py +0 -0
  315. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/instrument_prices.py +0 -0
  316. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/instrument_requests.py +0 -0
  317. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/instruments.py +0 -0
  318. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/monthly_performances.py +0 -0
  319. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/officers.py +0 -0
  320. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/prices.py +0 -0
  321. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/statement_with_estimates.py +0 -0
  322. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/display/statements.py +0 -0
  323. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/endpoints/__init__.py +0 -0
  324. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/endpoints/classifications.py +0 -0
  325. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/endpoints/esg.py +0 -0
  326. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/endpoints/exchanges.py +0 -0
  327. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/endpoints/financials_analysis.py +0 -0
  328. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/endpoints/instrument_lists.py +0 -0
  329. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/endpoints/instrument_prices.py +0 -0
  330. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/endpoints/instrument_requests.py +0 -0
  331. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/endpoints/instruments.py +0 -0
  332. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/endpoints/instruments_relationships.py +0 -0
  333. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/endpoints/statements.py +0 -0
  334. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/menus/__init__.py +0 -0
  335. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/menus/classifications.py +0 -0
  336. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/menus/exchanges.py +0 -0
  337. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/menus/instrument_lists.py +0 -0
  338. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/menus/instruments.py +0 -0
  339. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/menus/instruments_relationships.py +0 -0
  340. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/titles/__init__.py +0 -0
  341. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/titles/classifications.py +0 -0
  342. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/titles/esg.py +0 -0
  343. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/titles/exchanges.py +0 -0
  344. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/titles/financial_ratio_analysis.py +0 -0
  345. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/titles/financials_analysis.py +0 -0
  346. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/titles/instrument_requests.py +0 -0
  347. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/titles/instruments.py +0 -0
  348. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/titles/instruments_relationships.py +0 -0
  349. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/titles/market_data.py +0 -0
  350. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/titles/prices.py +0 -0
  351. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/configs/titles/statement_with_estimates.py +0 -0
  352. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/exchanges.py +0 -0
  353. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/financial_analysis/__init__.py +0 -0
  354. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/financial_analysis/statement_with_estimates.py +0 -0
  355. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/instruments/__init__.py +0 -0
  356. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/instruments/classifications.py +0 -0
  357. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/instruments/instrument_lists.py +0 -0
  358. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/instruments/instrument_prices.py +0 -0
  359. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/instruments/instrument_requests.py +0 -0
  360. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/instruments/instruments.py +0 -0
  361. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/instruments/instruments_relationships.py +0 -0
  362. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/instruments/utils.py +0 -0
  363. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/mixins.py +0 -0
  364. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/officers.py +0 -0
  365. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/prices.py +0 -0
  366. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/statements/__init__.py +0 -0
  367. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/statements/statements.py +0 -0
  368. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/technical_analysis/__init__.py +0 -0
  369. {wbfdm-1.55.9 → wbfdm-1.55.10rc0}/wbfdm/viewsets/technical_analysis/monthly_performances.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wbfdm
3
- Version: 1.55.9
3
+ Version: 1.55.10rc0
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.*
@@ -3,7 +3,7 @@ import re
3
3
  from datetime import date, datetime
4
4
  from typing import Generator, List, Optional
5
5
 
6
- import DatastreamPy as dsweb
6
+ import DatastreamPy as dsweb # noqa
7
7
  import numpy as np
8
8
  import pandas as pd
9
9
  import pytz
@@ -13,7 +13,7 @@ from wbcore.contrib.currency.models import Currency, CurrencyFXRates
13
13
 
14
14
 
15
15
  class CachedTokenDataClient(dsweb.DataClient):
16
- def _get_token(self, isProxy=False):
16
+ def _get_token(self, isProxy=False): # noqa
17
17
  if (token := cache.get("dsws_token")) and (token_expiry := cache.get("dsws_token_expiry")):
18
18
  self.token = token
19
19
  self.tokenExpiry = timezone.make_aware(datetime.fromtimestamp(token_expiry), timezone=pytz.UTC)
@@ -102,7 +102,7 @@ class Client:
102
102
  if len(requests_data) > self.MAXIMUM_REQUESTS_PER_BUNDLE:
103
103
  raise ValueError(f"number of request exceed {self.MAXIMUM_REQUESTS_PER_BUNDLE}")
104
104
  # Construct the requests bundle
105
- for request_tickers, request_symbols in requests_data:
105
+ for request_tickers, _ in requests_data:
106
106
  # Convert a list of string into a valid string
107
107
  converted_ticker = ",".join(request_tickers)
108
108
  if "start" in extra_client_kwargs or "end" in extra_client_kwargs:
@@ -30,7 +30,7 @@ FIELD_MAP = {
30
30
  class DSWSMarketDataDataloader(MarketDataProtocol, Dataloader):
31
31
  def market_data(
32
32
  self,
33
- values: list[MarketData] = [MarketData.CLOSE],
33
+ values: list[MarketData] | None = None,
34
34
  from_date: date | None = None,
35
35
  to_date: date | None = None,
36
36
  exact_date: date | None = None,
@@ -36,7 +36,7 @@ def _cast_decimal_to_float(value: float | Decimal) -> float:
36
36
  class MarketDataDataloader(MarketDataProtocol, Dataloader):
37
37
  def market_data(
38
38
  self,
39
- values: list[MarketData] = [MarketData.CLOSE],
39
+ values: list[MarketData] | None = None,
40
40
  from_date: date | None = None,
41
41
  to_date: date | None = None,
42
42
  exact_date: date | None = None,
@@ -13,7 +13,7 @@ from wbcore.contrib.currency.models import CurrencyFXRates
13
13
  from wbfdm.models import Instrument, InstrumentPrice
14
14
 
15
15
  from ..dto import Metric, MetricField, MetricKey
16
- from ..exceptions import MetricInvalidParameterException
16
+ from ..exceptions import MetricInvalidParameterError
17
17
  from .utils import get_today
18
18
 
19
19
  T = TypeVar("T", bound=Model)
@@ -94,7 +94,7 @@ class InstrumentMetricBaseBackend(AbstractBackend[Instrument]):
94
94
  [val_date, (get_today() - pd.tseries.offsets.BDay(1)).date()]
95
95
  ) # ensure that value date is at least lower than today (otherwise, we might compute performance for intraday, which we do not want yet
96
96
  else:
97
- raise MetricInvalidParameterException()
97
+ raise MetricInvalidParameterError()
98
98
 
99
99
 
100
100
  class BaseDataloader:
@@ -11,7 +11,7 @@ from wbfdm.models import Instrument, InstrumentPrice
11
11
 
12
12
  from ..decorators import register
13
13
  from ..dto import Metric, MetricField, MetricKey
14
- from ..exceptions import MetricInvalidParameterException
14
+ from ..exceptions import MetricInvalidParameterError
15
15
  from .base import BaseDataloader, InstrumentMetricBaseBackend
16
16
 
17
17
  STATISTICS_METRIC = MetricKey(
@@ -207,7 +207,7 @@ class InstrumentFinancialStatisticsMetricBackend(InstrumentMetricBaseBackend):
207
207
  elif self.val_date:
208
208
  with suppress(InstrumentPrice.DoesNotExist):
209
209
  return instrument.valuations.filter(date__lte=self.val_date).latest("date").date
210
- raise MetricInvalidParameterException()
210
+ raise MetricInvalidParameterError()
211
211
 
212
212
 
213
213
  @register(move_first=True)
@@ -1,4 +1,4 @@
1
- class MetricInvalidParameterException(Exception):
1
+ class MetricInvalidParameterError(Exception):
2
2
  """
3
3
  If instantiated backend parameters are invalid, the orchestrator or backend itself are expected to raise that exception
4
4
  """
@@ -48,6 +48,12 @@ class InstrumentMetric(models.Model):
48
48
  self.basket_repr = str(self.basket)
49
49
  super().save(*args, **kwargs)
50
50
 
51
+ def __str__(self) -> str:
52
+ repr = f"{self.basket} - {self.key}"
53
+ if self.date:
54
+ repr += f"({self.date})"
55
+ return repr
56
+
51
57
  @classmethod
52
58
  def update_or_create_from_metric(cls, metric: Metric, parent_instrument_metric: Self | None = None):
53
59
  """
@@ -8,7 +8,7 @@ from tqdm import tqdm
8
8
 
9
9
  from .backends.base import AbstractBackend
10
10
  from .dto import Metric
11
- from .exceptions import MetricInvalidParameterException
11
+ from .exceptions import MetricInvalidParameterError
12
12
  from .models import InstrumentMetric
13
13
  from .registry import backend_registry
14
14
 
@@ -73,9 +73,9 @@ class MetricOrchestrator:
73
73
  if debug:
74
74
  # if debug mode is enabled, we wrap the parameters list into a tqdm generator
75
75
  parameters = tqdm(parameters)
76
- for parameters in parameters:
77
- with suppress(MetricInvalidParameterException):
78
- yield from parameters[0].compute_metrics(parameters[1])
76
+ for param in parameters:
77
+ with suppress(MetricInvalidParameterError):
78
+ yield from param[0].compute_metrics(param[1])
79
79
 
80
80
  def process(self, debug: bool = False):
81
81
  """
@@ -185,19 +185,19 @@ class InstrumentMetricMixin(_Base):
185
185
  serializer_class = self.get_serializer_class()
186
186
  kwargs.setdefault("context", self.get_serializer_context())
187
187
 
188
- BaseMeta = serializer_class.Meta
189
- fields = list(getattr(BaseMeta, "fields", ()))
190
- read_only_fields = list(getattr(BaseMeta, "read_only_fields", ()))
188
+ base_meta = serializer_class.Meta
189
+ fields = list(getattr(base_meta, "fields", ()))
190
+ read_only_fields = list(getattr(base_meta, "read_only_fields", ()))
191
191
  for extra_field in self._metric_serializer_fields.keys():
192
192
  fields.append(extra_field)
193
193
  read_only_fields.append(extra_field)
194
194
 
195
- Meta = type(str("Meta"), (BaseMeta,), {"fields": fields, "read_only_fields": read_only_fields})
195
+ meta = type(str("Meta"), (base_meta,), {"fields": fields, "read_only_fields": read_only_fields})
196
196
  new_class = type(
197
197
  serializer_class.__name__,
198
198
  (serializer_class,),
199
199
  {
200
- "Meta": Meta,
200
+ "Meta": meta,
201
201
  **self._metric_serializer_fields,
202
202
  "SERIALIZER_CLASS_FOR_REMOTE_ADDITIONAL_RESOURCES": serializer_class,
203
203
  },
@@ -233,7 +233,7 @@ class InstrumentMetricMixin(_Base):
233
233
  # for all the missings keys (not present in the aggregates already), we compute the aggregatation based on the aggregate function given by the MetricField class
234
234
  missing_aggregate_map = {}
235
235
  for metric_key in self.metric_keys:
236
- for field_key, field_filter in metric_key.subfields_filter_map.items():
236
+ for field_key in metric_key.subfields_filter_map.keys():
237
237
  if field_key in self._metric_serializer_fields.keys() and field_key not in aggregates:
238
238
  missing_aggregate_map[field_key] = metric_key.subfields_map[field_key]
239
239
  missing_aggregate = queryset.aggregate(
@@ -38,6 +38,7 @@ class MSCIClient:
38
38
  "grant_type": "client_credentials",
39
39
  "audience": "https://esg/data",
40
40
  },
41
+ timeout=10,
41
42
  )
42
43
  if resp.status_code == requests.codes.ok:
43
44
  with suppress(KeyError, requests.exceptions.JSONDecodeError):
@@ -58,6 +59,7 @@ class MSCIClient:
58
59
  "factor_name_list": factors,
59
60
  },
60
61
  headers={"AUTHORIZATION": f"Bearer {self.oauth_token}"},
62
+ timeout=10,
61
63
  )
62
64
  if response.ok:
63
65
  for row in response.json().get("result", {}).get("issuers", []):
@@ -78,6 +80,7 @@ class MSCIClient:
78
80
  "offset": offset,
79
81
  },
80
82
  headers={"AUTHORIZATION": f"Bearer {self.oauth_token}"},
83
+ timeout=10,
81
84
  )
82
85
 
83
86
  if not response.ok:
@@ -20,6 +20,6 @@ class QARouter:
20
20
  return None
21
21
 
22
22
  def allow_migrate(self, db, app_label, model_name=None, **hints):
23
- if app_label == "qa":
23
+ if db == "qa":
24
24
  return False
25
25
  return None
@@ -57,7 +57,8 @@ class DatastreamAdjustmentsDataloader(AdjustmentsProtocol, Dataloader):
57
57
  pk.MSSQLQuery.create_table(infocode).columns(pk.Column("infocode", SqlTypes.INTEGER)).get_sql()
58
58
  )
59
59
  for batch in batched(lookup.keys(), 1000):
60
- cursor.execute(f"insert into #ds2infocode values {",".join(map(lambda x: f"({x})", batch))};")
60
+ placeholders = ",".join(map(lambda x: f"({x})", batch))
61
+ cursor.execute("insert into #ds2infocode values %s;", (placeholders,))
61
62
 
62
63
  cursor.execute(query.get_sql())
63
64
 
@@ -58,7 +58,8 @@ class DatastreamCorporateActionsDataloader(CorporateActionsProtocol, Dataloader)
58
58
  pk.MSSQLQuery.create_table(infocode).columns(pk.Column("infocode", SqlTypes.INTEGER)).get_sql()
59
59
  )
60
60
  for batch in batched(lookup.keys(), 1000):
61
- cursor.execute(f"insert into #ds2infocode values {','.join(map(lambda x: f'({x})', batch))};")
61
+ placeholders = ",".join(map(lambda x: f"({x})", batch))
62
+ cursor.execute("insert into #ds2infocode values %s;", (placeholders,))
62
63
 
63
64
  cursor.execute(query.get_sql())
64
65
  for row in dictfetchall(cursor, CorporateActionDataDict):
@@ -41,7 +41,7 @@ class DS2MarketData(Enum):
41
41
  class DatastreamMarketDataDataloader(MarketDataProtocol, Dataloader):
42
42
  def market_data(
43
43
  self,
44
- values: list[MarketData] = [MarketData.CLOSE],
44
+ values: list[MarketData] | None = None,
45
45
  from_date: date | None = None,
46
46
  to_date: date | None = None,
47
47
  exact_date: date | None = None,
@@ -60,7 +60,7 @@ class RKDOfficersDataloader(OfficersProtocol, Dataloader):
60
60
  )
61
61
  for batch in batched(lookup.keys(), 1000):
62
62
  placeholders = ",".join(map(lambda x: f"('{x}')", batch))
63
- cursor.execute(f"insert into #rkd_codes values {placeholders};")
63
+ cursor.execute("insert into #rkd_codes values %s;", (placeholders,))
64
64
 
65
65
  cursor.execute(query.get_sql())
66
66
 
@@ -290,14 +290,16 @@ def trigger_partial_update(
290
290
  else:
291
291
  with connections["qa"].cursor() as cursor:
292
292
  cursor.execute(
293
- f"SELECT MAX(last_user_update) FROM sys.dm_db_index_usage_stats WHERE OBJECT_NAME(object_id) = '{table_change_name}'"
293
+ "SELECT MAX(last_user_update) FROM sys.dm_db_index_usage_stats WHERE OBJECT_NAME(object_id) = %S'",
294
+ (table_change_name,),
294
295
  )
295
296
  max_last_updated_qa = (
296
297
  pytz.timezone(settings.TIME_ZONE).localize(result[0]) if (result := cursor.fetchone()) else None
297
298
  )
298
299
  if max_last_updated_qa and max_last_updated_qa > max_last_updated:
299
300
  for _, security_id in cursor.execute(
300
- f"SELECT UpdateFlag_, {id_field} FROM {table_change_name}"
301
+ "SELECT UpdateFlag_, %s FROM %s",
302
+ (id_field, table_change_name),
301
303
  ).fetchall():
302
304
  try:
303
305
  update_or_create_item(security_id)
@@ -49,7 +49,7 @@ class FXRateProtocol(Protocol):
49
49
  class MarketDataProtocol(Protocol):
50
50
  def market_data(
51
51
  self,
52
- values: list[MarketData] = [MarketData.CLOSE],
52
+ values: list[MarketData] | None = None,
53
53
  from_date: date | None = None,
54
54
  to_date: date | None = None,
55
55
  exact_date: date | None = None,
@@ -115,13 +115,7 @@ class FinancialAnalysisGenerator:
115
115
  self.instruments_repr_map = {i.id: i.name_repr for i in self.instruments}
116
116
  self.currency_map = {i.id: i.currency.id for i in self.instruments}
117
117
 
118
- def build_df(
119
- self,
120
- instrument_prices_field_names: list[str] = [],
121
- fundamental_field_names: list[str] = [],
122
- forecast_field_names: list[str] = [],
123
- daily_fundamental_field_names: list[str] = [],
124
- ):
118
+ def build_df(self, **kwargs):
125
119
  """
126
120
  Used to returns a df with all the variables passed in four separate lists
127
121
 
@@ -239,7 +233,7 @@ class FinancialAnalysisGenerator:
239
233
  @staticmethod
240
234
  def clean_data(
241
235
  df: pd.DataFrame,
242
- var_list: list[str] = [],
236
+ var_list: list[str],
243
237
  drop_negative=True,
244
238
  q_low: float = 0.05,
245
239
  q_high: float = 0.95,
@@ -138,7 +138,7 @@ class InstrumentFilterSet(TagFilterMixin, InstrumentFavoriteGroupFilterSet):
138
138
  if "parent" in data:
139
139
  data.pop("classifications", None) # remove classifications in case we are navigating the tree
140
140
  data.pop("level", None)
141
- super().__init__(data=data, *args, **kwargs)
141
+ super().__init__(*args, data=data, **kwargs)
142
142
 
143
143
  class Meta:
144
144
  model = Instrument
@@ -7,11 +7,11 @@ from celery import shared_task
7
7
  from tqdm import tqdm
8
8
 
9
9
 
10
- class RateLimitException(Exception):
10
+ class RateLimitError(Exception):
11
11
  pass
12
12
 
13
13
 
14
- class CreditLimitException(Exception):
14
+ class CreditLimitError(Exception):
15
15
  pass
16
16
 
17
17
 
@@ -38,17 +38,18 @@ class Client:
38
38
  url,
39
39
  params={**params, **{"nextPageToken": next_page_token}} if next_page_token else params,
40
40
  headers={"authorization": self.jwt_header_value},
41
+ timeout=10,
41
42
  )
42
43
  if resp.status_code != 200:
43
44
  if resp.status_code == 429:
44
- raise RateLimitException()
45
+ raise RateLimitError()
45
46
  raise requests.ConnectionError(
46
47
  f"unexpected error from api\nstatus_code: {resp.status_code}\nerror: {resp.text}"
47
48
  )
48
49
 
49
50
  if credits_remaining_str := resp.headers.get("x-cbinsights-credits-remaining", None):
50
51
  if int(credits_remaining_str) <= 0:
51
- raise CreditLimitException()
52
+ raise CreditLimitError()
52
53
 
53
54
  return resp.json()
54
55
 
@@ -72,11 +73,11 @@ class Client:
72
73
  resp = self._request(data_url, params=params, next_page_token=next_page_token)
73
74
  yield resp
74
75
  next_page_token = resp["nextPageToken"]
75
- except RateLimitException:
76
+ except RateLimitError:
76
77
  time.sleep(self.rate_limit_sleep)
77
78
  retry += 1
78
79
  if retry >= 5:
79
- raise RateLimitException()
80
+ raise RateLimitError()
80
81
 
81
82
  def _chunk_paginated_request(self, data_url, org_ids, extra_params, endpoint, debug: bool = False):
82
83
  data = []
@@ -96,8 +97,7 @@ class Client:
96
97
  auth_url = "https://api.cbinsights.com/v1/authorize"
97
98
 
98
99
  auth_resp = requests.get(
99
- auth_url,
100
- params={"clientId": self.client_id, "clientSecret": self.client_secret},
100
+ auth_url, params={"clientId": self.client_id, "clientSecret": self.client_secret}, timeout=10
101
101
  )
102
102
 
103
103
  if auth_resp.status_code != 200:
@@ -61,7 +61,7 @@ class Controller:
61
61
  instrument_ric: str = None,
62
62
  instrument_isin: str = None,
63
63
  instrument_mnemonic: str = None,
64
- perm_id_symbols: list[str] = ["QPID", "IPID"],
64
+ perm_id_symbols: tuple[str, ...] = ("QPID", "IPID"),
65
65
  ) -> str | None:
66
66
  def _process_ticker(ticker):
67
67
  if not (df := self.client.get_static_df(tickers=[ticker], fields=perm_id_symbols)).empty:
@@ -237,8 +237,8 @@ class InstrumentImportHandler(ImportExportHandler):
237
237
  if instrument_id := data.pop("id", None):
238
238
  try:
239
239
  return self.model.objects.get(id=instrument_id)
240
- except self.model.DoesNotExist:
241
- raise DeserializationError("Instrument id does not match an existing instrument")
240
+ except self.model.DoesNotExist as e:
241
+ raise DeserializationError("Instrument id does not match an existing instrument") from e
242
242
  else:
243
243
  return self.instrument_lookup.lookup(only_security=only_security, **data)
244
244
 
@@ -1,4 +1,5 @@
1
1
  import json
2
+ from contextlib import suppress
2
3
 
3
4
  from wbcore.contrib.geography.models import Geography
4
5
 
@@ -44,14 +45,12 @@ def parse(import_source):
44
45
  d["headquarter_address"] = f"{street}, {postal_code} {city_name}"
45
46
 
46
47
  if sector_id := summary.get("sectorId", None):
47
- try:
48
+ with suppress(Exception):
48
49
  code_aggregated = f"{int(sector_id):03}"
49
50
  if industry_id := summary.get("industryId", None):
50
51
  code_aggregated += f"{int(industry_id):03}"
51
52
  if subindustry_id := summary.get("subindustryId", None):
52
53
  code_aggregated += f"{int(subindustry_id):03}"
53
- except Exception:
54
- pass
55
54
  d["classifications"] = [{"code_aggregated": code_aggregated, "group": cbinsight_group.id}]
56
55
  data.append(d)
57
56
  return {"data": data}
@@ -3,5 +3,6 @@ from jinjasql import JinjaSql # type: ignore
3
3
 
4
4
 
5
5
  def get_environment(**options):
6
- env = Environment(**options)
6
+ # we except only SQL template, so we need to not escape special characters (possible XSS attack for HTML template)
7
+ env = Environment(**options) # noqa: S701
7
8
  return JinjaSql(env=env, param_style="format").env
@@ -56,6 +56,9 @@ class Controversy(models.Model):
56
56
  review = models.DateField(verbose_name="Reviewed", null=True, blank=True)
57
57
  initiated = models.DateField(verbose_name="initiated", null=True, blank=True)
58
58
 
59
+ def __str__(self) -> str:
60
+ return f"{self.headline} ({self.instrument})"
61
+
59
62
  @classmethod
60
63
  def dict_to_model(cls, controversy: dict[str, Any], instrument) -> Self:
61
64
  return Controversy(
@@ -23,7 +23,7 @@ class CompositeKey(models.AutoField):
23
23
  def __init__(self, columns: list[str], db_column_ref: str | None = None, *args, **kwargs):
24
24
  self.columns = columns
25
25
  self.db_column_ref = db_column_ref
26
- super().__init__(primary_key=True, *args, **kwargs)
26
+ super().__init__(*args, primary_key=True, **kwargs)
27
27
 
28
28
  def contribute_to_class(self, cls, name, private_only=False):
29
29
  self.set_attributes_from_name(name)
@@ -108,7 +108,7 @@ class Exact(models.Lookup):
108
108
 
109
109
  lookups = [
110
110
  lookup_class(field.get_col(self.lhs.alias), self.rhs[column])
111
- for lookup_class, field, column in zip(lookup_classes, fields, self.lhs.field.columns)
111
+ for lookup_class, field, column in zip(lookup_classes, fields, self.lhs.field.columns, strict=False)
112
112
  ]
113
113
 
114
114
  value_constraint = WhereNode()
@@ -93,7 +93,7 @@ class CompositeForeignKey(ForeignObject):
93
93
  kwargs["on_delete"] = self.override_on_delete(kwargs["on_delete"])
94
94
 
95
95
  kwargs["to_fields"], kwargs["from_fields"] = zip(
96
- *((k, v.value) for k, v in self._raw_fields.items() if v.is_local_field)
96
+ *((k, v.value) for k, v in self._raw_fields.items() if v.is_local_field), strict=False
97
97
  )
98
98
  super().__init__(to, **kwargs)
99
99
 
@@ -220,7 +220,7 @@ class CompositeForeignKey(ForeignObject):
220
220
 
221
221
  def _check_nullifequal_fields_exists(self):
222
222
  res = []
223
- for field_name, value in self.null_if_equal:
223
+ for field_name, _ in self.null_if_equal:
224
224
  try:
225
225
  self.model._meta.get_field(field_name)
226
226
  except FieldDoesNotExist:
@@ -269,7 +269,7 @@ class CompositeForeignKey(ForeignObject):
269
269
 
270
270
  return OrderedDict(
271
271
  (k, (v if isinstance(v, CompositePart) else LocalFieldValue(v)))
272
- for k, v in (to_fields.items() if isinstance(to_fields, dict) else zip(to_fields, to_fields))
272
+ for k, v in (to_fields.items() if isinstance(to_fields, dict) else zip(to_fields, to_fields, strict=False))
273
273
  )
274
274
 
275
275
  def db_type(self, connection):
@@ -162,6 +162,9 @@ class RelatedInstrumentThroughModel(models.Model):
162
162
  class Meta:
163
163
  unique_together = ("instrument", "related_instrument", "is_primary", "related_type")
164
164
 
165
+ def __str__(self) -> str:
166
+ return f"{self.instrument} - {self.related_instrument} ({self.related_type})"
167
+
165
168
  def save(self, *args, **kwargs):
166
169
  qs = RelatedInstrumentThroughModel.objects.filter(
167
170
  instrument=self.instrument, related_type=self.related_type, is_primary=True
@@ -205,38 +205,38 @@ class InstrumentType(models.Model):
205
205
 
206
206
  @classmethod
207
207
  @property
208
- def PRODUCT(cls):
208
+ def PRODUCT(cls): # noqa
209
209
  return InstrumentType.objects.get_or_create(
210
210
  key="product", defaults={"name": "Product", "short_name": "Product"}
211
211
  )[0]
212
212
 
213
213
  @classmethod
214
214
  @property
215
- def EQUITY(cls):
215
+ def EQUITY(cls): # noqa
216
216
  return InstrumentType.objects.get_or_create(key="equity", defaults={"name": "equity", "short_name": "equity"})[
217
217
  0
218
218
  ]
219
219
 
220
220
  @classmethod
221
221
  @property
222
- def INDEX(cls):
222
+ def INDEX(cls): # noqa
223
223
  return InstrumentType.objects.get_or_create(key="index", defaults={"name": "Index", "short_name": "Index"})[0]
224
224
 
225
225
  @classmethod
226
226
  @property
227
- def CASH(cls):
227
+ def CASH(cls): # noqa
228
228
  return InstrumentType.objects.get_or_create(key="cash", defaults={"name": "Cash", "short_name": "Cash"})[0]
229
229
 
230
230
  @classmethod
231
231
  @property
232
- def CASHEQUIVALENT(cls):
232
+ def CASHEQUIVALENT(cls): # noqa
233
233
  return InstrumentType.objects.get_or_create(
234
234
  key="cash_equivalent", defaults={"name": "Cash Equivalents", "short_name": "Cash Equivalents"}
235
235
  )[0]
236
236
 
237
237
  @classmethod
238
238
  @property
239
- def PRODUCT_GROUP(cls):
239
+ def PRODUCT_GROUP(cls): # noqa
240
240
  return InstrumentType.objects.get_or_create(
241
241
  key="product_group", defaults={"name": "Product Group", "short_name": "Product Group"}
242
242
  )[0]
@@ -63,7 +63,7 @@ class InstrumentPMSMixin:
63
63
  market_capitalization=price.market_capitalization,
64
64
  outstanding_shares=float(price.outstanding_shares) if price.outstanding_shares else None,
65
65
  )
66
- except InstrumentPrice.DoesNotExist:
66
+ except InstrumentPrice.DoesNotExist as e:
67
67
  prices = sorted(
68
68
  self.get_prices(from_date=(val_date - BDay(price_date_timedelta)).date(), to_date=val_date),
69
69
  key=lambda x: x["valuation_date"],
@@ -87,7 +87,7 @@ class InstrumentPMSMixin:
87
87
  market_capitalization=p.get("market_capitalization", None),
88
88
  outstanding_shares=p.get("outstanding_shares", None),
89
89
  )
90
- raise ValueError("Not price was found")
90
+ raise ValueError("Not price was found") from e
91
91
 
92
92
  # Instrument Prices Utility Functions
93
93
  @classmethod
@@ -143,6 +143,9 @@ class OptionAggregate(BaseOptionAbstractModel):
143
143
  ),
144
144
  ]
145
145
 
146
+ def __str__(self) -> str:
147
+ return f"{self.instrument} - {self.date} - {self.type}"
148
+
146
149
 
147
150
  class Option(BaseOptionAbstractModel):
148
151
  import_export_handler_class = OptionImportHandler
@@ -224,3 +227,6 @@ class Option(BaseOptionAbstractModel):
224
227
  fields=["type"],
225
228
  ),
226
229
  ]
230
+
231
+ def __str__(self):
232
+ return f"{self.contract_identifier} - {self.date} - {self.type}"
@@ -58,3 +58,6 @@ class Deal(ImportMixin, models.Model):
58
58
  null=True,
59
59
  help_text="List of URLs used to source the valuation for the Media Mentions source type.",
60
60
  )
61
+
62
+ def __str__(self) -> str:
63
+ return f"{self.equity} - {self.date}"
@@ -384,7 +384,6 @@ class TestStatementWithEstimates:
384
384
  "shares_outstanding",
385
385
  "market_capitalization",
386
386
  "close",
387
- "market_capitalization",
388
387
  "net_cash",
389
388
  "period_end_date",
390
389
  "estimate",
@@ -52,7 +52,9 @@ class ClassifiedInstrumentDisplayConfig(DisplayViewConfig):
52
52
  if group := self.view.classification_group:
53
53
  fields = [dp.Field(key="instrument", label="Instrument")]
54
54
  level_representations = group.get_levels_representation()
55
- for key, label in zip(reversed(group.get_fields_names(sep="_")), reversed(level_representations[1:])):
55
+ for key, label in zip(
56
+ reversed(group.get_fields_names(sep="_")), reversed(level_representations[1:]), strict=False
57
+ ):
56
58
  fields.append(
57
59
  dp.Field(key=f"classification_{key}", label=label),
58
60
  )
@@ -31,7 +31,8 @@ class MonthlyPerformancesInstrumentTitleConfig(TitleViewConfig):
31
31
 
32
32
  class InstrumentTitleConfigMixin(TitleViewConfig):
33
33
  def get_list_title(self):
34
- assert self.message, "No message has been set"
34
+ if not self.message:
35
+ raise AssertionError("No message has been set")
35
36
  instrument = Instrument.objects.get(id=self.view.kwargs["instrument_id"])
36
37
  return f"{self.message} {str(instrument)}"
37
38
 
@@ -66,8 +66,8 @@ class InstrumentESGPAIViewSet(InstrumentMixin, ExportPandasAPIViewSet):
66
66
  def get_dataframe(self, request, queryset, **kwargs):
67
67
  df = pd.DataFrame(queryset.dl.esg(values=list(ESG))).reset_index()
68
68
  if not df.empty:
69
- ESG_mapping = ESG.mapping()
69
+ esg_mapping = ESG.mapping()
70
70
  df[["section", "asi", "metric", "factor"]] = pd.DataFrame(
71
- df.factor_code.map(ESG_mapping).tolist(), index=df.index
71
+ df.factor_code.map(esg_mapping).tolist(), index=df.index
72
72
  )
73
73
  return df