neurostats-API 0.0.6__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.
@@ -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,,