neurostats-API 0.0.6__py3-none-any.whl → 0.0.7__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.
@@ -1 +1 @@
1
- __version__='0.0.6'
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
- fetched_data = self.collect_data(2024, 2)
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
+ - 庫藏股票買回成本
@@ -9,7 +9,7 @@ revenue:
9
9
  target_index: 營業收入合計
10
10
 
11
11
  grand_total_revenue:
12
- mode: grand_total_values
12
+ mode: grand_total_growth
13
13
  target_index: 營業收入合計
14
14
 
15
15
  gross_profit:
@@ -1,18 +1,138 @@
1
1
  from importlib.resources import files
2
2
  import json
3
+ import pandas as pd
3
4
  import yaml
4
5
 
6
+ target_metric_dict = {
7
+ 'value': ['value'],
8
+ 'value_and_percentage': ['value', 'percentage'],
9
+ 'percentage': ['percentage'],
10
+ 'grand_total': ['grand_total'],
11
+ 'grand_total_values': ['grand_total', 'grand_total_percentage'],
12
+ 'grand_total_percentage': ['grand_total_percentage'],
13
+ 'growth': [f'YoY_{i}' for i in [1, 3, 5, 10]],
14
+ 'grand_total_growth': [f"grand_total_YoY_{i}" for i in [1, 3, 5, 10]]
15
+ }
16
+
17
+
5
18
  class StatsProcessor:
19
+
6
20
  @classmethod
7
- def load_txt(cls, filename, json_load = True):
21
+ def load_txt(cls, filename, json_load=True):
8
22
  txt_path = files('neurostats_API.tools').joinpath(filename)
9
23
  with open(txt_path, 'r', encoding='utf-8') as f:
10
- data = json.load(f) if (json_load) else f.read()
24
+ data = json.load(f) if (json_load) else f.read()
11
25
  return data
26
+
12
27
  @classmethod
13
28
  def load_yaml(cls, filename):
14
29
  yaml_path = files('neurostats_API.tools').joinpath(filename)
15
30
  with open(yaml_path, 'r', encoding='utf-8') as f:
16
31
  data = yaml.safe_load(f)
17
32
 
18
- return data
33
+ return data
34
+
35
+ @classmethod
36
+ def expand_value_percentage(cls, dataframe):
37
+
38
+ expanded_columns = {}
39
+ for col in dataframe.columns:
40
+ # Use json_normalize to split 'value' and 'percentage'
41
+ expanded_df = pd.json_normalize(
42
+ dataframe[col]).add_prefix(f"{col}_")
43
+ expanded_df.index = dataframe.index
44
+ # Append the expanded columns to the new DataFrame
45
+ expanded_columns[col] = expanded_df
46
+
47
+ expanded_df = pd.concat(expanded_columns.values(), axis=1)
48
+
49
+ return expanded_df
50
+
51
+ @classmethod
52
+ def slice_table(
53
+ cls,
54
+ total_table,
55
+ mode='value',
56
+ target_index=None, # None or Str, 要特別抓哪個index
57
+ ):
58
+ """
59
+ total_table: column應為 <時間>_<單位>
60
+ 對只有單層column的table,切出想要的index
61
+ """
62
+ times = [
63
+ column.split("_")[0] for column in total_table.columns.unique()
64
+ ] #取出timeIndex
65
+ try:
66
+ target_metrics = target_metric_dict[mode]
67
+ except KeyError as e:
68
+ return f"mode Error: Get mode should be {list(target_metric_dict.keys())} but get {mode}"
69
+
70
+ desired_order = [
71
+ f"{time}_{value_name}" for time in times
72
+ for value_name in target_metrics
73
+ ]
74
+
75
+ if (target_index):
76
+ target_index = target_index.split()
77
+ sliced_table = total_table.loc[target_index, desired_order].T
78
+
79
+ return sliced_table.T
80
+
81
+ else:
82
+ return total_table.loc[:, desired_order]
83
+
84
+ @classmethod
85
+ def slice_multi_col_table(
86
+ cls,
87
+ total_table,
88
+ mode='value',
89
+ target_index=None, # None or Str, 要特別抓哪個index
90
+ ):
91
+ """
92
+ 對Multicolumn的dataframe切出目標的index
93
+ """
94
+ times = total_table.columns.get_level_values(0).unique()
95
+ try:
96
+ target_metrics = target_metric_dict[mode]
97
+ except KeyError as e:
98
+ return f"mode Error: Get mode should be {list(target_metric_dict.keys())} but get {mode}"
99
+
100
+ desired_order = [(time, value_name) for time in times
101
+ for value_name in target_metrics]
102
+
103
+ if (target_index):
104
+ target_index = target_index.split()
105
+ sliced_table = total_table.loc[
106
+ target_index, pd.IndexSlice[:,
107
+ target_metrics]][desired_order].T
108
+ if (mode == 'value_and_percentage'): # 因應balance_sheet 頁面的格式
109
+ return_table = sliced_table.T
110
+ return_table.columns = [
111
+ "_".join(flatten_indexs)
112
+ for flatten_indexs in return_table.columns.to_flat_index()
113
+ ]
114
+ return return_table
115
+
116
+ sliced_table = sliced_table.reset_index()
117
+ sliced_table = sliced_table.pivot(index='level_1',
118
+ columns='level_0',
119
+ values=target_index).sort_index(
120
+ axis=1, level = 1,ascending = False
121
+ )
122
+
123
+ sliced_table.columns = sliced_table.columns.get_level_values(1)
124
+ sliced_table.columns.name = None
125
+ sliced_table.index.name = None
126
+
127
+ return sliced_table.reindex(target_metrics)
128
+
129
+ else:
130
+ return_table = total_table.loc[:, pd.IndexSlice[:,
131
+ target_metrics]][
132
+ desired_order]
133
+ return_table.columns = [
134
+ "_".join(flatten_indexs)
135
+ for flatten_indexs in return_table.columns.to_flat_index()
136
+ ]
137
+ return return_table
138
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: neurostats-API
3
- Version: 0.0.6
3
+ Version: 0.0.7
4
4
  Summary: The service of NeuroStats website
