neurostats-API 0.0.7__py3-none-any.whl → 0.0.8__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.7'
1
+ __version__='0.0.8'
@@ -1,10 +1,12 @@
1
1
  from .base import StatsFetcher, StatsDateTime
2
2
  import json
3
+ import numpy as np
3
4
  import pandas as pd
4
5
  from ..utils import StatsDateTime, StatsProcessor
5
6
  import importlib.resources as pkg_resources
6
7
  import yaml
7
8
 
9
+
8
10
  class BalanceSheetFetcher(StatsFetcher):
9
11
  """
10
12
  對應iFa.ai -> 財務分析 -> 資產負債表
@@ -13,7 +15,7 @@ class BalanceSheetFetcher(StatsFetcher):
13
15
  def __init__(self, ticker, db_client):
14
16
  super().__init__(ticker, db_client)
15
17
  self.table_settings = StatsProcessor.load_yaml("balance_sheet.yaml")
16
-
18
+
17
19
  def prepare_query(self, target_year, target_season):
18
20
  pipeline = super().prepare_query()
19
21
 
@@ -24,36 +26,42 @@ class BalanceSheetFetcher(StatsFetcher):
24
26
  }
25
27
 
26
28
  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]
29
+ "$project": {
30
+ "_id": 0,
31
+ "ticker": 1,
32
+ "company_name": 1,
33
+ "balance_sheets": {
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
+ }
41
45
  }
46
+ },
47
+ "as": "target_season_data",
48
+ "in": {
49
+ "year":
50
+ "$$target_season_data.year",
51
+ "season":
52
+ "$$target_season_data.season",
53
+ "balance_sheet":
54
+ "$$target_season_data.balance_sheet"
42
55
  }
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
56
  }
50
- }
51
- },
52
- "sortBy": { "year": -1 } # 按 year 降序排序
57
+ },
58
+ "sortBy": {
59
+ "year": -1
60
+ } # 按 year 降序排序
61
+ }
53
62
  }
54
63
  }
55
- }
56
- })
64
+ })
57
65
 
58
66
  return pipeline
59
67
 
@@ -93,20 +101,26 @@ class BalanceSheetFetcher(StatsFetcher):
93
101
 
94
102
  time_index = f"{year}Q{target_season}"
95
103
 
96
- # 蒐集整體的keys
104
+ # 蒐集整體的keys
97
105
  index_names += list(data['balance_sheet'].keys())
98
106
  balance_sheet = data['balance_sheet']
99
107
 
100
108
  for index_name, value_dict in balance_sheet.items():
101
109
  for item_name, item in value_dict.items():
102
- try: # table_dict[項目][(2020Q1, '%')]
103
- table_dict[index_name][(time_index,item_name)] = item
110
+ try: # table_dict[項目][(2020Q1, '%')]
111
+ if (item_name == 'percentage'):
112
+ if (isinstance(item, (float, int))):
113
+ item = np.round(item, 2)
114
+ if ("YoY" in item_name):
115
+ if (isinstance(item, (float, int))):
116
+ item = np.round(item * 100, 2)
117
+ table_dict[index_name][(time_index, item_name)] = item
104
118
 
105
119
  except KeyError:
106
120
  if (index_name not in table_dict.keys()):
107
121
  table_dict[index_name] = dict()
108
122
 
109
- table_dict[index_name][(time_index,item_name)] = item
123
+ table_dict[index_name][(time_index, item_name)] = item
110
124
 
111
125
  total_table = pd.DataFrame.from_dict(table_dict, orient='index')
112
126
  total_table.columns = pd.MultiIndex.from_tuples(total_table.columns)
@@ -118,5 +132,4 @@ class BalanceSheetFetcher(StatsFetcher):
118
132
  target_index=setting['target_index']
119
133
  if "target_index" in setting.keys() else None)
120
134
 
121
- print(f"{name}: {return_dict[name].columns}")
122
135
  return return_dict
@@ -1,5 +1,6 @@
1
1
  from .base import StatsFetcher, StatsDateTime
2
2
  import json
3
+ import numpy as np
3
4
  import pandas as pd
4
5
  from ..utils import StatsDateTime, StatsProcessor
5
6
  import importlib.resources as pkg_resources
@@ -127,8 +128,9 @@ class CashFlowFetcher(StatsFetcher):
127
128
  'value']
128
129
  if (value['value']):
129
130
  table_dict[time_index][index_name][
130
- 'percentage'] = value['value'] / cash_flow[
131
- main_cash_flow_name]['value']
131
+ 'percentage'] = np.round(
132
+ (value['value'] / cash_flow[
133
+ main_cash_flow_name]['value']) * 100, 2)
132
134
  else:
133
135
  table_dict[time_index][index_name][
134
136
  'percentage'] = None
@@ -141,8 +143,9 @@ class CashFlowFetcher(StatsFetcher):
141
143
  'value']
142
144
  if (value['value']):
143
145
  table_dict[time_index][index_name][
144
- 'percentage'] = value['value'] / cash_flow[
145
- main_cash_flow_name]['value']
146
+ 'percentage'] = np.round(
147
+ (value['value'] / cash_flow[
148
+ main_cash_flow_name]['value']) * 100, 2)
146
149
  else:
147
150
  table_dict[time_index][index_name][
148
151
  'percentage'] = None
@@ -1,5 +1,6 @@
1
1
  from .base import StatsFetcher, StatsDateTime
2
2
  import json
3
+ import numpy as np
3
4
  import pandas as pd
4
5
  from ..utils import StatsDateTime, StatsProcessor
5
6
  import importlib.resources as pkg_resources
@@ -14,8 +15,10 @@ class FinanceOverviewFetcher(StatsFetcher):
14
15
  def __init__(self, ticker, db_client):
15
16
  super().__init__(ticker, db_client)
16
17
 
17
- self.target_fields = StatsProcessor.load_yaml("finance_overview_dict.yaml")
18
- self.inverse_dict = StatsProcessor.load_txt("seasonal_data_field_dict.txt", json_load=True)
18
+ self.target_fields = StatsProcessor.load_yaml(
19
+ "finance_overview_dict.yaml")
20
+ self.inverse_dict = StatsProcessor.load_txt(
21
+ "seasonal_data_field_dict.txt", json_load=True)
19
22
 
20
23
  def prepare_query(self, target_year, target_season):
21
24
 
@@ -83,9 +86,10 @@ class FinanceOverviewFetcher(StatsFetcher):
83
86
  today = StatsDateTime.get_today()
84
87
 
85
88
  year = today.year - 1 if (today.season == 1) else today.year
86
- season = 4 if (today.season == 1) else today.season - 2
89
+ season = 4 if (today.season == 1) else today.season - 1
87
90
  fetched_data = self.collect_data(year, season)
88
91
  finance_dict = fetched_data['seasonal_data'][0]
92
+ FinanceOverviewProcessor.process_rate(finance_dict)
89
93
  FinanceOverviewProcessor.process_all(finance_dict)
90
94
  fetched_data['seasonal_data'] = finance_dict
91
95
  return fetched_data
@@ -93,41 +97,38 @@ class FinanceOverviewFetcher(StatsFetcher):
93
97
 
94
98
  class FinanceOverviewProcessor(StatsProcessor):
95
99
 
100
+ @classmethod
101
+ def process_rate(cls, finance_dict):
102
+ for key in finance_dict:
103
+ if ('YoY' in key):
104
+ finance_dict[key] = StatsProcessor.cal_percentage(
105
+ finance_dict[key])
106
+ elif ("rate" in key or 'ratio' in key):
107
+ finance_dict[key] = StatsProcessor.cal_non_percentage(
108
+ finance_dict[key], to_str=True, postfix='%')
109
+ else:
110
+ finance_dict[key] = StatsProcessor.cal_non_percentage(
111
+ finance_dict[key])
112
+
96
113
  @classmethod
97
114
  def process_all(cls, finance_dict):
98
115
  methods = [
99
- cls.cal_EBIT,
100
- cls.cal_share_outstanding,
101
- cls.cal_fcf,
102
- cls.cal_revenue_per_share,
103
- cls.cal_gross_per_share,
104
- cls.cal_operating_income_per_share,
105
- cls.cal_operating_cash_flow_per_share,
106
- cls.fcf_per_share,
107
- cls.cal_roa,
108
- cls.cal_roe,
109
- cls.cal_gross_over_asset,
110
- cls.cal_roce,
111
- cls.cal_gross_profit_marginal,
112
- cls.cal_operation_profit_rate,
113
- cls.cal_operating_cash_flow_profit_rate,
114
- cls.cal_dso,
115
- cls.cal_account_receive_over_revenue,
116
- cls.cal_dpo,
117
- cls.cal_inventories_cycle_ratio,
118
- cls.cal_dio,
116
+ cls.cal_EBIT, cls.cal_share_outstanding, cls.cal_fcf,
117
+ cls.cal_interest_bearing_debt, cls.cal_revenue_per_share,
118
+ cls.cal_gross_per_share, cls.cal_operating_income_per_share,
119
+ cls.cal_operating_cash_flow_per_share, cls.fcf_per_share,
120
+ cls.cal_roa, cls.cal_roe, cls.cal_gross_over_asset, cls.cal_roce,
121
+ cls.cal_gross_profit_marginal, cls.cal_operation_profit_rate,
122
+ cls.cal_operating_cash_flow_profit_rate, cls.cal_dso,
123
+ cls.cal_account_receive_over_revenue, cls.cal_dpo,
124
+ cls.cal_inventories_cycle_ratio, cls.cal_dio,
119
125
  cls.cal_inventories_revenue_ratio,
120
- cls.cal_cash_of_conversion_cycle,
121
- cls.cal_asset_turnover,
122
- cls.cal_application_turnover,
123
- cls.cal_current_ratio,
124
- cls.cal_quick_ratio,
125
- cls.cal_debt_to_equity_ratio,
126
- cls.cal_net_debt_to_equity_ratio,
127
- cls.cal_interest_coverage_ratio,
126
+ cls.cal_cash_of_conversion_cycle, cls.cal_asset_turnover,
127
+ cls.cal_application_turnover, cls.cal_current_ratio,
128
+ cls.cal_quick_ratio, cls.cal_debt_to_equity_ratio,
129
+ cls.cal_net_debt_to_equity_ratio, cls.cal_interest_coverage_ratio,
128
130
  cls.cal_debt_to_operating_cash_flow,
129
- cls.cal_debt_to_free_cash_flow,
130
- cls.cal_cash_flow_ratio
131
+ cls.cal_debt_to_free_cash_flow, cls.cal_cash_flow_ratio
131
132
  ]
132
133
 
133
134
  for method in methods:
@@ -137,13 +138,13 @@ class FinanceOverviewProcessor(StatsProcessor):
137
138
  def cal_EBIT(cls, finance_dict):
138
139
  """
