neurostats-API 0.0.22__tar.gz → 0.0.23__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.
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/PKG-INFO +2 -2
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/README.md +1 -1
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/__init__.py +1 -1
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/fetchers/balance_sheet.py +59 -36
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/fetchers/base.py +6 -2
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/fetchers/cash_flow.py +87 -66
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/fetchers/finance_overview.py +26 -26
- neurostats_api-0.0.23/neurostats_API/fetchers/institution.py +413 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/fetchers/margin_trading.py +121 -94
- neurostats_api-0.0.23/neurostats_API/fetchers/month_revenue.py +195 -0
- neurostats_api-0.0.23/neurostats_API/fetchers/profit_lose.py +253 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/fetchers/tech.py +61 -26
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/fetchers/tej_finance_report.py +23 -8
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/fetchers/value_invest.py +32 -12
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/tools/tej_db/tej_db_percent_index.yaml +0 -3
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/tools/tej_db/tej_db_skip_index.yaml +12 -1
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/tools/tej_db/tej_db_thousand_index.yaml +0 -4
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/utils/calculate_value.py +5 -2
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/utils/data_process.py +11 -5
- neurostats_api-0.0.23/neurostats_API/utils/logger.py +21 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API.egg-info/PKG-INFO +2 -2
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API.egg-info/SOURCES.txt +1 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/setup.py +1 -1
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/test/test_fetchers.py +5 -5
- neurostats_api-0.0.22/neurostats_API/fetchers/institution.py +0 -299
- neurostats_api-0.0.22/neurostats_API/fetchers/month_revenue.py +0 -161
- neurostats_api-0.0.22/neurostats_API/fetchers/profit_lose.py +0 -233
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/MANIFEST.in +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/cli.py +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/fetchers/__init__.py +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/main.py +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/tools/company_list/tw.json +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/tools/tej_db/tej_db_index.yaml +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/tools/twse/balance_sheet.yaml +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/tools/twse/cash_flow_percentage.yaml +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/tools/twse/finance_overview_dict.yaml +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/tools/twse/profit_lose.yaml +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/tools/twse/seasonal_data_field_dict.txt +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/utils/__init__.py +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/utils/datetime.py +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API/utils/db_client.py +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API.egg-info/dependency_links.txt +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API.egg-info/requires.txt +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/neurostats_API.egg-info/top_level.txt +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/setup.cfg +0 -0
- {neurostats_api-0.0.22 → neurostats_api-0.0.23}/test/test_tej.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: neurostats_API
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.23
|
4
4
|
Summary: The service of NeuroStats website
|
5
5
|
Home-page: https://github.com/NeurowattStats/NeuroStats_API.git
|
6
6
|
Author: JasonWang@Neurowatt
|
@@ -89,7 +89,7 @@ pip install neurostats-API
|
|
89
89
|
```Python
|
90
90
|
>>> import neurostats_API
|
91
91
|
>>> print(neurostats_API.__version__)
|
92
|
-
0.0.
|
92
|
+
0.0.23
|
93
93
|
```
|
94
94
|
|
95
95
|
### 得到最新一期的評價資料與歷年評價
|
@@ -19,32 +19,43 @@ class BalanceSheetFetcher(StatsFetcher):
|
|
19
19
|
"us_stats": self.process_data_us
|
20
20
|
}
|
21
21
|
|
22
|
+
self.return_keys = [
|
23
|
+
'balance_sheet', 'total_asset', 'current_asset', 'non_current_asset',
|
24
|
+
'current_debt', 'non_current_debt', 'equity', 'balance_sheet_all', 'balance_sheet_YoY'
|
25
|
+
]
|
26
|
+
|
22
27
|
def prepare_query(self):
|
23
28
|
pipeline = super().prepare_query()
|
24
29
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
30
|
+
name_map = {
|
31
|
+
"twse_stats": "balance_sheet",
|
32
|
+
"us_stats": "balance_sheet"
|
33
|
+
}
|
34
|
+
|
35
|
+
|
36
|
+
chart_name = name_map.get(self.collection_name, "balance_sheet")
|
37
|
+
|
38
|
+
append_pipeline = [
|
39
|
+
{
|
40
|
+
"$project": {
|
41
|
+
"_id": 0,
|
42
|
+
"ticker": 1,
|
43
|
+
"company_name": 1,
|
44
|
+
"seasonal_data": {
|
45
|
+
"$map": {
|
46
|
+
"input": {"$ifNull": ["$seasonal_data", []]},
|
47
|
+
"as": "season",
|
48
|
+
"in": {
|
49
|
+
"year": "$$season.year",
|
50
|
+
"season": "$$season.season",
|
51
|
+
"data": {"$ifNull": [f"$$season.{chart_name}", []]}
|
52
|
+
}
|
53
|
+
}
|
45
54
|
}
|
46
55
|
}
|
47
|
-
|
56
|
+
}
|
57
|
+
]
|
58
|
+
pipeline = pipeline + append_pipeline
|
48
59
|
|
49
60
|
return pipeline
|
50
61
|
|
@@ -53,6 +64,7 @@ class BalanceSheetFetcher(StatsFetcher):
|
|
53
64
|
|
54
65
|
def query_data(self):
|
55
66
|
fetched_data = self.collect_data()
|
67
|
+
fetched_data = fetched_data[0]
|
56
68
|
|
57
69
|
process_fn = self.process_function_map[self.collection_name]
|
58
70
|
processed_data = process_fn(fetched_data)
|
@@ -72,14 +84,19 @@ class BalanceSheetFetcher(StatsFetcher):
|
|
72
84
|
|
73
85
|
return_dict = {
|
74
86
|
"ticker": self.ticker,
|
75
|
-
"company_name": fetched_data[
|
87
|
+
"company_name": fetched_data['company_name']
|
76
88
|
}
|
77
89
|
table_dict = {}
|
78
90
|
|
91
|
+
seasonal_data = fetched_data.get('seasonal_data')
|
92
|
+
if not seasonal_data:
|
93
|
+
return_dict.update(self._get_empty_structure())
|
94
|
+
return return_dict
|
95
|
+
|
79
96
|
# 將value與percentage跟著年分季度一筆筆取出
|
80
|
-
for data in
|
97
|
+
for data in seasonal_data:
|
81
98
|
year, season, balance_sheet = data['year'], data['season'], data[
|
82
|
-
'
|
99
|
+
'data']
|
83
100
|
time_index = f"{year}Q{season}"
|
84
101
|
|
85
102
|
new_balance_sheet = dict()
|
@@ -96,35 +113,37 @@ class BalanceSheetFetcher(StatsFetcher):
|
|
96
113
|
old_balance_sheet = old_balance_sheet.loc[:, target_season_col]
|
97
114
|
old_balance_sheet = StatsProcessor.expand_value_percentage(old_balance_sheet)
|
98
115
|
|
116
|
+
# 處理QoQ版BalanceSheet
|
99
117
|
for time_index, data_dict in table_dict.items():
|
100
118
|
new_balance_sheet = self.flatten_dict(
|
101
|
-
|
119
|
+
data_dict,
|
102
120
|
indexes = index_names,
|
103
121
|
target_keys=["value", "percentage"]
|
104
122
|
)
|
105
123
|
|
106
124
|
table_dict[time_index] = new_balance_sheet
|
107
125
|
|
108
|
-
total_table = pd.DataFrame.from_dict(table_dict)
|
109
|
-
value_index = total_table.
|
110
|
-
total_table.loc[value_index
|
111
|
-
|
112
|
-
|
113
|
-
|
126
|
+
total_table = pd.DataFrame.from_dict(table_dict).T
|
127
|
+
value_index = total_table.columns.str.endswith("_value")
|
128
|
+
value_cols = total_table.loc[:, value_index].columns
|
129
|
+
total_table[value_cols] = (
|
130
|
+
total_table[value_cols].map(
|
131
|
+
lambda x: StatsProcessor.cal_non_percentage(x, postfix="千元"),
|
114
132
|
)
|
115
133
|
)
|
116
134
|
|
117
|
-
|
135
|
+
percentage_index = total_table.columns.str.endswith(
|
118
136
|
"_percentage"
|
119
137
|
)
|
120
|
-
total_table.loc[
|
121
|
-
|
138
|
+
percentage_cols = total_table.loc[:, percentage_index].columns
|
139
|
+
total_table[percentage_cols] = (
|
140
|
+
total_table[percentage_cols].map(
|
122
141
|
lambda x: StatsProcessor.
|
123
142
|
cal_non_percentage(x, to_str=True, postfix="%"),
|
124
|
-
axis=0
|
125
143
|
)
|
126
144
|
)
|
127
145
|
|
146
|
+
total_table = total_table.T
|
128
147
|
target_season_columns = total_table.columns.str.endswith(
|
129
148
|
f"Q{target_season}"
|
130
149
|
)
|
@@ -140,7 +159,6 @@ class BalanceSheetFetcher(StatsFetcher):
|
|
140
159
|
)
|
141
160
|
break
|
142
161
|
except Exception as e:
|
143
|
-
print(f"error : {str(e)}")
|
144
162
|
continue
|
145
163
|
|
146
164
|
return_dict.update(
|
@@ -176,3 +194,8 @@ class BalanceSheetFetcher(StatsFetcher):
|
|
176
194
|
table_dict_YoY = table_dict.loc[:, target_season_columns]
|
177
195
|
return_dict["balance_sheet_YoY"] = table_dict_YoY
|
178
196
|
return return_dict
|
197
|
+
|
198
|
+
def _get_empty_structure(self):
|
199
|
+
return {
|
200
|
+
key: pd.DataFrame(columns= pd.Index([], name = 'date')) for key in self.return_keys
|
201
|
+
}
|
@@ -97,8 +97,12 @@ class BaseTEJFetcher(abc.ABC):
|
|
97
97
|
}
|
98
98
|
)
|
99
99
|
|
100
|
-
|
101
|
-
|
100
|
+
if (latest_data):
|
101
|
+
# return 得到最新日期或None
|
102
|
+
return latest_data.get('last_update', {}).get("latest_data_date", None)
|
103
|
+
|
104
|
+
else:
|
105
|
+
return None
|
102
106
|
|
103
107
|
def process_value(self, value):
|
104
108
|
if isinstance(value, str) and "%" in value:
|
@@ -18,6 +18,8 @@ class CashFlowFetcher(StatsFetcher):
|
|
18
18
|
"twse_stats": self.process_data_twse,
|
19
19
|
"us_stats": self.process_data_us
|
20
20
|
}
|
21
|
+
|
22
|
+
self.return_keys = ['cash_flow', 'CASHO', 'CASHI', 'CASHF', 'cash_flow_all', 'cash_flow_YoY']
|
21
23
|
|
22
24
|
def prepare_query(self):
|
23
25
|
pipeline = super().prepare_query()
|
@@ -31,28 +33,25 @@ class CashFlowFetcher(StatsFetcher):
|
|
31
33
|
chart_name = name_map.get(self.collection_name, "cash_flow")
|
32
34
|
|
33
35
|
append_pipeline = [
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
"
|
39
|
-
|
40
|
-
"
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
{
|
50
|
-
"$sort": {
|
51
|
-
"year": -1,
|
52
|
-
"season": -1
|
36
|
+
{
|
37
|
+
"$project": {
|
38
|
+
"_id": 0,
|
39
|
+
"ticker": 1,
|
40
|
+
"company_name": 1,
|
41
|
+
"seasonal_data": {
|
42
|
+
"$map": {
|
43
|
+
"input": {"$ifNull": ["$seasonal_data", []]},
|
44
|
+
"as": "season",
|
45
|
+
"in": {
|
46
|
+
"year": "$$season.year",
|
47
|
+
"season": "$$season.season",
|
48
|
+
"data": {"$ifNull": [f"$$season.{chart_name}", []]}
|
49
|
+
}
|
50
|
+
}
|
53
51
|
}
|
54
52
|
}
|
55
|
-
|
53
|
+
}
|
54
|
+
]
|
56
55
|
|
57
56
|
pipeline = pipeline + append_pipeline
|
58
57
|
|
@@ -63,6 +62,7 @@ class CashFlowFetcher(StatsFetcher):
|
|
63
62
|
|
64
63
|
def query_data(self):
|
65
64
|
fetched_data = self.collect_data()
|
65
|
+
fetched_data = fetched_data[0]
|
66
66
|
|
67
67
|
process_fn = self.process_function_map.get(self.collection_name, self.process_data_us)
|
68
68
|
return process_fn(fetched_data)
|
@@ -78,27 +78,36 @@ class CashFlowFetcher(StatsFetcher):
|
|
78
78
|
index_names = []
|
79
79
|
column_names = []
|
80
80
|
|
81
|
-
table_dict =
|
82
|
-
CASHO_dict =
|
83
|
-
CASHI_dict =
|
84
|
-
CASHF_dict =
|
81
|
+
table_dict = {}
|
82
|
+
CASHO_dict = {}
|
83
|
+
CASHI_dict = {}
|
84
|
+
CASHF_dict = {}
|
85
85
|
|
86
86
|
# 處理cash_flow 比例
|
87
87
|
checkpoints = ["營業活動之現金流量-間接法", "投資活動之現金流量", "籌資活動之現金流量", "匯率變動對現金及約當現金之影響"]
|
88
88
|
main_cash_flows = [
|
89
|
-
"營業活動之淨現金流入(流出)", "投資活動之淨現金流入(流出)", "籌資活動之淨現金流入(流出)",
|
89
|
+
"營業活動之淨現金流入(流出)", "投資活動之淨現金流入(流出)", "籌資活動之淨現金流入(流出)", "其他"
|
90
90
|
] # 主要的比例對象
|
91
91
|
partial_cash_flows = [CASHO_dict, CASHI_dict, CASHF_dict, dict()]
|
92
92
|
|
93
93
|
# 作法: dictionary中也有checkpoints,如果出現了就換下一個index去計算
|
94
94
|
|
95
|
-
|
96
|
-
|
95
|
+
return_dict = {
|
96
|
+
"ticker": self.ticker,
|
97
|
+
"company_name": fetched_data['company_name']
|
98
|
+
}
|
99
|
+
seasonal_data = fetched_data.get('seasonal_data')
|
100
|
+
if not seasonal_data:
|
101
|
+
return_dict.update(self._get_empty_structure())
|
102
|
+
return return_dict
|
103
|
+
|
104
|
+
for data in seasonal_data:
|
105
|
+
year, season, cash_flow = data['year'], data['season'], data['data']
|
97
106
|
|
98
107
|
time_index = f"{year}Q{season}"
|
99
108
|
|
100
|
-
main_cash_flow_name =
|
101
|
-
partial_cash_flow =
|
109
|
+
main_cash_flow_name = ""
|
110
|
+
partial_cash_flow = {}
|
102
111
|
next_checkpoint = 0
|
103
112
|
|
104
113
|
temp_dict = {}
|
@@ -110,34 +119,34 @@ class CashFlowFetcher(StatsFetcher):
|
|
110
119
|
partial_cash_flow = partial_cash_flows[next_checkpoint]
|
111
120
|
partial_cash_flow[time_index] = {}
|
112
121
|
next_checkpoint += 1
|
122
|
+
|
123
|
+
if main_cash_flow_name: # 有取得cash flow name再進行接下來的計算percentage
|
124
|
+
if (isinstance(cash_flow_value, dict)):
|
125
|
+
value = cash_flow_value.get('value', None)
|
126
|
+
else:
|
127
|
+
value = cash_flow_value
|
113
128
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
)
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
temp_dict[index_name] = {
|
136
|
-
"value" : value,
|
137
|
-
"percentage": ratio
|
138
|
-
}
|
139
|
-
|
140
|
-
partial_cash_flow[time_index][index_name] = temp_dict[index_name]
|
129
|
+
# 處理cashflow percentage部分(取2位 + 接%)
|
130
|
+
main_value = cash_flow.get(main_cash_flow_name, None)
|
131
|
+
if (isinstance(main_value, dict)):
|
132
|
+
main_value = main_value.get('value', None)
|
133
|
+
else:
|
134
|
+
pass
|
135
|
+
|
136
|
+
try:
|
137
|
+
ratio = np.round(
|
138
|
+
(value / main_value) * 100, 2
|
139
|
+
)
|
140
|
+
ratio = f"{ratio}%"
|
141
|
+
except:
|
142
|
+
ratio = None
|
143
|
+
|
144
|
+
value = StatsProcessor.cal_non_percentage(value, postfix="千元")
|
145
|
+
temp_dict[index_name] = {
|
146
|
+
"value" : value,
|
147
|
+
"percentage": ratio
|
148
|
+
}
|
149
|
+
partial_cash_flow[time_index][index_name] = temp_dict[index_name]
|
141
150
|
|
142
151
|
table_dict[time_index] = temp_dict
|
143
152
|
index_names += list(cash_flow.keys())
|
@@ -157,24 +166,31 @@ class CashFlowFetcher(StatsFetcher):
|
|
157
166
|
CASHF_table = pd.DataFrame(CASHF_dict)
|
158
167
|
CASHF_table = StatsProcessor.expand_value_percentage(CASHF_table)
|
159
168
|
|
160
|
-
|
161
|
-
|
162
|
-
cash_flow_flatten = pd.DataFrame.from_dict(table_dict)
|
169
|
+
# 回傳歷來格式
|
170
|
+
target_season = seasonal_data[0]['season']
|
163
171
|
|
164
|
-
|
165
|
-
|
172
|
+
cash_flow_flatten, cash_flow_flatten_YoY = self.flatten_twse(
|
173
|
+
table_dict, target_season, index_names
|
174
|
+
)
|
166
175
|
|
167
|
-
return_dict
|
168
|
-
"ticker": self.ticker,
|
169
|
-
"company_name": fetched_data[-1]['company_name'],
|
176
|
+
return_dict.update({
|
170
177
|
"cash_flow": cash_flow_table_stats,
|
171
178
|
"CASHO": CASHO_table,
|
172
179
|
"CASHI": CASHI_table,
|
173
180
|
"CASHF": CASHF_table,
|
174
181
|
"cash_flow_all": cash_flow_flatten,
|
175
|
-
"cash_flow_YoY":
|
176
|
-
}
|
182
|
+
"cash_flow_YoY": cash_flow_flatten_YoY
|
183
|
+
})
|
177
184
|
return return_dict
|
185
|
+
|
186
|
+
def flatten_twse(self, data_dict: dict, target_season: int, index_names: list):
|
187
|
+
for time_index in data_dict.keys():
|
188
|
+
data_dict[time_index] = self.flatten_dict(data_dict[time_index], index_names, target_keys=['value', 'percentage'])
|
189
|
+
cash_flow_flatten = pd.DataFrame.from_dict(data_dict)
|
190
|
+
|
191
|
+
target_season_column = cash_flow_flatten.columns.str.endswith(f"Q{target_season}")
|
192
|
+
|
193
|
+
return cash_flow_flatten, cash_flow_flatten.loc[:, target_season_column]
|
178
194
|
|
179
195
|
def process_data_us(self, fetched_data):
|
180
196
|
|
@@ -198,3 +214,8 @@ class CashFlowFetcher(StatsFetcher):
|
|
198
214
|
"cash_flow_YoY": cash_flow_df_YoY
|
199
215
|
}
|
200
216
|
return return_dict
|
217
|
+
|
218
|
+
def _get_empty_structure(self):
|
219
|
+
return {
|
220
|
+
key: pd.DataFrame(columns= pd.Index([], name = 'date')) for key in self.return_keys
|
221
|
+
}
|
@@ -196,7 +196,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
196
196
|
finance_dict['EBIT'] = StatsProcessor.cal_non_percentage(EBIT)
|
197
197
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
198
198
|
finance_dict['EBIT'] = None
|
199
|
-
print(f"Error calculating EBIT: {e}")
|
199
|
+
# print(f"Error calculating EBIT: {e}")
|
200
200
|
|
201
201
|
@classmethod
|
202
202
|
def cal_fcf(cls, finance_dict):
|
@@ -210,7 +210,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
210
210
|
finance_dict["fcf"] = StatsProcessor.cal_non_percentage(fcf)
|
211
211
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
212
212
|
finance_dict['fcf'] = None
|
213
|
-
print(f"Error calculating FCF: {e}")
|
213
|
+
# print(f"Error calculating FCF: {e}")
|
214
214
|
|
215
215
|
@classmethod
|
216
216
|
def cal_interest_bearing_debt(cls, finance_dict):
|
@@ -242,7 +242,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
242
242
|
finance_dict['eps'])
|
243
243
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
244
244
|
finance_dict['share_outstanding'] = None
|
245
|
-
print(f"share_outstanding failed because of {str(e)}")
|
245
|
+
# print(f"share_outstanding failed because of {str(e)}")
|
246
246
|
|
247
247
|
@classmethod
|
248
248
|
def cal_revenue_per_share(cls, finance_dict):
|
@@ -258,7 +258,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
258
258
|
revenue_per_share, False)
|
259
259
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
260
260
|
finance_dict['revenue_per_share'] = None
|
261
|
-
print(f"revenue_per_share failed because of {str(e)}")
|
261
|
+
# print(f"revenue_per_share failed because of {str(e)}")
|
262
262
|
|
263
263
|
@classmethod
|
264
264
|
def cal_gross_per_share(cls, finance_dict):
|
@@ -283,7 +283,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
283
283
|
|
284
284
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
285
285
|
finance_dict['gross_per_share'] = None
|
286
|
-
print(f"gross_per_share failed because of {str(e)}")
|
286
|
+
# print(f"gross_per_share failed because of {str(e)}")
|
287
287
|
|
288
288
|
@classmethod
|
289
289
|
def cal_operating_income_per_share(cls, finance_dict):
|
@@ -299,7 +299,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
299
299
|
operating_income_per_share)
|
300
300
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
301
301
|
finance_dict['operating_income_per_share'] = None
|
302
|
-
print(f"operating_income_per_share failed because of {str(e)}")
|
302
|
+
# print(f"operating_income_per_share failed because of {str(e)}")
|
303
303
|
|
304
304
|
@classmethod
|
305
305
|
def cal_operating_cash_flow_per_share(cls, finance_dict):
|
@@ -331,7 +331,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
331
331
|
fcf_per_share)
|
332
332
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
333
333
|
finance_dict['fcf_per_share'] = None
|
334
|
-
print(f"fcf_per_share failed because of {str(e)}")
|
334
|
+
# print(f"fcf_per_share failed because of {str(e)}")
|
335
335
|
|
336
336
|
# 盈利能力
|
337
337
|
|
@@ -375,7 +375,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
375
375
|
gross_over_asset)
|
376
376
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
377
377
|
finance_dict['gross_over_asset'] = None
|
378
|
-
print(f"營業毛利/總資產 failed because of {str(e)}")
|
378
|
+
# print(f"營業毛利/總資產 failed because of {str(e)}")
|
379
379
|
|
380
380
|
@classmethod
|
381
381
|
def cal_roce(cls, finance_dict):
|
@@ -392,7 +392,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
392
392
|
|
393
393
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
394
394
|
finance_dict['roce'] = None
|
395
|
-
print(f"ROCE failed because of {str(e)}")
|
395
|
+
# print(f"ROCE failed because of {str(e)}")
|
396
396
|
|
397
397
|
@classmethod
|
398
398
|
def cal_gross_profit_marginal(cls, finance_dict):
|
@@ -408,7 +408,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
408
408
|
gross_profit_margin)
|
409
409
|
except Exception as e:
|
410
410
|
finance_dict['gross_profit_margin'] = None
|
411
|
-
print(f"gross_profit_margin failed because of {str(e)}")
|
411
|
+
# print(f"gross_profit_margin failed because of {str(e)}")
|
412
412
|
|
413
413
|
@classmethod
|
414
414
|
def cal_operation_profit_rate(cls, finance_dict):
|
@@ -425,7 +425,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
425
425
|
operation_profit_rate)
|
426
426
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
427
427
|
finance_dict["operation_profit_rate"] = None
|
428
|
-
print(f"operation_profit failed because of {str(e)}")
|
428
|
+
# print(f"operation_profit failed because of {str(e)}")
|
429
429
|
|
430
430
|
@classmethod
|
431
431
|
def cal_operating_cash_flow_profit_rate(cls, finance_dict):
|
@@ -441,8 +441,8 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
441
441
|
operating_cash_flow_profit_rate)
|
442
442
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
443
443
|
finance_dict["operating_cash_flow_profit_rate"] = None
|
444
|
-
print(
|
445
|
-
|
444
|
+
# print(
|
445
|
+
# f"operating_cash_flow_profit_rate failed because of {str(e)}")
|
446
446
|
|
447
447
|
|
448
448
|
# 成長動能
|
@@ -466,7 +466,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
466
466
|
dso, to_str=True, postfix="日")
|
467
467
|
except Exception as e:
|
468
468
|
finance_dict['dso'] = None
|
469
|
-
print(f"Error calculating 應收帳款收現天數 because of {str(e)}")
|
469
|
+
# print(f"Error calculating 應收帳款收現天數 because of {str(e)}")
|
470
470
|
|
471
471
|
@classmethod
|
472
472
|
def cal_account_receive_over_revenue(cls, finance_dict):
|
@@ -498,7 +498,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
498
498
|
dpo, to_str=True, postfix="日")
|
499
499
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
500
500
|
finance_dict["dpo"] = None
|
501
|
-
print(f"應付帳款週轉天數 failed because of {str(e)}")
|
501
|
+
# print(f"應付帳款週轉天數 failed because of {str(e)}")
|
502
502
|
|
503
503
|
@classmethod
|
504
504
|
def cal_inventories_cycle_ratio(cls, finance_dict):
|
@@ -515,7 +515,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
515
515
|
inventories_cycle_ratio)
|
516
516
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
517
517
|
finance_dict["inventories_cycle_ratio"] = None
|
518
|
-
print(f"Error calculating 存貨周轉率 because of {str(e)}")
|
518
|
+
# print(f"Error calculating 存貨周轉率 because of {str(e)}")
|
519
519
|
|
520
520
|
@classmethod
|
521
521
|
def cal_dio(cls, finance_dict):
|
@@ -531,7 +531,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
531
531
|
dio, to_str=True, postfix="日")
|
532
532
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
533
533
|
finance_dict["dio"] = None
|
534
|
-
print(f"Error calculating 存貨週轉天數 because of {str(e)}")
|
534
|
+
# print(f"Error calculating 存貨週轉天數 because of {str(e)}")
|
535
535
|
|
536
536
|
@classmethod
|
537
537
|
def cal_inventories_revenue_ratio(cls, finance_dict):
|
@@ -548,7 +548,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
548
548
|
inventories_revenue_ratio)
|
549
549
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
550
550
|
finance_dict["inventories_revenue_ratio"] = None
|
551
|
-
print(f"Error calculating 存貨佔營收比率 because of {str(e)}")
|
551
|
+
# print(f"Error calculating 存貨佔營收比率 because of {str(e)}")
|
552
552
|
|
553
553
|
@classmethod
|
554
554
|
def cal_cash_of_conversion_cycle(cls, finance_dict):
|
@@ -609,7 +609,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
609
609
|
current_ratio)
|
610
610
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
611
611
|
finance_dict['current_ratio'] = None
|
612
|
-
print(f"Error calculating current ratio: {e}")
|
612
|
+
# print(f"Error calculating current ratio: {e}")
|
613
613
|
|
614
614
|
@classmethod
|
615
615
|
def cal_quick_ratio(cls, finance_dict):
|
@@ -625,7 +625,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
625
625
|
quick_ratio)
|
626
626
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
627
627
|
finance_dict['quick_ratio'] = None
|
628
|
-
print(f"Error calculating quick ratio: {e}")
|
628
|
+
# print(f"Error calculating quick ratio: {e}")
|
629
629
|
|
630
630
|
@classmethod
|
631
631
|
def cal_debt_to_equity_ratio(cls, finance_dict):
|
@@ -640,7 +640,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
640
640
|
debt_to_equity_ratio)
|
641
641
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
642
642
|
finance_dict['debt_to_equity_ratio'] = None
|
643
|
-
print(f"Error calculating debt to equity ratio: {e}")
|
643
|
+
# print(f"Error calculating debt to equity ratio: {e}")
|
644
644
|
|
645
645
|
@classmethod
|
646
646
|
def cal_net_debt_to_equity_ratio(cls, finance_dict):
|
@@ -657,7 +657,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
657
657
|
net_debt_to_equity_ratio)
|
658
658
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
659
659
|
finance_dict['net_debt_to_equity_ratio'] = None
|
660
|
-
print(f"Error calculating net debt to equity ratio: {e}")
|
660
|
+
# print(f"Error calculating net debt to equity ratio: {e}")
|
661
661
|
|
662
662
|
@classmethod
|
663
663
|
def cal_interest_coverage_ratio(cls, finance_dict):
|
@@ -672,7 +672,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
672
672
|
interest_coverage_ratio, to_str=True, postfix="倍")
|
673
673
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
674
674
|
finance_dict['interest_coverage_ratio'] = None
|
675
|
-
print(f"Error calculating interest coverage ratio: {e}")
|
675
|
+
# print(f"Error calculating interest coverage ratio: {e}")
|
676
676
|
|
677
677
|
@classmethod
|
678
678
|
def cal_debt_to_operating_cash_flow(cls, finance_dict):
|
@@ -687,7 +687,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
687
687
|
debt_to_operating_cash_flow)
|
688
688
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
689
689
|
finance_dict['debt_to_operating_cash_flow'] = None
|
690
|
-
print(f"Error calculating debt to operating cash flow: {e}")
|
690
|
+
# print(f"Error calculating debt to operating cash flow: {e}")
|
691
691
|
|
692
692
|
@classmethod
|
693
693
|
def cal_debt_to_free_cash_flow(cls, finance_dict):
|
@@ -702,7 +702,7 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
702
702
|
debt_to_free_cash_flow)
|
703
703
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
704
704
|
finance_dict['debt_to_free_cash_flow'] = None
|
705
|
-
print(f"Error calculating debt to free cash flow: {e}")
|
705
|
+
# print(f"Error calculating debt to free cash flow: {e}")
|
706
706
|
|
707
707
|
@classmethod
|
708
708
|
def cal_cash_flow_ratio(cls, finance_dict):
|
@@ -716,4 +716,4 @@ class FinanceOverviewProcessor(StatsProcessor):
|
|
716
716
|
cash_flow_ratio)
|
717
717
|
except (KeyError, ZeroDivisionError, TypeError) as e:
|
718
718
|
finance_dict['cash_flow_ratio'] = None
|
719
|
-
print(f"Error calculating cash flow ratio: {e}")
|
719
|
+
# print(f"Error calculating cash flow ratio: {e}")
|