wbfdm 1.44.0__py2.py3-none-any.whl → 1.44.1__py2.py3-none-any.whl

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.

@@ -1,4 +1,5 @@
1
1
  import pandas as pd
2
+ from django.contrib.messages import warning
2
3
  from django.utils.functional import cached_property
3
4
  from wbcore.contrib.io.viewsets import ExportPandasAPIViewSet
4
5
  from wbcore.metadata.configs.endpoints import NoEndpointViewConfig
@@ -40,6 +41,11 @@ class FinancialSummary(InstrumentMixin, ExportPandasAPIViewSet):
40
41
  ]
41
42
  )
42
43
 
44
+ def add_messages(self, request, instance=None, **kwargs):
45
+ super().add_messages(request, instance=instance, **kwargs)
46
+ if self.df.empty:
47
+ warning(request, "There is no data available for the Financial Summary table", extra_tags="auto_close=0")
48
+
43
49
  def get_dataframe(self, request, queryset, **kwargs):
44
50
  # Get all necessary data from the dataloader and load a dataframe
45
51
  df = pd.DataFrame(
@@ -49,123 +55,127 @@ class FinancialSummary(InstrumentMixin, ExportPandasAPIViewSet):
49
55
  to_index=3,
50
56
  )
51
57
  )
58
+ if not df.empty:
59
+ # Pivot the data
60
+ df = df.pivot_table(
61
+ columns="financial",
62
+ index=["year", "period_end_date", "estimate"],
63
+ values="value",
64
+ ).rename_axis(columns=None)
52
65
 
53
- # Pivot the data
54
- df = df.pivot_table(
55
- columns="financial",
56
- index=["year", "period_end_date", "estimate"],
57
- values="value",
58
- ).rename_axis(columns=None)
59
-
60
- sanitize_fields(df, map(lambda enum: enum.value, self.FINANCIAL_VALUES))
66
+ sanitize_fields(df, map(lambda enum: enum.value, self.FINANCIAL_VALUES))
61
67
 
62
- # Compute all necessary fields
63
- df["revenue_growth"] = df["revenue"].pct_change() * 100
64
- df["gross_profit_pct"] = df["gross_profit"] / df["revenue"] * 100
65
- df["ebitda_pct"] = df["ebitda"] / df["revenue"] * 100
66
- df["ebit_pct"] = df["ebit"] / df["revenue"] * 100
67
- df["net_income_pct"] = df["net_income"] / df["revenue"] * 100
68
- df["eps_growth"] = pct_change_with_negative_values(df, "eps") * 100
68
+ # Compute all necessary fields
69
+ df["revenue_growth"] = df["revenue"].pct_change() * 100
70
+ df["gross_profit_pct"] = df["gross_profit"] / df["revenue"] * 100
71
+ df["ebitda_pct"] = df["ebitda"] / df["revenue"] * 100
72
+ df["ebit_pct"] = df["ebit"] / df["revenue"] * 100
73
+ df["net_income_pct"] = df["net_income"] / df["revenue"] * 100
74
+ df["eps_growth"] = pct_change_with_negative_values(df, "eps") * 100
69
75
 
70
- df["net_debt_ebitda"] = df["net_debt"] / df["ebitda"]
71
- df["debt_assets"] = df["total_debt"] / df["total_assets"] * 100
72
- df["debt_equity"] = df["total_debt"] / df["total_assets"] * 100
76
+ df["net_debt_ebitda"] = df["net_debt"] / df["ebitda"]
77
+ df["debt_assets"] = df["total_debt"] / df["total_assets"] * 100
78
+ df["debt_equity"] = df["total_debt"] / df["total_assets"] * 100
73
79
 
74
- df["interest_coverage_ratio"] = df["ebit"] / df["interest_expense"]
75
- df["free_cash_flow_per_share"] = df["free_cash_flow"] / df["shares_outstanding"]
76
- df["free_cash_flow_per_share_growth"] = pct_change_with_negative_values(df, "free_cash_flow_per_share") * 100
80
+ df["interest_coverage_ratio"] = df["ebit"] / df["interest_expense"]
81
+ df["free_cash_flow_per_share"] = df["free_cash_flow"] / df["shares_outstanding"]
82
+ df["free_cash_flow_per_share_growth"] = (
83
+ pct_change_with_negative_values(df, "free_cash_flow_per_share") * 100
84
+ )
77
85
 