139
140
  計算EBIT
140
- EBIT = 營業收入 - 營業成本 - 營業費用
141
+ EBIT = 營業收入 - 營業成本 - 營業費用 - 所得稅費用
141
142
  """
142
143
  try:
143
- finance_dict['EBIT'] = (finance_dict['revenue'] -
144
- finance_dict['operating_cost'] -
145
- finance_dict['operating_expenses'])
146
- except (KeyError, TypeError) as e:
144
+ EBIT = (finance_dict['revenue'] - finance_dict['operating_cost'] -
145
+ finance_dict['operating_expenses'] - finance_dict['tax_fee'])
146
+ finance_dict['EBIT'] = StatsProcessor.cal_non_percentage(EBIT)
147
+ except (KeyError, ZeroDivisionError, TypeError) as e:
147
148
  finance_dict['EBIT'] = None
148
149
  print(f"Error calculating EBIT: {e}")
149
150
 
@@ -154,12 +155,32 @@ class FinanceOverviewProcessor(StatsProcessor):
154
155
  自由現金流 = 營業現金流 + 投資現金流
155
156
  """
156
157
  try:
157
- finance_dict["fcf"] = (finance_dict["operating_cash_flow"] +
158
- finance_dict["financing_cash_flow"])
159
- except Exception as e:
158
+ fcf = (finance_dict["operating_cash_flow"] +
159
+ finance_dict["financing_cash_flow"])
160
+ finance_dict["fcf"] = StatsProcessor.cal_non_percentage(fcf)
161
+ except (KeyError, ZeroDivisionError, TypeError) as e:
160
162
  finance_dict['fcf'] = None
161
163
  print(f"Error calculating FCF: {e}")
162
164
 
