-
Notifications
You must be signed in to change notification settings - Fork 0
/
report.py
159 lines (141 loc) · 4.08 KB
/
report.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
"""
Flask models
https://flask-sqlalchemy.palletsprojects.com/en/2.x/quickstart/
"""
import logging
from app.db import db
logger: logging.Logger = logging.getLogger(__name__)
class Report(db.Model):
"""
Report Model
"""
company_id: db.Column = db.Column(db.String(50), primary_key=True)
year: db.Column = db.Column(db.Integer, primary_key=True)
ebit: db.Column = db.Column(
db.Float(precision=10, asdecimal=True),
nullable=False,
default=0,
)
equity: db.Column = db.Column(
db.Float(precision=10, asdecimal=True),
nullable=False,
default=0,
)
retained_earnings: db.Column = db.Column(
db.Float(precision=10, asdecimal=True),
nullable=False,
default=0,
)
sales: db.Column = db.Column(
db.Float(precision=10, asdecimal=True),
nullable=False,
default=0,
)
total_assets: db.Column = db.Column(
db.Float(precision=10, asdecimal=True),
nullable=False,
default=0,
)
total_liabilities: db.Column = db.Column(
db.Float(precision=10, asdecimal=True),
nullable=False,
default=0,
)
def __repr__(self) -> str:
"""
String serializer.
"""
return f"<Report: {self.company_id} {self.year}>"
@property
def working_capital(self) -> float:
"""
The working capital calculation is:
>>> WC = Current Assets - Current Liabilities.
NOTE: It is assumed that the company has
no Non-Current Assets or Liabilities.
"""
return self.total_assets - self.total_liabilities
@property
def liquid_assets(self) -> float:
"""
Calculates the X1 ratio of the Altman Z-score.
"""
try:
return float(self.working_capital / self.total_assets)
except TypeError:
return 0.0
except ZeroDivisionError:
return 0.0
@property
def profitability(self) -> float:
"""
Calculates the X2 ratio of the Altman Z-score.
"""
try:
return float(self.retained_earnings / self.total_assets)
except TypeError:
return 0.0
except ZeroDivisionError:
return 0.0
@property
def return_of_total_assets(self) -> float:
"""
Calculates the X3 ratio of the Altman Z-score.
"""
try:
return float(self.ebit / self.total_assets)
except TypeError:
return 0.0
except ZeroDivisionError:
return 0.0
@property
def financial_leverage(self) -> float:
"""
Calculates the X4 ratio of the Altman Z-score.
"""
try:
return float(self.equity / self.total_liabilities)
except TypeError:
return 0.0
except ZeroDivisionError:
return 0.0
@property
def asset_turnover(self) -> float:
"""
Calculates the X5 ratio of the Altman Z-score.
"""
try:
return float(self.sales / self.total_assets)
except TypeError:
return 0.0
except ZeroDivisionError:
return 0.0
@property
def score(self) -> float:
"""
Calculates the Altman Z-score.
"""
return sum(
[
1.2 * self.liquid_assets,
1.4 * self.profitability,
3.3 * self.return_of_total_assets,
0.6 * self.financial_leverage,
1.0 * self.asset_turnover,
]
)
def to_json(self) -> dict:
"""
JSON serializer.
"""
return {
"id": self.company_id,
"year": int(self.year),
"equity": float(self.equity),
"retained_earnings": float(self.retained_earnings),
"sales": float(self.sales),
"total_assets": float(self.total_assets),
"total_liabilities": float(self.total_liabilities),
"score": float(self.score),
}
logger.info("Report model initialized: %s", Report)