78
- # Normalize data
79
- df["revenue"] = df["revenue"] / 1_000_000
80
- df["net_income"] = df["net_income"] / 1_000_000
86
+ # Normalize data
87
+ df["revenue"] = df["revenue"] / 1_000_000
88
+ df["net_income"] = df["net_income"] / 1_000_000
81
89
 
82
- # Sort the columns into the desired order
83
- # Reset the index to get the period end date as a column
84
- # Pivot back to have the dates on top
85
- df = df[self.FIELDS]
90
+ # Sort the columns into the desired order
91
+ # Reset the index to get the period end date as a column
92
+ # Pivot back to have the dates on top
93
+ df = df[self.FIELDS]
86
94
 
87
- # Reset the 2 indices and transpose back
88
- df = df.reset_index(level=[0, 2]).sort_index()
95
+ # Reset the 2 indices and transpose back
96
+ df = df.reset_index(level=[0, 2]).sort_index()
89
97
 
90
- # Adjust the columns to be in a different format
91
- df.index = df.index.map(lambda x: x.strftime("%b/%y"))
92
- MAX_ROW = 8
93
- if df.shape[0] > MAX_ROW:
94
- df = df.iloc[1:] # remove first row
95
- df = df.iloc[0 : min([df.shape[0], MAX_ROW])] # keep only 8 row maximum
98
+ # Adjust the columns to be in a different format
99
+ df.index = df.index.map(lambda x: x.strftime("%b/%y"))
100
+ MAX_ROW = 8
101
+ if df.shape[0] > MAX_ROW:
102
+ df = df.iloc[1:] # remove first row
103
+ df = df.iloc[0 : min([df.shape[0], MAX_ROW])] # keep only 8 row maximum
96
104
 
97
- self._estimate_columns = df["estimate"].to_dict()
98
- df = df.drop(columns=["estimate"], errors="ignore")
105
+ self._estimate_columns = df["estimate"].to_dict()
106
+ df = df.drop(columns=["estimate"], errors="ignore")
99
107
  return df
100
108
 
101
109
  def manipulate_dataframe(self, df):
102
- df = df.T
103
- # Add labels for human readable output
104
- df["label"] = self.LABELS
110
+ if not df.empty:
111
+ df = df.T
112
+ # Add labels for human readable output
113
+ df["label"] = self.LABELS
105
114
 
106
- override_number_to_percent(
107
- df,
108
- *list(
109
- map(
110
- lambda x: df.index == x,
111
- [
112
- "revenue_growth",
113
- "gross_profit_pct",
114
- "ebitda_pct",
115
- "ebit_pct",
116
- "net_income_pct",
117
- "eps_growth",
118
- "roe",
119
- "roic",
120
- "roc",
121
- "roa",
122
- "debt_equity",
123
- "debt_assets",
124
- "free_cash_flow_per_share_growth",
125
- ],
126
- )
127
- ),
128
- )
115
+ override_number_to_percent(
116
+ df,
117
+ *list(
118
+ map(
119
+ lambda x: df.index == x,
120
+ [
121
+ "revenue_growth",
122
+ "gross_profit_pct",
123
+ "ebitda_pct",
124
+ "ebit_pct",
125
+ "net_income_pct",
126
+ "eps_growth",
127
+ "roe",
128
+ "roic",
129
+ "roc",
130
+ "roa",
131
+ "debt_equity",
132
+ "debt_assets",
133
+ "free_cash_flow_per_share_growth",
134
+ ],
135
+ )
136
+ ),
137
+ )
129
138
 
130
- override_number_to_x(
131
- df,
132
- *list(
133
- map(
134
- lambda x: df.index == x,
135
- [
136
- "net_debt_ebitda",
137
- "interest_coverage_ratio",
138
- ],
139
- )
140
- ),
141
- )
139
+ override_number_to_x(
140
+ df,
141
+ *list(
142
+ map(
143
+ lambda x: df.index == x,
144
+ [
145
+ "net_debt_ebitda",
146
+ "interest_coverage_ratio",
147
+ ],
148
+ )
149
+ ),
150
+ )
142
151
 