165
+ @classmethod
166
+ def cal_interest_bearing_debt(cls, finance_dict):
167
+ """
168
+ 計算有息負債
169
+ 短期借款+長期借款
170
+ """
171
+ finance_dict['interest_bearing_debt'] = 0.0
172
+
173
+ try:
174
+ finance_dict['interest_bearing_debt'] += finance_dict[
175
+ 'short_term_liabilities']
176
+ except (KeyError, ZeroDivisionError, TypeError) as e:
177
+ finance_dict['interest_bearing_debt'] += 0.0
178
+ try:
179
+ finance_dict['interest_bearing_debt'] += finance_dict[
180
+ 'long_term_liabilities']
181
+ except (KeyError, ZeroDivisionError, TypeError) as e:
182
+ finance_dict['interest_bearing_debt'] += 0.0
183
+
163
184
  @classmethod
164
185
  def cal_share_outstanding(cls, finance_dict):
165
186
  """
@@ -169,7 +190,7 @@ class FinanceOverviewProcessor(StatsProcessor):
169
190
  try:
170
191
  finance_dict["share_outstanding"] = (finance_dict['net_income'] /
171
192
  finance_dict['eps'])
172
- except KeyError as e:
193
+ except (KeyError, ZeroDivisionError, TypeError) as e:
173
194
  finance_dict['share_outstanding'] = None
174
195
  print(f"share_outstanding failed because of {str(e)}")
175
196
 
@@ -180,9 +201,12 @@ class FinanceOverviewProcessor(StatsProcessor):
180
201
  每股營收 = 營業收入 / 在外流通股數
181
202
  """
182
203
  try:
183
- finance_dict['revenue_per_share'] = (
184
- finance_dict['revenue'] / finance_dict['share_outstanding'])
185
- except KeyError as e:
204
+ revenue_per_share = (finance_dict['revenue'] /
205
+ finance_dict['share_outstanding'])
206
+ finance_dict[
207
+ 'revenue_per_share'] = StatsProcessor.cal_non_percentage(
208
+ revenue_per_share, False)
209
+ except (KeyError, ZeroDivisionError, TypeError) as e:
186
210
  finance_dict['revenue_per_share'] = None
187
211
  print(f"revenue_per_share failed because of {str(e)}")
188
212
 
@@ -194,10 +218,13 @@ class FinanceOverviewProcessor(StatsProcessor):
194
218
  """
195
219
 
196
220
  try:
197
- finance_dict['gross_per_share'] = (
198
- finance_dict['gross_profit'] /
199
- finance_dict['share_outstanding'])
200
- except KeyError as e:
221
+ gross_per_share = (finance_dict['gross_profit'] /
222
+ finance_dict['share_outstanding'])
223
+ finance_dict[
224
+ 'gross_per_share'] = StatsProcessor.cal_non_percentage(
225
+ gross_per_share, False)
226
+
227
+ except (KeyError, ZeroDivisionError, TypeError) as e:
201
228
  finance_dict['gross_per_share'] = None
202
229
  print(f"gross_per_share failed because of {str(e)}")
203
230
 
@@ -208,10 +235,12 @@ class FinanceOverviewProcessor(StatsProcessor):
208
235
  每股營業利益= (當期營業利益)÷(當期在外流通股數)
209
236
  """
210
237
  try:
211
- finance_dict['operating_income_per_share'] = (
212
- finance_dict['operating_income'] /
213
- finance_dict['share_outstanding'])
214
- except KeyError as e:
238
+ operating_income_per_share = (finance_dict['operating_income'] /
239
+ finance_dict['share_outstanding'])
240
+ finance_dict[
241
+ 'operating_income_per_share'] = StatsProcessor.cal_non_percentage(
242
+ operating_income_per_share)
243
+ except (KeyError, ZeroDivisionError, TypeError) as e:
215
244
  finance_dict['operating_income_per_share'] = None
216
245
  print(f"operating_income_per_share failed because of {str(e)}")
217
246
 
@@ -222,10 +251,13 @@ class FinanceOverviewProcessor(StatsProcessor):
222
251
  = (當期營業現金流) ÷(當期在外流通股數)
223
252
  """
224
253
  try:
225
- finance_dict["operating_cash_flow_per_share"] = (
254
+ operating_cash_flow_per_share = (
226
255
  finance_dict["operating_cash_flow"] /
227
256
  finance_dict['share_outstanding'])
228
- except KeyError as e:
257
+ finance_dict[
258
+ "operating_cash_flow_per_share"] = StatsProcessor.cal_non_percentage(
259
+ operating_cash_flow_per_share)
260
+ except (KeyError, ZeroDivisionError, TypeError) as e:
229
261
  finance_dict['operating_cash_flow_per_share'] = None
230
262
  print(f'operating_cash_flow_per_share because of {str(e)}')
231
263
 
@@ -236,9 +268,11 @@ class FinanceOverviewProcessor(StatsProcessor):
236
268
  每股自由現金流 = (當期自由現金流) ÷(當期在外流通股數)
237
269
  """
238
270
  try:
239
- finance_dict['fcf_per_share'] = (finance_dict['fcf'] /
240
- finance_dict['share_outstanding'])
241
- except KeyError as e:
271
+ fcf_per_share = (finance_dict['fcf'] /
272
+ finance_dict['share_outstanding'])
273
+ finance_dict['fcf_per_share'] = StatsProcessor.cal_non_percentage(
274
+ fcf_per_share)
275
+ except (KeyError, ZeroDivisionError, TypeError) as e:
242
276
  finance_dict['fcf_per_share'] = None
243
277
  print(f"fcf_per_share failed because of {str(e)}")
244
278
 
@@ -250,27 +284,35 @@ class FinanceOverviewProcessor(StatsProcessor):
250
284
  計算資產報酬率(ROA)
251
285
  ROA = [ 本期淨利 + 利息費用 × (1-有效稅率) ] ÷(資產總額)
252
286
  """
253
- finance_dict["roa"] = (
287
+ roa = (
254
288
  finance_dict['net_income'] + finance_dict['interest'] +
255
289
  (1 * 0.1) # 有效稅率需要改,這裡先設0.1
256
290
  ) / finance_dict['inventories']
257
291
 
292
+ finance_dict["roa"] = StatsProcessor.cal_percentage(roa)
293
+
258
294
  @classmethod
259
295
  def cal_roe(cls, finance_dict):
260
296
  """
261
297
  計算股東權益報酬率(ROE)
262
298
  ROE = (本期淨利) ÷(權益總額)