5
5
  Home-page: https://github.com/NeurowattStats/NeuroStats_API.git
6
6
  Author: JasonWang@Neurowatt
@@ -30,10 +30,15 @@ Description-Content-Type: text/markdown
30
30
  │   ├── fetchers
31
31
  │   │   ├── __init__.py
32
32
  │   │   ├── base.py
33
+ │   │   ├── balance_sheet.py
34
+ │   │   ├── cash_flow.py
33
35
  │   │   ├── finance_overview.py
36
+ │   │   ├── profit_lose.py
34
37
  │   │   ├── tech.py
35
- │   │   └── value_invest.py
38
+ │   │   ├── value_invest.py
36
39
  │   ├── tools
40
+ │   │   ├── balance_sheet.yaml
41
+ │   │   ├── cash_flow_percentage.yaml
37
42
  │   │   ├── finance_overview_dict.yaml
38
43
  │   │   ├── profit_lose.yaml
39
44
  │   │   └── seasonal_data_field_dict.txt
@@ -73,14 +78,15 @@ pip install neurostats-API
73
78
  ```Python
74
79
  >>> import neurostats_API
75
80
  >>> print(neurostats_API.__version__)
76
- 0.0.5
81
+ 0.0.6
77
82
  ```
78
83
 
79
84
  ### 得到最新一期的評價資料與歷年評價
80
85
  ``` Python
81
- from neurostats_API.fetchers import ValueFetcher
82
- ticker = 2330 # 換成tw50內任意ticker
83
- fetcher = ValueFetcher(ticker)
86
+ from neurostats_API.utils import ValueFetcher, DBClient
87
+ db_client = DBClient("<連接的DB位置>").get_client()
88
+ ticker = "2330" # 換成tw50內任意ticker
89
+ fetcher = ValueFetcher(ticker, db_client)
84
90
  data = stats_fetcher.query_data()
85
91
  ```
86
92
 
@@ -118,43 +124,42 @@ data = stats_fetcher.query_data()
118
124
 
119
125
  ### 回傳月營收表
120
126
  ``` Python
121
- from neurostats_API.utils import StatsFetcher, DBClient
127
+ from neurostats_API.fetchers import MonthRevenueFetcher, DBClient
122
128
  db_client = DBClient("<連接的DB位置>").get_client()
123
- ticker = 2330 # 換成tw50內任意ticker
124
- fetcher = StatsFetcher(db_client)
125
- data = stats_fetcher.get_month_revenue_sheet(ticker)
129
+ ticker = "2330" # 換成tw50內任意ticker
130
+ fetcher = MonthRevenueFetcherFetcher(ticker, db_client)
131
+ data = fetcher.query_data()
126
132
  ```
127
133
 
128
134
  #### 回傳