143
- override_number_to_decimal(
144
- df,
145
- *list(
146
- map(
147
- lambda x: df.index == x,
148
- [
149
- "revenue",
150
- "net_income",
151
- ],
152
- )
153
- ),
154
- )
152
+ override_number_to_decimal(
153
+ df,
154
+ *list(
155
+ map(
156
+ lambda x: df.index == x,
157
+ [
158
+ "revenue",
159
+ "net_income",
160
+ ],
161
+ )
162
+ ),
163
+ )
155
164
 
156
- override_number_to_integer_without_decorations(
157
- df,
158
- *list(
159
- map(
160
- lambda x: df.index == x,
161
- [
162
- "year",
163
- ],
164
- )
165
- ),
166
- )
165
+ override_number_to_integer_without_decorations(
166
+ df,
167
+ *list(
168
+ map(
169
+ lambda x: df.index == x,
170
+ [
171
+ "year",
172
+ ],
173
+ )
174
+ ),
175
+ )
167
176
 
168
- return df.reset_index(names="id")
177
+ df = df.reset_index(names="id")
178
+ return df
169
179
 
170
180
  @cached_property
171
181
  def fiscal_columns(self) -> list:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wbfdm
3
- Version: 1.44.0
3
+ Version: 1.44.1
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.*
@@ -334,7 +334,7 @@ wbfdm/viewsets/configs/titles/statement_with_estimates.py,sha256=ZL4K0hOM0dVBplu
334
334
  wbfdm/viewsets/financial_analysis/__init__.py,sha256=cTTcvGnhz2Ep9RpkyUyTOpjTXJz7BWt1AGAMjiIY9C8,263
335
335
  wbfdm/viewsets/financial_analysis/financial_metric_analysis.py,sha256=ZO3iUExFu5BUK8a_wRu9ldOvRKc70l8Jpdjl2_4hp7s,3315
336
336
  wbfdm/viewsets/financial_analysis/financial_ratio_analysis.py,sha256=YtsSJUnqHjTpiarZcqo14IhWDXF3UXc_zla-slDpqiU,3097
337
- wbfdm/viewsets/financial_analysis/financial_summary.py,sha256=IxCqGstwDQC4jfv_7111vbZ85FcBLXnhxrrsNOKNAg4,8434
337
+ wbfdm/viewsets/financial_analysis/financial_summary.py,sha256=GHXIBZ6lHmFGxqAT6YMVB7f86BsGu6K--CbUECj0xfY,9245
338
338
  wbfdm/viewsets/financial_analysis/statement_with_estimates.py,sha256=1GiSgKZR8iyNK6yJs79eLSt7bo60KQoTv4o3vBsc9xU,6098
339
339
  wbfdm/viewsets/instruments/__init__.py,sha256=uydDdU6oZ6W2lgFkr3-cU7WZU7TeokXAA1J0xEgiLD0,2826
340
340
  wbfdm/viewsets/instruments/classifications.py,sha256=pDQG9rlXUbc4LvWgVOGTir0Dcp02z-78AODNH-SjynA,11440
@@ -349,6 +349,6 @@ wbfdm/viewsets/statements/__init__.py,sha256=odxtFYUDICPmz8WCE3nx93EvKZLSPBEI4d7
349
349
  wbfdm/viewsets/statements/statements.py,sha256=AVU5A7p63uWITEcMDl95iKyN-fBO5RwJlbxHrJZvz7o,4083
350
350
  wbfdm/viewsets/technical_analysis/__init__.py,sha256=qtCIBg0uSiZeJq_1tEQFilnorMBkMe6uCMfqar6-cLE,77
351
351
  wbfdm/viewsets/technical_analysis/monthly_performances.py,sha256=8VgafjW4efEJKTfBqUvAu-EG2eNawl2Cmh9QFt4sN8w,3973
352
- wbfdm-1.44.0.dist-info/METADATA,sha256=hQLhyfFZ2TSrNlm_G9_u0VLVdUPmz11yuuFuJq0fTJo,736
353
- wbfdm-1.44.0.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
354
- wbfdm-1.44.0.dist-info/RECORD,,
352
+ wbfdm-1.44.1.dist-info/METADATA,sha256=DI-CEs_MXLDyJDmT3IotMf4wBDpD9CVO8Y2_-ghaQfU,736
353
+ wbfdm-1.44.1.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
354
+ wbfdm-1.44.1.dist-info/RECORD,,
File without changes