263
299
  """
264
- finance_dict['roe'] = (finance_dict['net_income'] /
265
- finance_dict['equity'])
300
+ roe = (finance_dict['net_income'] / finance_dict['equity'])
301
+ finance_dict['roe'] = StatsProcessor.cal_percentage(roe)
266
302
 
267
303
  @classmethod
268
304
  def cal_gross_over_asset(cls, finance_dict):
269
305
  """
270
306
  計算營業毛利/總資產
271
307
  """
272
- finance_dict['gross_over_asset'] = (finance_dict['gross_profit'] /
273
- finance_dict['total_asset'])
308
+ try:
309
+ gross_over_asset = (finance_dict['gross_profit'] /
310
+ finance_dict['total_asset'])
311
+ finance_dict['gross_over_asset'] = StatsProcessor.cal_percentage(
312
+ gross_over_asset)
313
+ except (KeyError, ZeroDivisionError, TypeError) as e:
314
+ finance_dict['gross_over_asset'] = None
315
+ print(f"營業毛利/總資產 failed because of {str(e)}")
274
316
 
275
317
  @classmethod
276
318
  def cal_roce(cls, finance_dict):
@@ -279,11 +321,13 @@ class FinanceOverviewProcessor(StatsProcessor):
279
321
  ROCE = (稅前淨利+利息費用) / (資產總額-流動負債)
280
322
  """
281
323
  try:
282
- finance_dict['roce'] = (
283
- (finance_dict['net_income_before_tax'] +
284
- finance_dict['interest']) /
285
- (finance_dict['asset'] - finance_dict['current_liabilities']))
286
- except KeyError as e:
324
+ roce = ((finance_dict['net_income_before_tax'] +
325
+ finance_dict['interest']) /
326
+ (finance_dict['total_asset'] -
327
+ finance_dict['current_liabilities']))
328
+ finance_dict['roce'] = StatsProcessor.cal_percentage(roce)
329
+
330
+ except (KeyError, ZeroDivisionError, TypeError) as e:
287
331
  finance_dict['roce'] = None
288
332
  print(f"ROCE failed because of {str(e)}")
289
333
 
@@ -294,8 +338,11 @@ class FinanceOverviewProcessor(StatsProcessor):
294
338
  營業毛利率 = 營業毛利 ÷ 營業收入
295
339
  """
296
340
  try:
297
- finance_dict['gross_profit_margin'] = (
298
- finance_dict['gross_profit'] / finance_dict['revenue'])
341
+ gross_profit_margin = (finance_dict['gross_profit'] /
342
+ finance_dict['revenue'])
343
+ finance_dict[
344
+ 'gross_profit_margin'] = StatsProcessor.cal_percentage(
345
+ gross_profit_margin)
299
346
  except:
300
347
  finance_dict['gross_profit_margin'] = None
301
348
  print(f"gross_profit_margin failed because of {str(e)}")
@@ -307,10 +354,13 @@ class FinanceOverviewProcessor(StatsProcessor):
307
354
  營業利益率 = ( 營業收入-營業成本-營業費用)÷ 營業收入
308
355
  """
309
356
  try:
310
- finance_dict["operation_profit_rate"] = (
357
+ operation_profit_rate = (
311
358
  finance_dict['revenue'] - finance_dict['operating_cost'] -
312
- finance_dict['operating_price']) / finance_dict['revenue']
313
- except KeyError as e:
359
+ finance_dict['operating_expenses']) / finance_dict['revenue']
360
+ finance_dict[
361
+ "operation_profit_rate"] = StatsProcessor.cal_percentage(
362
+ operation_profit_rate)
363
+ except (KeyError, ZeroDivisionError, TypeError) as e:
314
364
  finance_dict["operation_profit_rate"] = None
315
365
  print(f"operation_profit failed because of {str(e)}")
316
366
 
@@ -321,11 +371,13 @@ class FinanceOverviewProcessor(StatsProcessor):
321
371
  營業現金流利潤率 = 營業活動現金流 ÷ 營業收入
322
372
  """
323
373
  try:
324
- finance_dict["operating_cash_flow_profit_rate"] = (
374
+ operating_cash_flow_profit_rate = (
325
375
  finance_dict["operating_cash_flow"] / finance_dict["revenue"])
326
- except KeyError:
376
+ finance_dict[
377
+ "operating_cash_flow_profit_rate"] = StatsProcessor.cal_percentage(
378
+ operating_cash_flow_profit_rate)
379
+ except (KeyError, ZeroDivisionError, TypeError) as e:
327
380
  finance_dict["operating_cash_flow_profit_rate"] = None
328
-
329
381
  print(
330
382
  f"operating_cash_flow_profit_rate failed because of {str(e)}")
331
383
 
@@ -342,10 +394,16 @@ class FinanceOverviewProcessor(StatsProcessor):
342
394
  def cal_dso(cls, finance_dict):
343
395
  """
344
396
  計算應收帳款收現天數(DSO)
345
- DSO = 365 × (營業收入 ÷ 應收帳款平均餘額)
397
+ DSO = 365 × (應收帳款平均餘額 ÷ 營業收入)
346
398
  """
347
- finance_dict['dso'] = (
348
- 365 * (finance_dict['revenue'] / finance_dict['account_pay']))
399
+ try:
400
+ dso = (365 *
401
+ (finance_dict['account_pay'] / finance_dict['revenue']))
402
+ finance_dict['dso'] = StatsProcessor.cal_non_percentage(
403
+ dso, to_str=True, postfix="日")
404
+ except:
405
+ finance_dict['dso'] = None
406
+ print(f"Error calculating 應收帳款收現天數 because of {str(e)}")
349
407
 
350
408
  @classmethod
351
409
  def cal_account_receive_over_revenue(cls, finance_dict):
@@ -353,8 +411,11 @@ class FinanceOverviewProcessor(StatsProcessor):
353
411
  計算應收帳款佔營收比率
354
412
  = 應收帳款平均餘額 ÷ 營業收入
355
413
  """
356
- finance_dict["account_receive_over_revenue"] = (
357
- finance_dict['account_receive'] / finance_dict['revenue'])
414
+ account_receive_over_revenue = (finance_dict['account_receive'] /
415
+ finance_dict['revenue'])
416
+ finance_dict[
417
+ "account_receive_over_revenue"] = StatsProcessor.cal_percentage(
418
+ account_receive_over_revenue)
358
419
 