129
135
  ```Python
130
136
  {
131
- "_id": 671b776dd834afbfbeb9adb3
132
- "ticker": 2330
133
- "company_name":台積電
137
+ "ticker": "2330",
138
+ "company_name": "台積電",
134
139
  "month_revenue":
135
- 2014 2015 ... 2023 2024
136
- 1 51,429,993 87,120,068 ... 200,050,544 215,785,127
137
- 2 46,829,051 62,645,075 ... 163,174,097 181,648,270
138
- ... ... ... ... ... ...
139
- 12 69,510,190 58,347,005 ... 176,299,866 None
140
- grand_total None 639,978,805 ... 1,536,206,985 2,025,846,521
140
+ year 2024 ... 2014
141
+ month ...
142
+ grand_total 2.025847e+09 ... NaN
143
+ 12 NaN ... 69510190.0
144
+ ... ... ... ...
145
+ 2 1.816483e+08 ... 46829051.0
146
+ 1 2.157851e+08 ... 51429993.0
141
147
 
142
148
  "this_month_revenue_over_years":
143
- 2015 2016 ... 2023 2024
144
- revenue 64,514,083 89,702,807 ... 180,430,282 251,872,717
145
- MoM None None ... None None
146
- ... ... ... ... ... ...
147
- YoY_5 None None ... None None
148
- YoY_10 None None ... None None
149
-
149
+ year 2024 ... 2015
150
+ revenue 2.518727e+08 ... 64514083.0
151
+ revenue_increment_ratio 3.960000e+01 ... -13.8
152
+ ... ... ... ...
153
+ YoY_5 1.465200e+02 ... NaN
154
+ YoY_10 NaN ... NaN
150
155
 
151
156
  "grand_total_over_years":
152
- 2015 2016 ... 2023 2024
153
- revenue 639,978,805 685,711,092 ... 1,536,206,985 2,025,846,521
154
- MoM None None ... None None
155
- ... ... ... ... ... ...
156
- YoY_5 None None ... None None
157
- YoY_10 None None ... None None
157
+ year 2024 ... 2015
158
+ grand_total 2.025847e+09 ... 6.399788e+08
159
+ grand_total_increment_ratio 3.187000e+01 ... 1.845000e+01
160
+ ... ... ... ...
161
+ grand_total_YoY_5 1.691300e+02 ... NaN
162
+ grand_total_YoY_10 NaN ... NaN
158
163
 
159
164
 
160
165
  }
@@ -171,7 +176,7 @@ YoY_10 None None ... None None
171
176
  ### 財務分析: 重要指標
172
177
  對應https://ifa.ai/tw-stock/2330/finance-overview
173
178
  ```Python
174
- from neurostats_API.utils import StatsFetcher, DBClient
179
+ from neurostats_API.fetchers import FinanceOverviewFetcher, DBClient
175
180
  db_client = DBClient("<連接的DB位置>").get_client()
176
181
  ticker = "2330"
177
182
  fetcher = FinanceOverviewFetcher(ticker = "2330", db_client = db_client)
@@ -194,6 +199,7 @@ markdown
194
199
  複製程式碼
195
200
  | 英文 | 中文 |
196
201
  |-----------------------------------|-----------------------------|
202
+ |**財務概況**|
197
203
  | revenue | 營業收入 |
198
204
  | gross_profit | 營業毛利 |
199
205
  | operating_income | 營業利益 |
@@ -201,6 +207,7 @@ markdown
201
207
  | operating_cash_flow | 營業活動之現金流 |
202
208
  | invest_cash_flow | 投資活動之淨現金流 |
203
209
  | financing_cash_flow | 籌資活動之淨現金流 |
210
+ |**每股財務狀況**|
204
211
  | revenue_per_share | 每股營收 |
205
212
  | gross_per_share | 每股營業毛利 |
206
213
  | operating_income_per_share | 每股營業利益 |
@@ -209,6 +216,7 @@ markdown
209
216
  | fcf_per_share | 每股自由現金流 |
210
217
  | debt_to_operating_cash_flow | 每股有息負債 |
211
218
  | equity | 每股淨值 |
219
+ |**獲利能力**|
212
220
  | roa | 資產報酬率 |
213
221
  | roe | 股東權益報酬率 |
214
222
  | gross_over_asset | 營業毛利÷總資產 |
@@ -217,10 +225,12 @@ markdown
217
225
  | operation_profit_rate | 營業利益率 |
218
226
  | net_income_rate | 淨利率 |
219
227
  | operating_cash_flow_profit_rate | 營業現金流利潤率 |
228
+ |**成長動能**|
220
229
  | revenue_YoY | 營收年成長率 |
221
230
  | gross_prof_YoY | 營業毛利年成長率 |
222
231
  | operating_income_YoY | 營業利益年成長率 |
223
232
  | net_income_YoY | 淨利年成長率 |
233
+ |**營運指標**|
224
234
  | dso | 應收帳款收現天數 |
225
235
  | account_receive_over_revenue | 應收帳款佔營收比率 |
226
236
  | dio | 平均售貨天數 |
@@ -229,6 +239,7 @@ markdown
229
239
  | cash_of_conversion_cycle | 現金循環週期 |
230
240
  | asset_turnover | 總資產週轉率 |
231
241
  | applcation_turnover | 不動產、廠房及設備週轉率 |
242
+ |**財務韌性**|
232
243
  | current_ratio | 流動比率 |
233
244
  | quick_ratio | 速動比率 |
234
245
  | debt_to_equity_ratio | 負債權益比率 |
@@ -237,6 +248,7 @@ markdown
237
248
  | debt_to_operating_cash_flow | 有息負債÷營業活動現金流 |
238
249
  | debt_to_free_cash_flow | 有息負債÷自由現金流 |
