neurostats-API 0.0.5__py3-none-any.whl → 0.0.7__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- neurostats_API/__init__.py +1 -1
- neurostats_API/fetchers/__init__.py +4 -0
- neurostats_API/fetchers/balance_sheet.py +122 -0
- neurostats_API/fetchers/cash_flow.py +181 -0
- neurostats_API/fetchers/finance_overview.py +3 -1
- neurostats_API/fetchers/month_revenue.py +92 -0
- neurostats_API/fetchers/profit_lose.py +131 -0
- neurostats_API/tools/balance_sheet.yaml +26 -0
- neurostats_API/tools/cash_flow_percentage.yaml +39 -0
- neurostats_API/tools/profit_lose.yaml +1 -1
- neurostats_API/utils/data_process.py +123 -3
- {neurostats_API-0.0.5.dist-info → neurostats_API-0.0.7.dist-info}/METADATA +144 -191
- neurostats_API-0.0.7.dist-info/RECORD +26 -0
- {neurostats_API-0.0.5.dist-info → neurostats_API-0.0.7.dist-info}/WHEEL +1 -1
- neurostats_API-0.0.5.dist-info/RECORD +0 -23
- {neurostats_API-0.0.5.dist-info → neurostats_API-0.0.7.dist-info}/top_level.txt +0 -0
neurostats_API/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__='0.0.
|
1
|
+
__version__='0.0.7'
|
@@ -1,3 +1,7 @@
|
|
1
1
|
from .base import StatsDateTime, StatsFetcher
|
2
|
+
from .balance_sheet import BalanceSheetFetcher
|
3
|
+
from .cash_flow import CashFlowFetcher
|
2
4
|
from .finance_overview import FinanceOverviewFetcher
|
5
|
+
from .month_revenue import MonthRevenueFetcher
|
6
|
+
from .profit_lose import ProfitLoseFetcher
|
3
7
|
from .value_invest import ValueFetcher
|
@@ -0,0 +1,122 @@
|
|
1
|
+
from .base import StatsFetcher, StatsDateTime
|
2
|
+
import json
|
3
|
+
import pandas as pd
|
4
|
+
from ..utils import StatsDateTime, StatsProcessor
|
5
|
+
import importlib.resources as pkg_resources
|
6
|
+
import yaml
|
7
|
+
|
8
|
+
class BalanceSheetFetcher(StatsFetcher):
|
9
|
+
"""
|
10
|
+
對應iFa.ai -> 財務分析 -> 資產負債表
|
11
|
+
"""
|
12
|
+
|
13
|
+
def __init__(self, ticker, db_client):
|
14
|
+
super().__init__(ticker, db_client)
|
15
|
+
self.table_settings = StatsProcessor.load_yaml("balance_sheet.yaml")
|
16
|
+
|
17
|
+
def prepare_query(self, target_year, target_season):
|
18
|
+
pipeline = super().prepare_query()
|
19
|
+
|
20
|
+
target_query = {
|
21
|
+
"year": "$$target_season_data.year",
|
22
|
+
"season": "$$target_season_data.season",
|
23
|
+
"balance_sheet": "$$$$target_season_data.balance_sheet"
|
24
|
+
}
|
25
|
+
|
26
|
+
pipeline.append({
|
27
|
+
"$project": {
|
28
|
+
"_id": 0,
|
29
|
+
"ticker": 1,
|
30
|
+
"company_name": 1,
|
31
|
+
"balance_sheets": {
|
32
|
+
"$sortArray": {
|
33
|
+
"input": {
|
34
|
+
"$map": {
|
35
|
+
"input": {
|
36
|
+
"$filter": {
|
37
|
+
"input": "$seasonal_data",
|
38
|
+
"as": "season",
|
39
|
+
"cond": {
|
40
|
+
"$eq": ["$$season.season", target_season]
|
41
|
+
}
|
42
|
+
}
|
43
|
+
},
|
44
|
+
"as": "target_season_data",
|
45
|
+
"in": {
|
46
|
+
"year": "$$target_season_data.year",
|
47
|
+
"season": "$$target_season_data.season",
|
48
|
+
"balance_sheet": "$$target_season_data.balance_sheet"
|
49
|
+
}
|
50
|
+
}
|
51
|
+
},
|
52
|
+
"sortBy": { "year": -1 } # 按 year 降序排序
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
})
|
57
|
+
|
58
|
+
return pipeline
|
59
|
+
|
60
|
+
def collect_data(self, target_year, target_season):
|
61
|
+
pipeline = self.prepare_query(target_year, target_season)
|
62
|
+
|
63
|
+
fetched_data = self.collection.aggregate(pipeline)
|
64
|
+
|
65
|
+
fetched_data = list(fetched_data)
|
66
|
+
|
67
|
+
return fetched_data[-1]
|
68
|
+
|
69
|
+
def query_data(self):
|
70
|
+
today = StatsDateTime.get_today()
|
71
|
+
|
72
|
+
year = today.year - 1 if (today.season == 1) else today.year
|
73
|
+
season = 4 if (today.season == 1) else today.season - 2
|
74
|
+
fetched_data = self.collect_data(year, season)
|
75
|
+
|
76
|
+
return self.process_data(season, fetched_data)
|
77
|
+
|
78
|
+
def process_data(self, target_season, fetched_data):
|
79
|
+
return_dict = {
|
80
|
+
"ticker": self.ticker,
|
81
|
+
"company_name": fetched_data['company_name']
|
82
|
+
}
|
83
|
+
|
84
|
+
index_names = []
|
85
|
+
|
86
|
+
table_dict = dict()
|
87
|
+
|
88
|
+
balance_sheets = fetched_data['balance_sheets']
|
89
|
+
|
90
|
+
# 將value與percentage跟著年分季度一筆筆取出
|
91
|
+
for data in balance_sheets:
|
92
|
+
year = data['year']
|
93
|
+
|
94
|
+
time_index = f"{year}Q{target_season}"
|
95
|
+
|
96
|
+
# 蒐集整體的keys
|
97
|
+
index_names += list(data['balance_sheet'].keys())
|
98
|
+
balance_sheet = data['balance_sheet']
|
99
|
+
|
100
|
+
for index_name, value_dict in balance_sheet.items():
|
101
|
+
for item_name, item in value_dict.items():
|
102
|
+
try: # table_dict[項目][(2020Q1, '%')]
|
103
|
+
table_dict[index_name][(time_index,item_name)] = item
|
104
|
+
|
105
|
+
except KeyError:
|
106
|
+
if (index_name not in table_dict.keys()):
|
107
|
+
table_dict[index_name] = dict()
|
108
|
+
|
109
|
+
table_dict[index_name][(time_index,item_name)] = item
|
110
|
+
|
111
|
+
total_table = pd.DataFrame.from_dict(table_dict, orient='index')
|
112
|
+
total_table.columns = pd.MultiIndex.from_tuples(total_table.columns)
|
113
|
+
|
114
|
+
for name, setting in self.table_settings.items():
|
115
|
+
return_dict[name] = StatsProcessor.slice_multi_col_table(
|
116
|
+
total_table=total_table,
|
117
|
+
mode=setting['mode'],
|
118
|
+
target_index=setting['target_index']
|
119
|
+
if "target_index" in setting.keys() else None)
|
120
|
+
|
121
|
+
print(f"{name}: {return_dict[name].columns}")
|
122
|
+
return return_dict
|
@@ -0,0 +1,181 @@
|
|
1
|
+
from .base import StatsFetcher, StatsDateTime
|
2
|
+
import json
|
3
|
+
import pandas as pd
|
4
|
+
from ..utils import StatsDateTime, StatsProcessor
|
5
|
+
import importlib.resources as pkg_resources
|
6
|
+
import yaml
|
7
|
+
|
8
|
+
class CashFlowFetcher(StatsFetcher):
|
9
|
+
def __init__(self, ticker, db_client):
|
10
|
+
super().__init__(ticker, db_client)
|
11
|
+
|
12
|
+
self.cash_flow_dict = StatsProcessor.load_yaml(
|
13
|
+
"cash_flow_percentage.yaml"
|
14
|
+
) # 計算子表格用
|
15
|
+
|
16
|
+
def prepare_query(self, target_season):
|
17
|
+
pipeline = super().prepare_query()
|
18
|
+
|
19
|
+
pipeline.append({
|
20
|
+
"$project": {
|
21
|
+
"_id": 0,
|
22
|
+
"ticker": 1,
|
23
|
+
"company_name": 1,
|
24
|
+
"cash_flows": {
|
25
|
+
"$sortArray": {
|
26
|
+
"input": {
|
27
|
+
"$map": {
|
28
|
+
"input": {
|
29
|
+
"$filter": {
|
30
|
+
"input": "$seasonal_data",
|
31
|
+
"as": "season",
|
32
|
+
"cond": {
|
33
|
+
"$eq":
|
34
|
+
["$$season.season", target_season]
|
35
|
+
}
|
36
|
+
}
|
37
|
+
},
|
38
|
+
"as": "target_season_data",
|
39
|
+
"in": {
|
40
|
+
"year":
|
41
|
+
"$$target_season_data.year",
|
42
|
+
"season":
|
43
|
+
"$$target_season_data.season",
|
44
|
+
"cash_flow":
|
45
|
+
"$$target_season_data.cash_flow"
|
46
|
+
}
|
47
|
+
}
|
48
|
+
},
|
49
|
+
"sortBy": {
|
50
|
+
"year": -1
|
51
|
+
} # 按 year 降序排序
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
})
|
56
|
+
|
57
|
+
return pipeline
|
58
|
+
|
59
|
+
def collect_data(self, target_season):
|
60
|
+
pipeline = self.prepare_query(target_season)
|
61
|
+
|
62
|
+
fetched_data = self.collection.aggregate(pipeline)
|
63
|
+
|
64
|
+
return list(fetched_data)[0]
|
65
|
+
|
66
|
+
def query_data(self):
|
67
|
+
today = StatsDateTime.get_today()
|
68
|
+
|
69
|
+
target_season = today.season - 1 if (today.season > 1) else 4
|
70
|
+
|
71
|
+
fetched_data = self.collect_data(target_season)
|
72
|
+
|
73
|
+
return self.process_data(fetched_data, target_season)
|
74
|
+
|
75
|
+
def process_data(self, fetched_data, target_season):
|
76
|
+
"""
|
77
|
+
處理現金流量表頁面的所有表格
|
78
|
+
金流表本身沒有比例 但是Ifa有算,
|
79
|
+
項目所屬的情況也不一(分別所屬營業,投資,籌資三個活動)
|
80
|
+
所以這裡選擇不用slicing處理
|
81
|
+
"""
|
82
|
+
cash_flows = fetched_data['cash_flows']
|
83
|
+
|
84
|
+
index_names = []
|
85
|
+
column_names = []
|
86
|
+
|
87
|
+
table_dict = dict()
|
88
|
+
CASHO_dict = dict()
|
89
|
+
CASHI_dict = dict()
|
90
|
+
CASHF_dict = dict()
|
91
|
+
|
92
|
+
return_dict = {
|
93
|
+
"ticker": fetched_data['ticker'],
|
94
|
+
"company_name": fetched_data['company_name'],
|
95
|
+
"cash_flow": dict(),
|
96
|
+
"CASHO": dict(),
|
97
|
+
"CASHI": dict(),
|
98
|
+
"CASHF": dict()
|
99
|
+
}
|
100
|
+
|
101
|
+
checkpoints = ["營業活動之現金流量-間接法", "投資活動之現金流量", "籌資活動之現金流量", "匯率變動對現金及約當現金之影響"]
|
102
|
+
main_cash_flows = [
|
103
|
+
"營業活動之淨現金流入(流出)", "投資活動之淨現金流入(流出)", "籌資活動之淨現金流入(流出)", None
|
104
|
+
] # 主要的比例對象
|
105
|
+
partial_cash_flows = [CASHO_dict, CASHI_dict, CASHF_dict, dict()]
|
106
|
+
|
107
|
+
# 作法: dictionary中也有checkpoints,如果出現了就換下一個index去計算
|
108
|
+
|
109
|
+
for data in cash_flows:
|
110
|
+
year = data['year']
|
111
|
+
|
112
|
+
time_index = f"{year}Q{target_season}"
|
113
|
+
|
114
|
+
cash_flow = data['cash_flow']
|
115
|
+
main_cash_flow_name = None
|
116
|
+
partial_cash_flow = None
|
117
|
+
next_checkpoint = 0
|
118
|
+
|
119
|
+
for index_name, value in cash_flow.items():
|
120
|
+
if (next_checkpoint < 3
|
121
|
+
and index_name == checkpoints[next_checkpoint]): # 找到了主要的變動點
|
122
|
+
main_cash_flow_name = main_cash_flows[next_checkpoint]
|
123
|
+
partial_cash_flow = partial_cash_flows[next_checkpoint]
|
124
|
+
next_checkpoint += 1
|
125
|
+
try:
|
126
|
+
table_dict[time_index][index_name]['value'] = value[
|
127
|
+
'value']
|
128
|
+
if (value['value']):
|
129
|
+
table_dict[time_index][index_name][
|
130
|
+
'percentage'] = value['value'] / cash_flow[
|
131
|
+
main_cash_flow_name]['value']
|
132
|
+
else:
|
133
|
+
table_dict[time_index][index_name][
|
134
|
+
'percentage'] = None
|
135
|
+
except:
|
136
|
+
if (time_index not in table_dict.keys()):
|
137
|
+
table_dict[time_index] = dict()
|
138
|
+
table_dict[time_index][index_name] = dict()
|
139
|
+
|
140
|
+
table_dict[time_index][index_name]['value'] = value[
|
141
|
+
'value']
|
142
|
+
if (value['value']):
|
143
|
+
table_dict[time_index][index_name][
|
144
|
+
'percentage'] = value['value'] / cash_flow[
|
145
|
+
main_cash_flow_name]['value']
|
146
|
+
else:
|
147
|
+
table_dict[time_index][index_name][
|
148
|
+
'percentage'] = None
|
149
|
+
|
150
|
+
try:
|
151
|
+
partial_cash_flow[time_index][index_name] = table_dict[
|
152
|
+
time_index][index_name]
|
153
|
+
except:
|
154
|
+
if (time_index not in partial_cash_flow.keys()):
|
155
|
+
partial_cash_flow[time_index] = dict()
|
156
|
+
partial_cash_flow[time_index][index_name] = table_dict[
|
157
|
+
time_index][index_name]
|
158
|
+
|
159
|
+
index_names += list(cash_flow.keys())
|
160
|
+
|
161
|
+
# 轉成dictionary keys
|
162
|
+
index_names = list(dict.fromkeys(index_names))
|
163
|
+
|
164
|
+
cash_flow_table = pd.DataFrame(table_dict)
|
165
|
+
cash_flow_table = StatsProcessor.expand_value_percentage(cash_flow_table)
|
166
|
+
|
167
|
+
CASHO_table = pd.DataFrame(CASHO_dict)
|
168
|
+
CASHO_table = StatsProcessor.expand_value_percentage(CASHO_table)
|
169
|
+
|
170
|
+
CASHI_table = pd.DataFrame(CASHI_dict)
|
171
|
+
CASHI_table = StatsProcessor.expand_value_percentage(CASHI_table)
|
172
|
+
|
173
|
+
CASHF_table = pd.DataFrame(CASHF_dict)
|
174
|
+
CASHF_table = StatsProcessor.expand_value_percentage(CASHF_table)
|
175
|
+
|
176
|
+
return_dict['cash_flow'] = cash_flow_table
|
177
|
+
return_dict['CASHO'] = CASHO_table
|
178
|
+
return_dict['CASHI'] = CASHI_table
|
179
|
+
return_dict['CASHF'] = CASHF_table
|
180
|
+
|
181
|
+
return return_dict
|
@@ -82,7 +82,9 @@ class FinanceOverviewFetcher(StatsFetcher):
|
|
82
82
|
def query_data(self):
|
83
83
|
today = StatsDateTime.get_today()
|
84
84
|
|
85
|
-
|
85
|
+
year = today.year - 1 if (today.season == 1) else today.year
|
86
|
+
season = 4 if (today.season == 1) else today.season - 2
|
87
|
+
fetched_data = self.collect_data(year, season)
|
86
88
|
finance_dict = fetched_data['seasonal_data'][0]
|
87
89
|
FinanceOverviewProcessor.process_all(finance_dict)
|
88
90
|
fetched_data['seasonal_data'] = finance_dict
|
@@ -0,0 +1,92 @@
|
|
1
|
+
from .base import StatsFetcher, StatsDateTime
|
2
|
+
import json
|
3
|
+
import pandas as pd
|
4
|
+
from ..utils import StatsDateTime, StatsProcessor
|
5
|
+
import importlib.resources as pkg_resources
|
6
|
+
import yaml
|
7
|
+
|
8
|
+
|
9
|
+
class MonthRevenueFetcher(StatsFetcher):
|
10
|
+
"""
|
11
|
+
iFa.ai: 財務分析 -> 每月營收
|
12
|
+
"""
|
13
|
+
|
14
|
+
def __init__(self, ticker, db_client):
|
15
|
+
super().__init__(ticker, db_client)
|
16
|
+
|
17
|
+
def prepare_query(self, target_year, target_month):
|
18
|
+
pipeline = super().prepare_query()
|
19
|
+
|
20
|
+
pipeline.append({
|
21
|
+
"$project": {
|
22
|
+
"_id": 0,
|
23
|
+
"ticker": 1,
|
24
|
+
"company_name": 1,
|
25
|
+
"monthly_data": {
|
26
|
+
"$sortArray": {
|
27
|
+
"input": "$monthly_data",
|
28
|
+
"sortBy": {
|
29
|
+
"year": -1,
|
30
|
+
"month": -1
|
31
|
+
}
|
32
|
+
}
|
33
|
+
},
|
34
|
+
}
|
35
|
+
})
|
36
|
+
|
37
|
+
return pipeline
|
38
|
+
|
39
|
+
def collect_data(self, target_year, target_month):
|
40
|
+
pipeline = self.prepare_query(target_year, target_month)
|
41
|
+
|
42
|
+
fetched_data = self.collection.aggregate(pipeline)
|
43
|
+
|
44
|
+
fetched_data = list(fetched_data)
|
45
|
+
|
46
|
+
return fetched_data[-1]
|
47
|
+
|
48
|
+
def query_data(self):
|
49
|
+
today = StatsDateTime.get_today()
|
50
|
+
target_month = today.month
|
51
|
+
target_year = today.year
|
52
|
+
|
53
|
+
# Query data
|
54
|
+
fetched_data = self.collect_data(target_year, target_month)
|
55
|
+
|
56
|
+
return self.process_data(fetched_data)
|
57
|
+
|
58
|
+
def process_data(self, fetched_data):
|
59
|
+
|
60
|
+
monthly_data = fetched_data['monthly_data']
|
61
|
+
target_month = monthly_data[0]['month']
|
62
|
+
monthly_df = pd.DataFrame(monthly_data)
|
63
|
+
target_month_df = monthly_df[monthly_df['month'] == target_month]
|
64
|
+
month_revenue_df = monthly_df.pivot(index='month',
|
65
|
+
columns='year',
|
66
|
+
values='revenue')
|
67
|
+
|
68
|
+
grand_total_df = target_month_df.pivot(index='month',
|
69
|
+
columns='year',
|
70
|
+
values='grand_total')
|
71
|
+
|
72
|
+
grand_total_df.rename(index={target_month: f"grand_total"},
|
73
|
+
inplace=True)
|
74
|
+
month_revenue_df = month_revenue_df.sort_index(ascending = False)
|
75
|
+
month_revenue_df = pd.concat([grand_total_df, month_revenue_df],
|
76
|
+
axis=0)
|
77
|
+
|
78
|
+
fetched_data['month_revenue'] = month_revenue_df[sorted(month_revenue_df.columns, reverse = True)]
|
79
|
+
# 歷年月營收
|
80
|
+
fetched_data[
|
81
|
+
'this_month_revenue_over_years'] = target_month_df.set_index(
|
82
|
+
"year")[["revenue", "revenue_increment_ratio", "YoY_1",
|
83
|
+
"YoY_3", "YoY_5", "YoY_10"]].T
|
84
|
+
# 歷年營收成長量
|
85
|
+
fetched_data['grand_total_over_years'] = target_month_df.set_index(
|
86
|
+
"year")[["grand_total", "grand_total_increment_ratio",
|
87
|
+
"grand_total_YoY_1", "grand_total_YoY_3",
|
88
|
+
"grand_total_YoY_5", "grand_total_YoY_10"]].T
|
89
|
+
|
90
|
+
fetched_data.pop("monthly_data")
|
91
|
+
|
92
|
+
return fetched_data
|
@@ -0,0 +1,131 @@
|
|
1
|
+
from .base import StatsFetcher, StatsDateTime
|
2
|
+
import json
|
3
|
+
import pandas as pd
|
4
|
+
from ..utils import StatsDateTime, StatsProcessor
|
5
|
+
import importlib.resources as pkg_resources
|
6
|
+
import yaml
|
7
|
+
|
8
|
+
|
9
|
+
class ProfitLoseFetcher(StatsFetcher):
|
10
|
+
"""
|
11
|
+
iFa.ai: 財務分析 -> 損益表
|
12
|
+
"""
|
13
|
+
|
14
|
+
def __init__(self, ticker, db_client):
|
15
|
+
super().__init__(ticker, db_client)
|
16
|
+
|
17
|
+
self.table_settings = StatsProcessor.load_yaml("profit_lose.yaml")
|
18
|
+
|
19
|
+
def prepare_query(self, target_season):
|
20
|
+
pipeline = super().prepare_query()
|
21
|
+
|
22
|
+
target_query = {
|
23
|
+
"year": "$$target_season_data.year",
|
24
|
+
"season": "$$target_season_data.season",
|
25
|
+
"balance_sheet": "$$$$target_season_data.balance_sheet"
|
26
|
+
}
|
27
|
+
|
28
|
+
pipeline.append({
|
29
|
+
"$project": {
|
30
|
+
"_id": 0,
|
31
|
+
"ticker": 1,
|
32
|
+
"company_name": 1,
|
33
|
+
"profit_loses": {
|
34
|
+
"$sortArray": {
|
35
|
+
"input": {
|
36
|
+
"$map": {
|
37
|
+
"input": {
|
38
|
+
"$filter": {
|
39
|
+
"input": "$seasonal_data",
|
40
|
+
"as": "season",
|
41
|
+
"cond": {
|
42
|
+
"$eq":
|
43
|
+
["$$season.season", target_season]
|
44
|
+
}
|
45
|
+
}
|
46
|
+
},
|
47
|
+
"as": "target_season_data",
|
48
|
+
"in": {
|
49
|
+
"year":
|
50
|
+
"$$target_season_data.year",
|
51
|
+
"season":
|
52
|
+
"$$target_season_data.season",
|
53
|
+
"profit_lose":
|
54
|
+
"$$target_season_data.profit_lose"
|
55
|
+
}
|
56
|
+
}
|
57
|
+
},
|
58
|
+
"sortBy": {
|
59
|
+
"year": -1
|
60
|
+
} # 按 year 降序排序
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
})
|
65
|
+
|
66
|
+
return pipeline
|
67
|
+
|
68
|
+
def collect_data(self, target_season):
|
69
|
+
pipeline = self.prepare_query(target_season)
|
70
|
+
|
71
|
+
fetched_data = self.collection.aggregate(pipeline)
|
72
|
+
|
73
|
+
return list(fetched_data)[-1]
|
74
|
+
|
75
|
+
def query_data(self):
|
76
|
+
today = StatsDateTime.get_today()
|
77
|
+
|
78
|
+
target_season = today.season
|
79
|
+
target_season = target_season - 1 if target_season > 1 else 4
|
80
|
+
|
81
|
+
fetched_data = self.collect_data(target_season)
|
82
|
+
|
83
|
+
return self.process_data(fetched_data, target_season)
|
84
|
+
|
85
|
+
def process_data(self, fetched_data, target_season):
|
86
|
+
|
87
|
+
profit_loses = fetched_data['profit_loses']
|
88
|
+
|
89
|
+
index_names = []
|
90
|
+
|
91
|
+
table_dict = dict()
|
92
|
+
grand_total_dict = dict()
|
93
|
+
|
94
|
+
return_dict = {
|
95
|
+
"ticker": fetched_data['ticker'],
|
96
|
+
"company_name": fetched_data['company_name'],
|
97
|
+
}
|
98
|
+
|
99
|
+
for data in profit_loses:
|
100
|
+
year = data['year']
|
101
|
+
|
102
|
+
time_index = f"{year}Q{target_season}"
|
103
|
+
|
104
|
+
# 蒐集整體的keys
|
105
|
+
index_names += list(data['profit_lose'].keys())
|
106
|
+
profit_lose = data['profit_lose']
|
107
|
+
|
108
|
+
for index_name, value_dict in profit_lose.items():
|
109
|
+
# (2020Q1, 項目, 金額或%)
|
110
|
+
for item_name, item in value_dict.items():
|
111
|
+
try:
|
112
|
+
table_dict[index_name][(time_index, item_name)] = item
|
113
|
+
|
114
|
+
except KeyError:
|
115
|
+
if (index_name not in table_dict.keys()):
|
116
|
+
table_dict[index_name] = dict()
|
117
|
+
grand_total_dict[index_name] = dict()
|
118
|
+
|
119
|
+
table_dict[index_name][(time_index, item_name)] = item
|
120
|
+
|
121
|
+
total_table = pd.DataFrame.from_dict(table_dict, orient='index')
|
122
|
+
total_table.columns = pd.MultiIndex.from_tuples(total_table.columns)
|
123
|
+
|
124
|
+
for name, setting in self.table_settings.items():
|
125
|
+
return_dict[name] = StatsProcessor.slice_multi_col_table(
|
126
|
+
total_table=total_table,
|
127
|
+
mode=setting['mode'],
|
128
|
+
target_index=setting['target_index']
|
129
|
+
if "target_index" in setting.keys() else None)
|
130
|
+
|
131
|
+
return return_dict
|
@@ -0,0 +1,26 @@
|
|
1
|
+
balance_sheet:
|
2
|
+
mode: value_and_percentage
|
3
|
+
|
4
|
+
total_asset:
|
5
|
+
mode: value_and_percentage
|
6
|
+
target_index: 資產總額 負債總額 權益總額
|
7
|
+
|
8
|
+
current_asset:
|
9
|
+
mode: value_and_percentage
|
10
|
+
target_index: 流動資產合計
|
11
|
+
|
12
|
+
non_current_asset:
|
13
|
+
mode: value_and_percentage
|
14
|
+
target_index: 非流動資產合計
|
15
|
+
|
16
|
+
current_debt:
|
17
|
+
mode: value_and_percentage
|
18
|
+
target_index: 流動負債合計
|
19
|
+
|
20
|
+
non_current_debt:
|
21
|
+
mode: value_and_percentage
|
22
|
+
target_index: 非流動負債合計
|
23
|
+
|
24
|
+
equity:
|
25
|
+
mode: value_and_percentage
|
26
|
+
target_index: 權益總額
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# 注意此並非用於slicing
|
2
|
+
CASHO:
|
3
|
+
main_index: 營業活動之淨現金流入(流出)
|
4
|
+
index:
|
5
|
+
- 繼續營業單位稅前淨利(淨損)
|
6
|
+
- 收益費損項目合計
|
7
|
+
- 折舊費用
|
8
|
+
- 攤銷費用
|
9
|
+
- 與營業活動相關之資產及負債之淨變動合計
|
10
|
+
- 營業活動之淨現金流入(流出)
|
11
|
+
|
12
|
+
CASHI:
|
13
|
+
main_index: 投資活動之淨現金流入(流出)
|
14
|
+
index:
|
15
|
+
- 投資活動之淨現金流入(流出)
|
16
|
+
- 取得不動產、廠房及設備
|
17
|
+
- 處分不動產、廠房及設備
|
18
|
+
- 取得無形資產
|
19
|
+
- 處分無形資產
|
20
|
+
- 取得透過損益按公允價值衡量之金融資產
|
21
|
+
- 處分透過損益按公允價值衡量之金融資產
|
22
|
+
- 取得透過其他綜合損益按公允價值衡量之金融資產
|
23
|
+
- 處分透過其他綜合損益按公允價值衡量之金融資產
|
24
|
+
- 取得按攤銷後成本衡量之金融資產
|
25
|
+
- 處分按攤銷後成本衡量之金融資產
|
26
|
+
- 按攤銷後成本衡量之金融資產到期還本
|
27
|
+
|
28
|
+
CASHO:
|
29
|
+
main_index: 籌資活動之淨現金流入(流出)
|
30
|
+
index:
|
31
|
+
- 籌資活動之淨現金流入(流出)
|
32
|
+
- 短期借款增加
|
33
|
+
- 短期借款減少
|
34
|
+
- 發行公司債
|
35
|
+
- 償還公司債
|
36
|
+
- 舉借長期借款
|
37
|
+
- 償還長期借款
|
38
|
+
- 發放現金股利
|
39
|
+
- 庫藏股票買回成本
|