359
420
  @classmethod
360
421
  def cal_dpo(cls, finance_dict):
@@ -362,9 +423,15 @@ class FinanceOverviewProcessor(StatsProcessor):
362
423
  計算應付帳款週轉天數
363
424
  DPO = 365天 ÷ (銷貨成本÷平均應付帳款)
364
425
  """
365
- finance_dict["dpo"] = (
366
- 365 *
367
- (finance_dict['operating_cost'] / finance_dict['account_pay']))
426
+ try:
427
+ dpo = (
428
+ 365 *
429
+ (finance_dict['account_pay'] / finance_dict['operating_cost']))
430
+ finance_dict["dpo"] = StatsProcessor.cal_non_percentage(
431
+ dpo, to_str=True, postfix="日")
432
+ except (KeyError, ZeroDivisionError, TypeError) as e:
433
+ finance_dict["dpo"] = None
434
+ print(f"應付帳款週轉天數 failed because of {str(e)}")
368
435
 
369
436
  @classmethod
370
437
  def cal_inventories_cycle_ratio(cls, finance_dict):
@@ -372,19 +439,32 @@ class FinanceOverviewProcessor(StatsProcessor):
372
439
  計算存貨周轉率
373
440
  = 銷貨成本 ÷ 存貨
374
441
  """
442
+ try:
443
+ inventories_cycle_ratio = (finance_dict['operating_cost'] /
444
+ finance_dict['inventories'])
375
445
 
376
- finance_dict["inventories_cycle_ratio"] = (
377
- finance_dict['operating_cost'] / finance_dict['inventories'])
446
+ finance_dict[
447
+ "inventories_cycle_ratio"] = StatsProcessor.cal_percentage(
448
+ inventories_cycle_ratio)
449
+ except (KeyError, ZeroDivisionError, TypeError) as e:
450
+ finance_dict["inventories_cycle_ratio"] = None
451
+ print(f"Error calculating 存貨周轉率 because of {str(e)}")
378
452
 
379
453
  @classmethod
380
454
  def cal_dio(cls, finance_dict):
381
455
  """
382
- 計算 存貨週轉天數
383
- DIO = 365天 ÷ (銷貨成本 ÷ 存貨)
384
- MUDA MUDA MUDA MUDA !!!
456
+ 計算 存貨週轉天數 or 平均售貨天數
457
+ DIO = 365天 * (存貨 ÷ 銷貨成本)
458
+ MUDA MUDA MUDA !!!
385
459
  """
386
- finance_dict["dio"] = (finance_dict["operating_cost"] /
387
- finance_dict["inventories"])
460
+ try:
461
+ dio = 365 * (finance_dict["inventories"] /
462
+ finance_dict["operating_cost"])
463
+ finance_dict["dio"] = StatsProcessor.cal_non_percentage(
464
+ dio, to_str=True, postfix="日")
465
+ except (KeyError, ZeroDivisionError, TypeError) as e:
466
+ finance_dict["dio"] = None
467
+ print(f"Error calculating 存貨週轉天數 because of {str(e)}")
388
468
 
389
469
  @classmethod
390
470
  def cal_inventories_revenue_ratio(cls, finance_dict):
@@ -392,8 +472,16 @@ class FinanceOverviewProcessor(StatsProcessor):
392
472
  計算存貨佔營收比率
393
473
  存貨佔營收比= 存貨 ÷ 營業收入
394
474
  """
395
- finance_dict["inventories_revenue_ratio"] = (
396
- finance_dict['inventories'] / finance_dict['revenue'])
475
+ try:
476
+ inventories_revenue_ratio = (finance_dict['inventories'] /
477
+ finance_dict['revenue'])
478
+
479
+ finance_dict[
480
+ "inventories_revenue_ratio"] = StatsProcessor.cal_percentage(
481
+ inventories_revenue_ratio)
482
+ except (KeyError, ZeroDivisionError, TypeError) as e:
483
+ finance_dict["inventories_revenue_ratio"] = None
484
+ print(f"Error calculating 存貨佔營收比率 because of {str(e)}")
397
485
 
398
486
  @classmethod
399
487
  def cal_cash_of_conversion_cycle(cls, finance_dict):
@@ -401,19 +489,42 @@ class FinanceOverviewProcessor(StatsProcessor):
401
489
  計算現金循環週期
402
490
  存貨週轉天數 + 應收帳款週轉天數 - 應付帳款週轉天數
403
491
  """
404
- finance_dict["cash_of_conversion_cycle"] = (finance_dict["dio"] +
405
- finance_dict["dso"] -
406
- finance_dict['dpo'])
492
+ try:
493
+ cash_of_conversion_cycle = (finance_dict["dio"] +
494
+ finance_dict["dso"] -
495
+ finance_dict['dpo'])
496
+ finance_dict[
497
+ "cash_of_conversion_cycle"] = StatsProcessor.cal_non_percentage(
498
+ cash_of_conversion_cycle, to_str=True, postfix="日")
499
+ except (KeyError, ZeroDivisionError, TypeError) as e:
500
+ finance_dict["cash_of_conversion_cycle"] = None
407
501
 
408
502
  @classmethod
409
503
  def cal_asset_turnover(cls, finance_dict):
410
- finance_dict["asset_turnover"] = (finance_dict["revenue"] /
411
- finance_dict["inventories"])
504
+ """
505
+ 計算資產周轉率
506
+ 營業收入 ÷ 資產總額
507
+ """
508
+ asset_turnover = (finance_dict["revenue"] /
509
+ finance_dict["inventories"])
510
+ finance_dict["asset_turnover"] = StatsProcessor.cal_percentage(
511
+ asset_turnover)
412
512
 
413
513
  @classmethod
414
514
  def cal_application_turnover(cls, finance_dict):
415
- finance_dict['applcation_turnover'] = (finance_dict['revenue'] /
416
- finance_dict["application"])
515
+ """
516
+ 不動產、廠房及設備週轉率
517
+ 營業收入 ÷ 不動產、廠房與設備平均餘額
518
+ """
519
+ try:
520
+ applcation_turnover = (finance_dict['revenue'] /
521
+ finance_dict["application"])
522
+ finance_dict[
523
+ 'applcation_turnover'] = StatsProcessor.cal_percentage(
524
+ applcation_turnover)
525
+
526
+ except (KeyError, ZeroDivisionError, TypeError) as e:
527
+ finance_dict['application_turnover'] = None
417
528
 