239
250
  | cash_flow_ratio | 現金流量比率 |
251
+ |**資產負債表**|
240
252
  | current_assets | 流動資產 |
241
253
  | current_liabilities | 流動負債 |
242
254
  | non_current_assets | 非流動資產 |
@@ -248,18 +260,19 @@ markdown
248
260
  #### 以下數值未在回傳資料中,待資料庫更新
249
261
  |英文|中文|
250
262
  |---|----|
251
- | operating_cash_flow_YoY (not in list, inferred) | 營業現金流年成長率 |
252
- | fcf_YoY (not in list, inferred) | 自由現金流年成長率 |
253
- | operating_cash_flow_per_share_YoY (not in list, inferred) | 每股營業現金流年成長率 |
254
- | fcf_per_share_YoY (not in list, inferred) | 每股自由現金流年成長率 |
263
+ |**成長動能**|
264
+ | operating_cash_flow_YoY | 營業現金流年成長率 |
265
+ | fcf_YoY | 自由現金流年成長率 |
266
+ | operating_cash_flow_per_share_YoY | 每股營業現金流年成長率 |
267
+ | fcf_per_share_YoY | 每股自由現金流年成長率 |
255
268
 
256
269
  ### 損益表
257
270
  ```Python
258
- from neurostats_API.utils import StatsFetcher, DBClient
271
+ from neurostats_API.fetchers import ProfitLoseFetcher, DBClient
259
272
  db_client = DBClient("<連接的DB位置>").get_client()
260
- fetcher = StatsFetcher(db_client)
261
- ticker = 2330 # 換成tw50內任意ticker
262
- data = fetcher.get_profit_lose(ticker)
273
+ fetcher = ProfitLoseFetcher(db_client)
274
+ ticker = "2330" # 換成tw50內任意ticker
275
+ data = fetcher.query_data()
263
276
  ```
264
277
 
265
278
  #### 回傳
@@ -272,83 +285,85 @@ data = fetcher.get_profit_lose(ticker)
272
285
  "profit_lose": #損益表,
273
286
  "grand_total_profit_lose": #今年度累計損益表,
274
287
  # 營業收入
275
- "revenue":
276
- "grand_total_revenue":
288
+ "revenue": # 營收成長率
289
+ "grand_total_revenue": # 營收累計成場濾
277
290
  # 毛利
278
- "gross_profit":
279
- "grand_total_gross_profit":
280
- "gross_profit_percentage":
281
- "grand_total_gross_profit_percentage"
291
+ "gross_profit": # 毛利成長率
292
+ "grand_total_gross_profit": # 累計毛利成長率
293
+ "gross_profit_percentage": # 毛利率
294
+ "grand_total_gross_profit_percentage" # 累計毛利率
282
295
  # 營利
283
- "operating_income":
284
- "grand_total_operating_income":
285
- "operating_income_percentage":
286
- "grand_total_operating_income_percentage":
296
+ "operating_income": # 營利成長率
297
+ "grand_total_operating_income": # 累計營利成長率
298
+ "operating_income_percentage": # 營利率
299
+ "grand_total_operating_income_percentage": # 累計營利率
287
300
  # 稅前淨利
288
- "net_income_before_tax":
289
- "grand_total_net_income_before_tax":
290
- "net_income_before_tax_percentage":
291
- "grand_total_net_income_before_tax_percentage":
301
+ "net_income_before_tax": # 稅前淨利成長率
302
+ "grand_total_net_income_before_tax": # 累計稅前淨利成長率
303
+ "net_income_before_tax_percentage": # 稅前淨利率
304
+ "grand_total_net_income_before_tax_percentage": # 累計稅前淨利率
292
305
  # 本期淨利
293
- "net_income":
294
- "grand_total_net_income":
295
- "net_income_percentage":
296
- "grand_total_income_percentage":
306
+ "net_income": # 本期淨利成長率
307
+ "grand_total_net_income": # 累計本期淨利成長率
308
+ "net_income_percentage": # 本期淨利率
309
+ "grand_total_income_percentage": # 累計本期淨利率
297
310
  # EPS
298
- "EPS":
299
- "EPS_growth":
300
- "grand_total_EPS":
301
- "grand_total_EPS_growth":
311
+ "EPS": # EPS
312
+ "EPS_growth": # EPS成長率
313
+ "grand_total_EPS": # 累計EPS
314
+ "grand_total_EPS_growth": # 累計EPS成長率
302
315
  }
303
316
  ```
304
317
 
305
318
  ### 資產負債表
306
319
  ``` Python
307
- from neurostats_API.utils import StatsFetcher, DBClient
320
+ from neurostats_API.fetchers import BalanceSheetFetcher, DBClient
308
321
  db_client = DBClient("<連接的DB位置>").get_client()