418
529
  @classmethod
419
530
  def cal_current_ratio(cls, finance_dict):
@@ -421,81 +532,117 @@ class FinanceOverviewProcessor(StatsProcessor):
421
532
  計算流動比率 = 流動資產 / 流動負債
422
533
  """
423
534
  try:
424
- finance_dict['current_ratio'] = finance_dict[
425
- 'current_assets'] / finance_dict['current_liabilities']
535
+ current_ratio = (finance_dict['current_assets'] /
536
+ finance_dict['current_liabilities'])
537
+ finance_dict['current_ratio'] = StatsProcessor.cal_percentage(
538
+ current_ratio)
426
539
  except (KeyError, ZeroDivisionError, TypeError) as e:
427
540
  finance_dict['current_ratio'] = None
428
541
  print(f"Error calculating current ratio: {e}")
429
542
 
430
543
  @classmethod
431
544
  def cal_quick_ratio(cls, finance_dict):
545
+ """
546
+ 速動比率
547
+ (流動資產 - 存貨) / 流動負債
548
+ """
432
549
  try:
433
- # 速動比率 = (流動資產 - 存貨) / 流動負債
434
- finance_dict['quick_ratio'] = (
435
- finance_dict['current_assets'] - finance_dict['inventories']
436
- ) / finance_dict['current_liabilities']
550
+ quick_ratio = (finance_dict['current_assets'] -
551
+ finance_dict['inventories']
552
+ ) / finance_dict['current_liabilities']
553
+ finance_dict['quick_ratio'] = StatsProcessor.cal_percentage(
554
+ quick_ratio)
437
555
  except (KeyError, ZeroDivisionError, TypeError) as e:
438
556
  finance_dict['quick_ratio'] = None
439
557
  print(f"Error calculating quick ratio: {e}")
440
558
 
441
559
  @classmethod
442
560
  def cal_debt_to_equity_ratio(cls, finance_dict):
561
+ """
562
+ # 負債權益比率 = 總負債 / 股東權益
563
+ """
443
564
  try:
444
- # 負債權益比率 = 總負債 / 股東權益
445
- finance_dict['debt_to_equity_ratio'] = finance_dict[
565
+ debt_to_equity_ratio = finance_dict[
446
566
  'total_liabilities'] / finance_dict['equity']
567
+ finance_dict[
568
+ 'debt_to_equity_ratio'] = StatsProcessor.cal_percentage(
569
+ debt_to_equity_ratio)
447
570
  except (KeyError, ZeroDivisionError, TypeError) as e:
448
571
  finance_dict['debt_to_equity_ratio'] = None
449
572
  print(f"Error calculating debt to equity ratio: {e}")
450
573
 
451
574
  @classmethod
452
575
  def cal_net_debt_to_equity_ratio(cls, finance_dict):
576
+ """
577
+ # 淨負債權益比率 = (總負債 - 現金及約當現金) / 股東權益
578
+ """
453
579
  try:
454
- # 淨負債權益比率 = (總負債 - 現金及約當現金) / 股東權益
455
- finance_dict['net_debt_to_equity_ratio'] = (
580
+ net_debt_to_equity_ratio = (
456
581
  finance_dict['total_liabilities'] -
457
582
  finance_dict['cash_and_cash_equivalents']
458
583
  ) / finance_dict['equity']
584
+ finance_dict[
585
+ 'net_debt_to_equity_ratio'] = StatsProcessor.cal_percentage(
586
+ net_debt_to_equity_ratio)
459
587
  except (KeyError, ZeroDivisionError, TypeError) as e:
460
588
  finance_dict['net_debt_to_equity_ratio'] = None
461
589
  print(f"Error calculating net debt to equity ratio: {e}")
462
590
 
463
591
  @classmethod
464
592
  def cal_interest_coverage_ratio(cls, finance_dict):
593
+ """
594
+ # 利息保障倍數 = EBIT / 利息費用
595
+ """
465
596
  try:
466
- # 利息保障倍數 = EBIT / 利息費用
467
- finance_dict['interest_coverage_ratio'] = finance_dict[
468
- 'EBIT'] / finance_dict['interest_expense']
597
+ interest_coverage_ratio = finance_dict['EBIT'] / finance_dict[
598
+ 'interest_expense']
599
+ finance_dict[
600
+ 'interest_coverage_ratio'] = StatsProcessor.cal_non_percentage(
601
+ interest_coverage_ratio, to_str=True, postfix="倍")
469
602
  except (KeyError, ZeroDivisionError, TypeError) as e:
470
603
  finance_dict['interest_coverage_ratio'] = None
471
604
  print(f"Error calculating interest coverage ratio: {e}")
472
605
 
473
606
  @classmethod
474
607
  def cal_debt_to_operating_cash_flow(cls, finance_dict):
608
+ """
609
+ 有息負債 / 營業活動現金流
610
+ """
475
611
  try:
476
- # 有息負債 / 營業活動現金流
477
- finance_dict['debt_to_operating_cash_flow'] = finance_dict[
612
+ debt_to_operating_cash_flow = finance_dict[
478
613
  'interest_bearing_debt'] / finance_dict['operating_cash_flow']
614
+ finance_dict[
615
+ 'debt_to_operating_cash_flow'] = StatsProcessor.cal_percentage(
616
+ debt_to_operating_cash_flow)
479
617
  except (KeyError, ZeroDivisionError, TypeError) as e:
480
618
  finance_dict['debt_to_operating_cash_flow'] = None
481
619
  print(f"Error calculating debt to operating cash flow: {e}")
482
620
 
483
621
  @classmethod
484
622
  def cal_debt_to_free_cash_flow(cls, finance_dict):
623
+ """
624
+ # 有息負債 / 自由現金流
625
+ """
485
626
  try:
486
- # 有息負債 / 自由現金流
487
- finance_dict['debt_to_free_cash_flow'] = finance_dict[
627
+ debt_to_free_cash_flow = finance_dict[
488
628
  'interest_bearing_debt'] / finance_dict['fcf']
629
+ finance_dict[
630
+ 'debt_to_free_cash_flow'] = StatsProcessor.cal_percentage(
631
+ debt_to_free_cash_flow)
489
632
  except (KeyError, ZeroDivisionError, TypeError) as e:
490
633
  finance_dict['debt_to_free_cash_flow'] = None
491
634
  print(f"Error calculating debt to free cash flow: {e}")
492
635
 
493
636
  @classmethod
494
637
  def cal_cash_flow_ratio(cls, finance_dict):
638
+ """
639
+ # 現金流量比率 = 營業活動現金流 / 流動負債
640
+ """
495
641
  try:
496
- # 現金流量比率 = 營業活動現金流 / 流動負債
497
- finance_dict['cash_flow_ratio'] = finance_dict[
642
+ cash_flow_ratio = finance_dict[
498
643
  'operating_cash_flow'] / finance_dict['current_liabilities']
644
+ finance_dict['cash_flow_ratio'] = StatsProcessor.cal_percentage(
645
+ cash_flow_ratio)
499
646
  except (KeyError, ZeroDivisionError, TypeError) as e:
500
647
  finance_dict['cash_flow_ratio'] = None
501
648
  print(f"Error calculating cash flow ratio: {e}")
@@ -1,11 +1,13 @@
1
1
  from .base import StatsFetcher, StatsDateTime
2
+ import importlib.resources as pkg_resources
2
3
  import json
4
+ import numpy as np
3
5
  import pandas as pd
4
6
  from ..utils import StatsDateTime, StatsProcessor
5
- import importlib.resources as pkg_resources
6
7
  import yaml
7
8
 
8
9
 
10
+
9
11
  class ProfitLoseFetcher(StatsFetcher):
10
12
  """
11
13
  iFa.ai: 財務分析 -> 損益表
@@ -108,6 +110,12 @@ class ProfitLoseFetcher(StatsFetcher):
108
110
  for index_name, value_dict in profit_lose.items():
109
111
  # (2020Q1, 項目, 金額或%)
110
112
  for item_name, item in value_dict.items():
113
+ if (item_name == 'percentage'):
114
+ if (isinstance(item, (float, int))):
115
+ item = np.round(item, 2)
116
+ if ('YoY' in item_name):
117
+ if (isinstance(item, (float, int))):
118
+ item = np.round(item * 100, 2)
111
119
  try:
112
120
  table_dict[index_name][(time_index, item_name)] = item
113
121
 
@@ -121,6 +129,8 @@ class ProfitLoseFetcher(StatsFetcher):
121
129
  total_table = pd.DataFrame.from_dict(table_dict, orient='index')
122
130
  total_table.columns = pd.MultiIndex.from_tuples(total_table.columns)
123
131
 
132
+ total_table = total_table.replace("N/A", None)
133
+
124
134
  for name, setting in self.table_settings.items():
125
135
  return_dict[name] = StatsProcessor.slice_multi_col_table(
126
136
  total_table=total_table,
@@ -15,22 +15,22 @@ net_income:
15
15
  field: 本期淨利(淨損)
16
16
  value: value
17
17
 
18
+ tax_fee:
19
+ field: 所得稅費用(利益)合計
20
+ value: value
21
+
18
22
  # TODO: 以下所爬到的資料都是累計的,Ifa有額外計算當季的變化量
19
23
  operating_cash_flow:
20
24
  field: 營業活動之淨現金流入(流出)
21
- value: value
25
+ value: single_season_value
22
26
 
23
27
  invest_cash_flow:
24
28
  field: 投資活動之淨現金流入(流出)
25
- value: value
29
+ value: single_season_value
26
30
 
27
31
  financing_cash_flow:
28
32
  field: 籌資活動之淨現金流入(流出)
29
- value: value
30
-
31
- fcf:
32
- field: 本期現金及約當現金增加(減少)數
33
- value: value
33
+ value: single_season_value
34
34
  # ^^^ 以上皆需要額外在DataBase處理
35
35
 
36
36
  # 每股財務狀況
@@ -84,7 +84,7 @@ net_income_YoY:
84
84
 
85
85
  operating_cash_flow_YoY:
86
86
  field: 營業活動之淨現金流入(流出)
87
- value: YoY_1
87
+ value: single_season_YoY
88
88
 
89
89
  # operating_cash_flow_per_share_YoY:
90
90
  # field: 每股營業現金流年成長率
@@ -123,6 +123,13 @@ total_liabilities:
123
123
  field: 負債總額
124
124
  value: value
125
125
 
126
+ short_term_liabilities:
127
+ field: 短期借款
128
+ value: value
129
+
130
+ long_term_liabilities:
131
+ field: 長期借款
132
+ value: value
126
133
  #
127
134
  cash_and_cash_equivalents:
128
135
  field: 現金及約當現金
@@ -23,6 +23,7 @@
23
23
  "非流動資產合計": "balance_sheet",
24
24
  "資產總額": "balance_sheet",
25
25
  "短期借款": "balance_sheet",
26
+ "長期借款": "balance_sheet",
26
27
  "透過損益按公允價值衡量之金融負債-流動": "balance_sheet",
27
28
  "應付票據": "balance_sheet",
28
29
  "應付帳款": "balance_sheet",
@@ -1,5 +1,6 @@
1
1
  from importlib.resources import files
2
2
  import json
3
+ import numpy as np
3
4
  import pandas as pd
4
5
  import yaml
5
6
 
@@ -117,8 +118,9 @@ class StatsProcessor:
117
118
  sliced_table = sliced_table.pivot(index='level_1',
118
119
  columns='level_0',
119
120
  values=target_index).sort_index(
120
- axis=1, level = 1,ascending = False
121
- )
121
+ axis=1,
122
+ level=1,
123
+ ascending=False)
122
124
 
123
125
  sliced_table.columns = sliced_table.columns.get_level_values(1)
124
126
  sliced_table.columns.name = None
@@ -136,3 +138,27 @@ class StatsProcessor:
136
138
  ]
137
139
  return return_table
138
140
 
141
+ @classmethod
142
+ def cal_percentage(cls, value, postfix="%"):
143
+ if (isinstance(value, (float, int))):
144
+ value = np.round(value * 100 , 2).item()
145
+ value = f"{value:.2f}{postfix}"
146
+
147
+ return value
148
+
149
+ else:
150
+ return value
151
+
152
+ @classmethod
153
+ def cal_non_percentage(cls, value, to_str=False, postfix="元"):
154
+ if (isinstance(value, (float, int))):
155
+ value = np.round(value, 2).item()
156
+ if (to_str):
157
+ value = f"{value:.2f}{postfix}"
158
+ return value
159
+
160
+ else:
161
+ return value
162
+
163
+ else:
164
+ return value
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: neurostats-API
3
- Version: 0.0.7
3
+ Version: 0.0.8
4
4
  Summary: The service of NeuroStats website