309
- fetcher = StatsFetcher(db_client)
310
- ticker = 2330 # 換成tw50內任意ticker
311
- stats_fetcher.get_balance_sheet(ticker)
322
+ ticker = "2330" # 換成tw50內任意ticker
323
+ fetcher = BalanceSheetFetcher(ticker, db_client)
324
+
325
+ stats_fetcher.query_data()
312
326
  ```
313
327
 
314
328
  #### 回傳
315
329
  ```Python
316
330
  {
317
331
  "ticker": "2330"
318
- "company_name": "台積電"
332
+ "company_name":"台積電"
319
333
  "balance_sheet":
320
- 2018Q2_value 2018Q2_percentage ... 2024Q2_value 2024Q2_percentage
321
- 流動資產 NaN NaN ... NaN NaN
322
- 現金及約當現金 632229880.0 30.79 ... 1.799127e+09 30.07
323
- ... ... ... ... ... ... ...
324
- 按攤銷後成本衡量之金融資產-非流動 NaN NaN ... 8.868079e+07 1.48
325
- 其他權益 NaN NaN ... NaN NaN
334
+ 2024Q2_value ... 2018Q2_percentage
335
+ 流動資產 NaN ... NaN
336
+ 現金及約當現金 1.799127e+09 ... 30.79
337
+ ... ... ... ...
338
+ 避險之衍生金融負債-流動 NaN ... 0.00
339
+ 負債準備-流動 NaN ... 0.00
326
340
 
327
341
  "total_asset":
328
- 2018Q2_value 2018Q2_percentage ... 2024Q2_value 2024Q2_percentage
329
- total_asset 2.053413e+09 100.00 ... 5.982364e+09 100.00
330
- total_debt 5.627777e+08 27.41 ... 2.162216e+09 36.14
331
- total_equity 1.490635e+09 72.59 ... 3.820148e+09 63.86
342
+ 2024Q2_value ... 2018Q2_percentage
343
+ 資產總額 5.982364e+09 ... 100.00
344
+ 負債總額 2.162216e+09 ... 27.41
345
+ 權益總額 3.820148e+09 ... 72.59
346
+
332
347
 
333
348
  "current_asset":
334
- 2018Q2_value 2018Q2_percentage ... 2024Q2_value 2024Q2_percentage
335
- current_asset 959042679.0 46.7 ... 2.591658e+09 43.32
349
+ 2024Q2_value ... 2018Q2_percentage
350
+ 流動資產合計 2.591658e+09 ... 46.7
336
351
 
337
352
  "non_current_asset":
338
- 2018Q2_value 2018Q2_percentage ... 2024Q2_value 2024Q2_percentage
339
- non_current_asset 1.094370e+09 53.3 ... 3.390706e+09 56.68
353
+ 2024Q2_value ... 2018Q2_percentage
354
+ 非流動資產合計 3.390706e+09 ... 53.3
340
355
 
341
356
  "current_debt":
342
- 2018Q2_value 2018Q2_percentage ... 2024Q2_value 2024Q2_percentage
343
- current_debt 1.094370e+09 53.3 ... 3.390706e+09 56.68
357
+ 2024Q2_value ... 2018Q2_percentage
358
+ 流動負債合計 1.048916e+09 ... 22.55
344
359
 
345
360
  "non_current_debt":
346
- 2018Q2_value 2018Q2_percentage ... 2024Q2_value 2024Q2_percentage
347
- non_current_debt 1.094370e+09 53.3 ... 3.390706e+09 56.68
361
+ 2024Q2_value ... 2018Q2_percentage
362
+ 非流動負債合計 1.113300e+09 ... 4.86
348
363
 
349
364
  "equity":
350
- 2018Q2_value 2018Q2_percentage ... 2024Q2_value 2024Q2_percentage
351
- equity 1.094370e+09 53.3 ... 3.390706e+09 56.68
365
+ 2024Q2_value ... 2018Q2_percentage
366
+ 權益總額 3.820148e+09 ... 72.59
352
367
 
353
368
  }
354
369
  ```
@@ -373,68 +388,39 @@ stats_fetcher.get_cash_flow(ticker)
373
388
  #### 回傳
374
389
  ```Python