5
5
  Home-page: https://github.com/NeurowattStats/NeuroStats_API.git
6
6
  Author: JasonWang@Neurowatt
@@ -78,7 +78,7 @@ pip install neurostats-API
78
78
  ```Python
79
79
  >>> import neurostats_API
80
80
  >>> print(neurostats_API.__version__)
81
- 0.0.6
81
+ 0.0.8
82
82
  ```
83
83
 
84
84
  ### 得到最新一期的評價資料與歷年評價
@@ -379,11 +379,12 @@ stats_fetcher.query_data()
379
379
 
380
380
  ### 現金流量表
381
381
  ``` Python
382
- from neurostats_API.utils import StatsFetcher, DBClient
382
+ from neurostats_API.fetchers import CashFlowFetcher
383
383
  db_client = DBClient("<連接的DB位置>").get_client()
384
- fetcher = StatsFetcher(db_client)
385
384
  ticker = 2330 # 換成tw50內任意ticker
386
- stats_fetcher.get_cash_flow(ticker)
385
+ fetcher = StatsFetcher(ticker, db_client)
386
+
387
+ stats_fetcher.query()
387
388
  ```
388
389
  #### 回傳
389
390
  ```Python
@@ -1,26 +1,26 @@
1
- neurostats_API/__init__.py,sha256=3Kn8sHWnxjlagph2LmftcF8JLlcMlmQIbU5t_jzgK3w,19
1
+ neurostats_API/__init__.py,sha256=9_jSwg7P5SlFv0Ci2ZSYBcAbygp9XV2C8sryRO8tvko,19
2
2
  neurostats_API/cli.py,sha256=UJSWLIw03P24p-gkBb6JSEI5dW5U12UvLf1L8HjQD-o,873
3
3
  neurostats_API/main.py,sha256=QcsfmWivg2Dnqw3MTJWiI0QvEiRs0VuH-BjwQHFCv00,677
4
4
  neurostats_API/fetchers/__init__.py,sha256=U_OMG-mLpsVKYnCBrW2OjFuCzvPeVQ__7A676vGzztY,313
5
- neurostats_API/fetchers/balance_sheet.py,sha256=FPsVobaNzFOxpXCo1Ui_rPmlG1crTRj9ukqQ4J8aiJg,4268
5
+ neurostats_API/fetchers/balance_sheet.py,sha256=kOpk_83qeNgfhjF44UEmma8k6V6qTsIaFYiEcSVV20A,4910
6
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
7
+ neurostats_API/fetchers/cash_flow.py,sha256=5xN5YPGb7i4slDYe_KI2ucL4kh733iC5LLOEmm4J8mM,7137
8
+ neurostats_API/fetchers/finance_overview.py,sha256=-cUb4wWr02xKhNCAXLuduhpvXsO0b14hJLqJqhagooY,25307
9
9
  neurostats_API/fetchers/month_revenue.py,sha256=RNA7ROl2vm8Xbib3k50p_1shsHDVSKIbHkyNiRa8yMw,3182
10
- neurostats_API/fetchers/profit_lose.py,sha256=ffEVNo7-fvtnAq2_gj-Ga55TGW7pPd6WhruOZH8NGYM,4463
10
+ neurostats_API/fetchers/profit_lose.py,sha256=aCvcTbe1FjR3oi8QIDZg0c6G7-r0B-cCdfj6Rtlw0Jw,4870
11
11
  neurostats_API/fetchers/tech.py,sha256=wH1kkqiETQhF0HAhk-UIiucnZ3EiL85Q-yMWCcVOiFM,11395
12
12
  neurostats_API/fetchers/value_invest.py,sha256=tg8yELbVnTFTEclrwgXnCRW377KkcoLiP-Gk2pyM-9Y,2886
13
13
  neurostats_API/tools/balance_sheet.yaml,sha256=dKTMbsYR9EFp48WAzmm_ISHMiJQLyE0V-XWS_gkxmr0,541
14
14
  neurostats_API/tools/cash_flow_percentage.yaml,sha256=fk2Z4eb1JjGFvP134eJatHacB7BgTkBenhDJr83w8RE,1345
15
- neurostats_API/tools/finance_overview_dict.yaml,sha256=Vvf8bv23NwJP8Yyw8DPS8c0_jjT_Wctnnz51SHS4AeI,2335
15
+ neurostats_API/tools/finance_overview_dict.yaml,sha256=URL1IFqO0j5uOwN3xETHriy_u9lYbLvdwghuznenP2Q,2500
16
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
17
+ neurostats_API/tools/seasonal_data_field_dict.txt,sha256=Za1fJR1yERbqrX8TgsS2kmMYMbaye43Gu_5ukUNBCNM,7904
18
18
  neurostats_API/utils/__init__.py,sha256=FTYKRFzW2XVXdnSHXnS3mQQaHlKF9xGqrMsgZZ2kroc,142
19
- neurostats_API/utils/data_process.py,sha256=rRKf2H0X2J-tDXDreErcz3Y3TGb8_0Q6GKe0izRjnmA,4942
19
+ neurostats_API/utils/data_process.py,sha256=m1B4EhCNSzOMfTBDtYCjkQSjbDTAEFC6TNf3NNxV36k,5657
20
20
  neurostats_API/utils/datetime.py,sha256=I9CIgZdE5OMzUciOS5wvapOVEIrXG_0Qb6iDKfIod6c,574
21
21
  neurostats_API/utils/db_client.py,sha256=OYe6yazcR4Aa6jYmy47JrryUeh2NnKGqY2K_lSZe6i8,455
22
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,,
23
+ neurostats_API-0.0.8.dist-info/METADATA,sha256=SCspApNeq7b9pflJC30SaOVCdZtQjBIbh6QOps9HnGw,18232
24
+ neurostats_API-0.0.8.dist-info/WHEEL,sha256=bFJAMchF8aTQGUgMZzHJyDDMPTO3ToJ7x23SLJa1SVo,92
25
+ neurostats_API-0.0.8.dist-info/top_level.txt,sha256=nSlQPMG0VtXivJyedp4Bkf86EOy2TpW10VGxolXrqnU,15
26
+ neurostats_API-0.0.8.dist-info/RECORD,,