375
390
  {
376
- "ticker":2330
377
- "company_name":台積電
391
+ "ticker": "2330"
392
+ "company_name": "台積電"
378
393
  "cash_flow":
379
- 2018Q2_value 2018Q2_percentage ... 2024Q2_value \
380
- 營業活動之現金流量-間接法 NaN NaN ... NaN
381
- 繼續營業單位稅前淨利(淨損) 187531229.0 0.645548 ... 572853779.0
382
- ... ... ... ... ...
383
- 存出保證金增加 NaN NaN ... -122271.0
384
- 收取之股利 NaN NaN ... 895503.0
385
-
386
- 2024Q2_percentage
387
- 營業活動之現金流量-間接法 NaN
388
- 繼續營業單位稅前淨利(淨損) 0.703769
389
- ... ...
390
- 存出保證金增加 0.000755
391
- 收取之股利 -0.005530
392
-
393
- "CASHO":
394
- 2018Q2_value 2018Q2_percentage ... 2024Q2_value \
395
- 營業活動之現金流量-間接法 NaN NaN ... NaN
396
- 繼續營業單位稅前淨利(淨損) 187531229.0 0.645548 ... 572853779.0
397
- ... ... ... ... ...
398
- 退還(支付)之所得稅 -31709079.0 -0.109154 ... -89154446.0
399
- 營業活動之淨現金流入(流出) 290499278.0 1.000000 ... 813979318.0
400
-
401
- 2024Q2_percentage
402
- 營業活動之現金流量-間接法 NaN
403
- 繼續營業單位稅前淨利(淨損) 0.703769
404
- ... ...
405
- 退還(支付)之所得稅 -0.109529
406
- 營業活動之淨現金流入(流出) 1.000000
407
-
408
- "CASHI":
409
- 2018Q2_value 2018Q2_percentage ... 2024Q2_value \
410
- 投資活動之現金流量 NaN NaN ... NaN
411
- 取得透過其他綜合損益按公允價值衡量之金融資產 -47523622.0 0.355889 ... -43780180.0
412
- ... ... ... ... ...
413
- 其他投資活動 -149104.0 0.001117 ... 7956680.0
414
- 投資活動之淨現金流入(流出) -133534789.0 1.000000 ... -357414321.0
415
-
416
- 2024Q2_percentage
417
- 投資活動之現金流量 NaN
418
- 取得透過其他綜合損益按公允價值衡量之金融資產 0.122491
419
- ... ...
420
- 其他投資活動 -0.022262
421
- 投資活動之淨現金流入(流出) 1.000000
422
-
423
- "CASHF":
424
- 2018Q2_value 2018Q2_percentage ... 2024Q2_value \
425
- 籌資活動之現金流量 NaN NaN ... NaN
426
- 短期借款減少 -33743725.0 0.387977 ... NaN
427
- ... ... ... ... ...
428
- 存出保證金增加 NaN NaN ... -122271.0
429
- 收取之股利 NaN NaN ... 895503.0
430
-
431
- 2024Q2_percentage
432
- 籌資活動之現金流量 NaN
433
- 短期借款減少 NaN
434
- ... ...
435
- 存出保證金增加 0.000755
436
- 收取之股利 -0.005530
437
-
394
+ 2023Q3_value ... 2018Q3_percentage
395
+ 營業活動之現金流量-間接法 NaN ... NaN
396
+ 繼續營業單位稅前淨利(淨損) 700890335.0 ... 0.744778
397
+ ... ... ... ...
398
+ 以成本衡量之金融資產減資退回股款 NaN ... NaN
399
+ 除列避險之金融負債∕避險 之衍生金融負債 NaN ... -0.000770
400
+
401
+ "CASHO":
402
+ 2023Q3_value ... 2018Q3_percentage
403
+ 營業活動之現金流量-間接法 NaN ... NaN
404
+ 繼續營業單位稅前淨利(淨損) 700890335.0 ... 0.744778
405
+ ... ... ... ...
406
+ 持有供交易之金融資產(增加)減少 NaN ... 0.001664
407
+ 負債準備增加(減少) NaN ... NaN
408
+
409
+ "CASHI":
410
+ 2023Q3_value ... 2018Q3_percentage
411
+ 投資活動之現金流量 NaN ... NaN
412
+ 取得透過其他綜合損益按公允價值衡量之金融資產 -54832622.0 ... 0.367413
413
+ ... ... ... ...
414
+ 持有至到期日金融資產到期還本 NaN ... NaN
415
+ 取得以成本衡量之金融資產 NaN ... NaN
416
+
417
+ "CASHF":
418
+ 2023Q3_value ... 2018Q3_percentage
419
+ 籌資活動之現金流量 NaN ... NaN
420
+ 短期借款減少 0.0 ... NaN
421
+ ... ... ... ...
422
+ 以成本衡量之金融資產減資退回股款 NaN ... NaN
423
+ 除列避險之金融負債∕避險 之衍生金融負債 NaN ... -0.00077
438
424
  }
439
425
  ```
440
426
  - `'ticker'`: 股票代碼
@@ -447,44 +433,6 @@ stats_fetcher.get_cash_flow(ticker)
447
433
  > 大部分資料缺失是因為尚未計算,僅先填上已經有的資料
448
434
 
449
435
 
450
-
451
-
452
- ## cli 範例輸入
453
- ```
454
- python ./cli.py --ticker 1101
455
- ```
456
-
457
- ### cli 輸出
458
- ```Python
459
- _id
460
- ObjectId('67219e046104872ef7490cd3')
461
- ticker
462
- '1101'
463
- company_name
464
- '台泥'
465
- yearly_data
466
- year P_E P_FCF P_B P_S EV_OPI EV_EBIT EV_EBITDA EV_S
467
- 0 107 9.78 66.346637 1.07 1.963814 16.061211 14.807325 32.858903 3.685025
468
- 1 108 10.76 23.532308 1.35 3.296749 21.995948 19.877169 44.395187 5.338454
469
- 2 109 10.29 -26.134468 1.32 4.282560 26.353871 23.417022 46.269197 6.908155
470
- 3 110 14.08 22.345215 1.50 5.558267 42.034804 32.290621 77.139298 7.973839
471
- 4 111 28.04 -63.248928 1.16 4.595606 -136332.740038 149.169022 -756.781156 7.324556
472
- 5 112 29.53 -18.313377 1.15 5.301801 98.225453 65.598234 321.991608 8.582981
473
- 6 過去4季 NaN -24.929987 NaN 4.300817 83.102921 55.788996 -1073.037084 7.436656
474
- daily_data
475
- { 'EV_EBIT': 55.78899626851681,
476
- 'EV_EBITDA': -1073.037084015388,
477
- 'EV_OPI': 83.10292101832388,
478
- 'EV_S': 7.436656083243897,
479
- 'P_B': None,
480
- 'P_E': None,
481
- 'P_FCF': -24.92998660989962,
482
- 'P_S': 4.300817175744059,
483
- 'close': 32.150001525878906,
484
- }
485
- ```
486
- > 這裡有Nan是因為本益比與P/B等資料沒有爬到最新的時間
487
-
488
436
  ## TODO
489
437
  - 將utils/fetcher.py中的功能切分到fetchers資料夾中
490
438
 
@@ -0,0 +1,26 @@
1
+ neurostats_API/__init__.py,sha256=3Kn8sHWnxjlagph2LmftcF8JLlcMlmQIbU5t_jzgK3w,19
2
+ neurostats_API/cli.py,sha256=UJSWLIw03P24p-gkBb6JSEI5dW5U12UvLf1L8HjQD-o,873
3
+ neurostats_API/main.py,sha256=QcsfmWivg2Dnqw3MTJWiI0QvEiRs0VuH-BjwQHFCv00,677
4
+ neurostats_API/fetchers/__init__.py,sha256=U_OMG-mLpsVKYnCBrW2OjFuCzvPeVQ__7A676vGzztY,313
5
+ neurostats_API/fetchers/balance_sheet.py,sha256=FPsVobaNzFOxpXCo1Ui_rPmlG1crTRj9ukqQ4J8aiJg,4268
6
+ neurostats_API/fetchers/base.py,sha256=NW2SFzrimyAIrdJx1LVmTazelyZOAtcj54kJKHc4Vaw,1662
7
+ neurostats_API/fetchers/cash_flow.py,sha256=muVnteEEyeFPapGqgBOoHa8PAieEI796rHPNi5otOMY,7009
8
+ neurostats_API/fetchers/finance_overview.py,sha256=t5QlTM0bL3fkrqlyMn8-8GB6YgMLsofH9NRI8PfPRxE,18447
9
+ neurostats_API/fetchers/month_revenue.py,sha256=RNA7ROl2vm8Xbib3k50p_1shsHDVSKIbHkyNiRa8yMw,3182
10
+ neurostats_API/fetchers/profit_lose.py,sha256=ffEVNo7-fvtnAq2_gj-Ga55TGW7pPd6WhruOZH8NGYM,4463
11
+ neurostats_API/fetchers/tech.py,sha256=wH1kkqiETQhF0HAhk-UIiucnZ3EiL85Q-yMWCcVOiFM,11395
12
+ neurostats_API/fetchers/value_invest.py,sha256=tg8yELbVnTFTEclrwgXnCRW377KkcoLiP-Gk2pyM-9Y,2886
13
+ neurostats_API/tools/balance_sheet.yaml,sha256=dKTMbsYR9EFp48WAzmm_ISHMiJQLyE0V-XWS_gkxmr0,541
14
+ neurostats_API/tools/cash_flow_percentage.yaml,sha256=fk2Z4eb1JjGFvP134eJatHacB7BgTkBenhDJr83w8RE,1345
15
+ neurostats_API/tools/finance_overview_dict.yaml,sha256=Vvf8bv23NwJP8Yyw8DPS8c0_jjT_Wctnnz51SHS4AeI,2335
16
+ neurostats_API/tools/profit_lose.yaml,sha256=qHBnqG7fR4Pxc_c3n4raL-3l7o5RnABLz9YGOXoaGiA,2086
17
+ neurostats_API/tools/seasonal_data_field_dict.txt,sha256=KlIIdTTdbvUd9TSDE9-gpzk2jt2ck_LdisX8cnrWMD4,7869
18
+ neurostats_API/utils/__init__.py,sha256=FTYKRFzW2XVXdnSHXnS3mQQaHlKF9xGqrMsgZZ2kroc,142
19
+ neurostats_API/utils/data_process.py,sha256=rRKf2H0X2J-tDXDreErcz3Y3TGb8_0Q6GKe0izRjnmA,4942
20
+ neurostats_API/utils/datetime.py,sha256=I9CIgZdE5OMzUciOS5wvapOVEIrXG_0Qb6iDKfIod6c,574
21
+ neurostats_API/utils/db_client.py,sha256=OYe6yazcR4Aa6jYmy47JrryUeh2NnKGqY2K_lSZe6i8,455
22
+ neurostats_API/utils/fetcher.py,sha256=VbrUhjA-GG5AyjPX2SHtFIbZM4dm3jo0RgZzuCbb_Io,40927
23
+ neurostats_API-0.0.7.dist-info/METADATA,sha256=Ajugxp0vnHoxdzriFfmLhTt32ckq2VnIiIO_eRU2QDo,18241
24
+ neurostats_API-0.0.7.dist-info/WHEEL,sha256=bFJAMchF8aTQGUgMZzHJyDDMPTO3ToJ7x23SLJa1SVo,92
25
+ neurostats_API-0.0.7.dist-info/top_level.txt,sha256=nSlQPMG0VtXivJyedp4Bkf86EOy2TpW10VGxolXrqnU,15
26
+ neurostats_API-0.0.7.dist-info/RECORD,,
@@ -1,23 +0,0 @@
1
- neurostats_API/__init__.py,sha256=zzMTjJY407ibU6_ATOPO8KibRVB3tyW9yO0tRYzjTqw,19
2
- neurostats_API/cli.py,sha256=UJSWLIw03P24p-gkBb6JSEI5dW5U12UvLf1L8HjQD-o,873
3
- neurostats_API/main.py,sha256=QcsfmWivg2Dnqw3MTJWiI0QvEiRs0VuH-BjwQHFCv00,677
4
- neurostats_API/fetchers/__init__.py,sha256=k-pPWen3gQNr6d6DPFEXP1Q6SPC6TGIuIFf8w6r75YQ,137
5
- neurostats_API/fetchers/balance_sheet.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- neurostats_API/fetchers/base.py,sha256=NW2SFzrimyAIrdJx1LVmTazelyZOAtcj54kJKHc4Vaw,1662
7
- neurostats_API/fetchers/finance_overview.py,sha256=_w5OzFQpzC7eL_S5iMtgrIhx5gcov9gKzc6XzFutEFU,18309
8
- neurostats_API/fetchers/month_revenue.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- neurostats_API/fetchers/profit_lose.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- neurostats_API/fetchers/tech.py,sha256=wH1kkqiETQhF0HAhk-UIiucnZ3EiL85Q-yMWCcVOiFM,11395
11
- neurostats_API/fetchers/value_invest.py,sha256=tg8yELbVnTFTEclrwgXnCRW377KkcoLiP-Gk2pyM-9Y,2886
12
- neurostats_API/tools/finance_overview_dict.yaml,sha256=Vvf8bv23NwJP8Yyw8DPS8c0_jjT_Wctnnz51SHS4AeI,2335
13
- neurostats_API/tools/profit_lose.yaml,sha256=f8balMTcK9elMW0k1PtbZ_6kEobTQ51fcBzqpbMObkk,2086
14
- neurostats_API/tools/seasonal_data_field_dict.txt,sha256=KlIIdTTdbvUd9TSDE9-gpzk2jt2ck_LdisX8cnrWMD4,7869
15
- neurostats_API/utils/__init__.py,sha256=FTYKRFzW2XVXdnSHXnS3mQQaHlKF9xGqrMsgZZ2kroc,142
16
- neurostats_API/utils/data_process.py,sha256=AeDWS9eHlHRqzfDKph-14GXERtHLSMKijsIrzZ0pPPo,595
17
- neurostats_API/utils/datetime.py,sha256=I9CIgZdE5OMzUciOS5wvapOVEIrXG_0Qb6iDKfIod6c,574
18
- neurostats_API/utils/db_client.py,sha256=OYe6yazcR4Aa6jYmy47JrryUeh2NnKGqY2K_lSZe6i8,455
19
- neurostats_API/utils/fetcher.py,sha256=VbrUhjA-GG5AyjPX2SHtFIbZM4dm3jo0RgZzuCbb_Io,40927
20
- neurostats_API-0.0.6.dist-info/METADATA,sha256=cOomXaKrsCOt1V9ZRTuPgfLCzdWnw0fzWd7PkGKlo8U,20666
21
- neurostats_API-0.0.6.dist-info/WHEEL,sha256=bFJAMchF8aTQGUgMZzHJyDDMPTO3ToJ7x23SLJa1SVo,92
22
- neurostats_API-0.0.6.dist-info/top_level.txt,sha256=nSlQPMG0VtXivJyedp4Bkf86EOy2TpW10VGxolXrqnU,15
23
- neurostats_API-0.0.6.dist-info/RECORD,,