neurostats-API 0.0.25__tar.gz → 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. neurostats_api-1.0.0/MANIFEST.in +9 -0
  2. neurostats_api-1.0.0/PKG-INFO +102 -0
  3. neurostats_api-1.0.0/README.md +85 -0
  4. neurostats_api-1.0.0/neurostats_API/__init__.py +29 -0
  5. neurostats_api-1.0.0/neurostats_API/async_mode/__init__.py +13 -0
  6. neurostats_api-1.0.0/neurostats_API/async_mode/db/__init__.py +3 -0
  7. neurostats_api-1.0.0/neurostats_API/async_mode/db/base.py +24 -0
  8. neurostats_api-1.0.0/neurostats_API/async_mode/db/tej.py +10 -0
  9. neurostats_api-1.0.0/neurostats_API/async_mode/db/twse.py +8 -0
  10. neurostats_api-1.0.0/neurostats_API/async_mode/db/us.py +9 -0
  11. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/__init__.py +20 -0
  12. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/base.py +66 -0
  13. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/daily/__init__.py +7 -0
  14. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/daily/base.py +89 -0
  15. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/daily/tej_chip.py +14 -0
  16. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/daily/tej_tech.py +12 -0
  17. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/daily/twse_chip.py +49 -0
  18. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/daily/value.py +93 -0
  19. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/daily/yf.py +12 -0
  20. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/month_revenue/__init__.py +1 -0
  21. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/month_revenue/base.py +140 -0
  22. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/month_revenue/twse.py +5 -0
  23. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/seasonal/__init__.py +4 -0
  24. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/seasonal/balance_sheet.py +19 -0
  25. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/seasonal/base.py +152 -0
  26. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/seasonal/cashflow.py +10 -0
  27. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/seasonal/profit_lose.py +17 -0
  28. neurostats_api-1.0.0/neurostats_API/async_mode/db_extractors/seasonal/tej.py +87 -0
  29. neurostats_api-1.0.0/neurostats_API/async_mode/factory/__init__.py +1 -0
  30. neurostats_api-1.0.0/neurostats_API/async_mode/factory/extractor_factory.py +168 -0
  31. neurostats_api-1.0.0/neurostats_API/async_mode/factory/transformer_factory.py +164 -0
  32. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/__init__.py +10 -0
  33. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/balance_sheet.py +31 -0
  34. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/base.py +48 -0
  35. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/cash_flow.py +56 -0
  36. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/finance_overview.py +134 -0
  37. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/month_revenue.py +35 -0
  38. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/profit_lose.py +46 -0
  39. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/tech.py +205 -0
  40. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/tej/__init__.py +2 -0
  41. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/tej/seasonal_data.py +88 -0
  42. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/tej/tech.py +34 -0
  43. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/twse_institution.py +62 -0
  44. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/twse_margin.py +100 -0
  45. neurostats_api-1.0.0/neurostats_API/async_mode/fetchers/value.py +76 -0
  46. neurostats_api-1.0.0/neurostats_API/config/company_list/ticker_index_industry_map.json +7946 -0
  47. neurostats_api-1.0.0/neurostats_API/config/company_list/us.json +9986 -0
  48. {neurostats_api-0.0.25/neurostats_API/tools → neurostats_api-1.0.0/neurostats_API/config}/tej_db/tej_db_skip_index.yaml +0 -2
  49. {neurostats_api-0.0.25/neurostats_API/tools → neurostats_api-1.0.0/neurostats_API/config}/twse/profit_lose.yaml +0 -6
  50. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/fetchers/finance_overview.py +22 -2
  51. neurostats_api-1.0.0/neurostats_API/transformers/__init__.py +40 -0
  52. neurostats_api-1.0.0/neurostats_API/transformers/balance_sheet/__init__.py +2 -0
  53. neurostats_api-1.0.0/neurostats_API/transformers/balance_sheet/base.py +51 -0
  54. neurostats_api-1.0.0/neurostats_API/transformers/balance_sheet/twse.py +81 -0
  55. neurostats_api-1.0.0/neurostats_API/transformers/balance_sheet/us.py +38 -0
  56. neurostats_api-1.0.0/neurostats_API/transformers/base.py +158 -0
  57. neurostats_api-1.0.0/neurostats_API/transformers/cash_flow/__init__.py +2 -0
  58. neurostats_api-1.0.0/neurostats_API/transformers/cash_flow/base.py +114 -0
  59. neurostats_api-1.0.0/neurostats_API/transformers/cash_flow/twse.py +70 -0
  60. neurostats_api-1.0.0/neurostats_API/transformers/cash_flow/us.py +38 -0
  61. neurostats_api-1.0.0/neurostats_API/transformers/daily_chip/__init__.py +1 -0
  62. neurostats_api-1.0.0/neurostats_API/transformers/daily_chip/base.py +5 -0
  63. neurostats_api-1.0.0/neurostats_API/transformers/daily_chip/tej.py +0 -0
  64. neurostats_api-1.0.0/neurostats_API/transformers/daily_chip/twse_chip.py +415 -0
  65. neurostats_api-1.0.0/neurostats_API/transformers/daily_chip/utils/__init__.py +0 -0
  66. neurostats_api-1.0.0/neurostats_API/transformers/daily_chip/utils/institution.py +90 -0
  67. neurostats_api-1.0.0/neurostats_API/transformers/daily_chip/utils/margin_trading.py +2 -0
  68. neurostats_api-1.0.0/neurostats_API/transformers/daily_chip/utils/security_lending.py +0 -0
  69. neurostats_api-1.0.0/neurostats_API/transformers/daily_tech/__init__.py +1 -0
  70. neurostats_api-1.0.0/neurostats_API/transformers/daily_tech/base.py +5 -0
  71. neurostats_api-1.0.0/neurostats_API/transformers/daily_tech/tech.py +84 -0
  72. neurostats_api-1.0.0/neurostats_API/transformers/daily_tech/utils/__init__.py +1 -0
  73. neurostats_api-1.0.0/neurostats_API/transformers/daily_tech/utils/processor.py +251 -0
  74. neurostats_api-1.0.0/neurostats_API/transformers/finance_overview/__init__.py +2 -0
  75. neurostats_api-1.0.0/neurostats_API/transformers/finance_overview/agent_overview.py +55 -0
  76. neurostats_api-1.0.0/neurostats_API/transformers/finance_overview/base.py +824 -0
  77. neurostats_api-1.0.0/neurostats_API/transformers/finance_overview/stats_overview.py +79 -0
  78. neurostats_api-1.0.0/neurostats_API/transformers/month_revenue/__init__.py +1 -0
  79. neurostats_api-1.0.0/neurostats_API/transformers/month_revenue/base.py +60 -0
  80. neurostats_api-1.0.0/neurostats_API/transformers/month_revenue/twse.py +134 -0
  81. neurostats_api-1.0.0/neurostats_API/transformers/profit_lose/__init__.py +2 -0
  82. neurostats_api-1.0.0/neurostats_API/transformers/profit_lose/base.py +82 -0
  83. neurostats_api-1.0.0/neurostats_API/transformers/profit_lose/twse.py +133 -0
  84. neurostats_api-1.0.0/neurostats_API/transformers/profit_lose/us.py +26 -0
  85. neurostats_api-1.0.0/neurostats_API/transformers/tej/__init__.py +1 -0
  86. neurostats_api-1.0.0/neurostats_API/transformers/tej/base.py +149 -0
  87. neurostats_api-1.0.0/neurostats_API/transformers/tej/finance_statement.py +80 -0
  88. neurostats_api-1.0.0/neurostats_API/transformers/value/__init__.py +1 -0
  89. neurostats_api-1.0.0/neurostats_API/transformers/value/base.py +5 -0
  90. neurostats_api-1.0.0/neurostats_API/transformers/value/tej.py +8 -0
  91. neurostats_api-1.0.0/neurostats_API/transformers/value/twse.py +48 -0
  92. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/utils/__init__.py +1 -1
  93. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/utils/data_process.py +10 -6
  94. neurostats_api-1.0.0/neurostats_API/utils/exception.py +11 -0
  95. neurostats_api-1.0.0/neurostats_API/utils/logger.py +21 -0
  96. neurostats_api-1.0.0/neurostats_API.egg-info/PKG-INFO +102 -0
  97. neurostats_api-1.0.0/neurostats_API.egg-info/SOURCES.txt +128 -0
  98. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API.egg-info/requires.txt +1 -1
  99. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/setup.py +3 -3
  100. neurostats_api-1.0.0/test/test_async_fetcher.py +245 -0
  101. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/test/test_fetchers.py +8 -8
  102. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/test/test_tej.py +0 -1
  103. neurostats_api-0.0.25/MANIFEST.in +0 -9
  104. neurostats_api-0.0.25/PKG-INFO +0 -858
  105. neurostats_api-0.0.25/README.md +0 -841
  106. neurostats_api-0.0.25/neurostats_API/__init__.py +0 -15
  107. neurostats_api-0.0.25/neurostats_API/utils/exception.py +0 -3
  108. neurostats_api-0.0.25/neurostats_API.egg-info/PKG-INFO +0 -858
  109. neurostats_api-0.0.25/neurostats_API.egg-info/SOURCES.txt +0 -42
  110. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/cli.py +0 -0
  111. {neurostats_api-0.0.25/neurostats_API/tools → neurostats_api-1.0.0/neurostats_API/config}/company_list/tw.json +0 -0
  112. {neurostats_api-0.0.25/neurostats_API/tools → neurostats_api-1.0.0/neurostats_API/config}/company_list/us_TradingView_list.json +0 -0
  113. {neurostats_api-0.0.25/neurostats_API/tools → neurostats_api-1.0.0/neurostats_API/config}/tej_db/tej_db_index.yaml +0 -0
  114. {neurostats_api-0.0.25/neurostats_API/tools → neurostats_api-1.0.0/neurostats_API/config}/tej_db/tej_db_percent_index.yaml +0 -0
  115. {neurostats_api-0.0.25/neurostats_API/tools → neurostats_api-1.0.0/neurostats_API/config}/tej_db/tej_db_thousand_index.yaml +0 -0
  116. {neurostats_api-0.0.25/neurostats_API/tools → neurostats_api-1.0.0/neurostats_API/config}/twse/balance_sheet.yaml +0 -0
  117. {neurostats_api-0.0.25/neurostats_API/tools → neurostats_api-1.0.0/neurostats_API/config}/twse/cash_flow_percentage.yaml +0 -0
  118. {neurostats_api-0.0.25/neurostats_API/tools → neurostats_api-1.0.0/neurostats_API/config}/twse/finance_overview_dict.yaml +0 -0
  119. {neurostats_api-0.0.25/neurostats_API/tools → neurostats_api-1.0.0/neurostats_API/config}/twse/seasonal_data_field_dict.txt +0 -0
  120. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/fetchers/__init__.py +0 -0
  121. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/fetchers/balance_sheet.py +0 -0
  122. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/fetchers/base.py +0 -0
  123. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/fetchers/cash_flow.py +0 -0
  124. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/fetchers/institution.py +0 -0
  125. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/fetchers/margin_trading.py +0 -0
  126. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/fetchers/month_revenue.py +0 -0
  127. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/fetchers/profit_lose.py +0 -0
  128. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/fetchers/tech.py +0 -0
  129. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/fetchers/tej_finance_report.py +0 -0
  130. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/fetchers/value_invest.py +0 -0
  131. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/main.py +0 -0
  132. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/utils/calculate_value.py +0 -0
  133. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/utils/datetime.py +0 -0
  134. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API/utils/db_client.py +0 -0
  135. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API.egg-info/dependency_links.txt +0 -0
  136. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/neurostats_API.egg-info/top_level.txt +0 -0
  137. {neurostats_api-0.0.25 → neurostats_api-1.0.0}/setup.cfg +0 -0
@@ -0,0 +1,9 @@
1
+ recursive-include neurostats_api/config/tej_db *.yaml
2
+ recursive-include neurostats_api/config/tej_db *.txt
3
+ recursive-include neurostats_api/config/tej_db *.json
4
+ recursive-include neurostats_api/config/twse *.yaml
5
+ recursive-include neurostats_api/config/twse *.txt
6
+ recursive-include neurostats_api/config/twse *.json
7
+ recursive-include neurostats_api/config/company_list *.yaml
8
+ recursive-include neurostats_api/config/company_list *.txt
9
+ recursive-include neurostats_api/config/company_list *.json
@@ -0,0 +1,102 @@
1
+ Metadata-Version: 2.1
2
+ Name: neurostats_API
3
+ Version: 1.0.0
4
+ Summary: The service of NeuroStats website
5
+ Home-page: https://github.com/NeurowattStats/NeuroStats_API.git
6
+ Author: JasonWang@Neurowatt
7
+ Author-email: jason@neurowatt.ai
8
+ Requires-Python: >=3.6
9
+ Description-Content-Type: text/markdown
10
+ Requires-Dist: numpy
11
+ Requires-Dist: pandas
12
+ Requires-Dist: pymongo
13
+ Requires-Dist: pytz
14
+ Requires-Dist: python-dotenv
15
+ Requires-Dist: yfinance
16
+ Requires-Dist: holidays==0.70
17
+
18
+ # neurostats_API
19
+
20
+ - [檔案架構](#檔案架構)
21
+ - [下載](#下載)
22
+ - [使用方法](#使用方法)
23
+
24
+ ## 檔案架構
25
+
26
+ ```
27
+ ./neurostats_API
28
+ ├── async_mode
29
+ │ ├── db
30
+ │ ├── db_extractors
31
+ │ │ ├── daily
32
+ │ │ ├── month_revenue
33
+ │ │ └── seasonal
34
+ │ ├── factory
35
+ │ └── fetchers
36
+ ├── config
37
+ │ ├── company_list
38
+ │ ├── tej_db
39
+ │ └── twse
40
+ ├── fetchers
41
+ ├── transformers
42
+ │ ├── balance_sheet
43
+ │ ├── cash_flow
44
+ │ ├── daily_chip
45
+ │ │ └── utils
46
+ │ ├── daily_tech
47
+ │ │ └── utils
48
+ │ ├── finance_overview
49
+ │ ├── month_revenue
50
+ │ ├── profit_lose
51
+ │ ├── tej
52
+ │ └── value
53
+ └── utils
54
+ ```
55
+ - `neurostats_API`: 主要的package運行內容
56
+ - `async_mode`: \[新版新增\]以非同步方式進行DB資料的取得以及回傳資料
57
+ - `/db`: 連接到伺服器下的特定db
58
+ - `/db_extractor`: 決定取得db下的哪個collection的檔案,以及取得檔案內容
59
+ ` `/factory`: 使extractor的初始化變得通用
60
+ - `/fetchers`: 開發者將此套件用於其他專案的接口
61
+ - `fetchers`: (舊版)回傳service內容的fetcher檔案夾
62
+ - `transformers`: \[新版新增\] 處理從DB取出的資料,以dictionary的方式回傳需要的資料
63
+ - `config`: 【新舊通用】存放各種設定檔的dictionary,例如公司名單、各項指標對應的計算欄位、每個項目屬於哪份財報等設定
64
+ - `utils`: 【新舊通用】class之間通用的函式,例如讀取檔案、計算成長率函式、轉換格式與進位等
65
+
66
+ ## 下載
67
+ ```
68
+ pip install neurostats-API
69
+ ```
70
+ ### 確認下載成功
71
+ ```Python
72
+ >>> import neurostats_API
73
+ >>> print(neurostats_API.__version__)
74
+ 1.0.0
75
+ ```
76
+
77
+ ### 下載舊版
78
+ ```
79
+ pip install neurostats-API==0.0.25
80
+ ```
81
+
82
+ ## 使用方式 (以Balance_Sheet為例)
83
+ ### Async Mode
84
+ ```
85
+ from neurostats_API.async_mode.fetchers import AsyncBalanceSheetFetcher
86
+ from pymongo import AsyncMongoClient
87
+
88
+ db_client = AsyncMongoClient("<伺服器的MONGO_URI>")
89
+ ticker = "2330"
90
+
91
+ fetcher = AsyncBalanceSheetFetcher(ticker, db_client)
92
+
93
+ data = await fetcher.query_data()
94
+
95
+ print(data)
96
+ ```
97
+ 詳細各個fetcher的使用法請到[async_mode的fetchers資料夾下觀看](./neurostats_API/async_mode/fetchers/README.md)
98
+
99
+ ### Sync Mode
100
+ (#TODO)
101
+
102
+ > 舊版使用方法請到[fetchers資料夾下觀看](./neurostats_API/fetchers/README.md)
@@ -0,0 +1,85 @@
1
+ # neurostats_API
2
+
3
+ - [檔案架構](#檔案架構)
4
+ - [下載](#下載)
5
+ - [使用方法](#使用方法)
6
+
7
+ ## 檔案架構
8
+
9
+ ```
10
+ ./neurostats_API
11
+ ├── async_mode
12
+ │ ├── db
13
+ │ ├── db_extractors
14
+ │ │ ├── daily
15
+ │ │ ├── month_revenue
16
+ │ │ └── seasonal
17
+ │ ├── factory
18
+ │ └── fetchers
19
+ ├── config
20
+ │ ├── company_list
21
+ │ ├── tej_db
22
+ │ └── twse
23
+ ├── fetchers
24
+ ├── transformers
25
+ │ ├── balance_sheet
26
+ │ ├── cash_flow
27
+ │ ├── daily_chip
28
+ │ │ └── utils
29
+ │ ├── daily_tech
30
+ │ │ └── utils
31
+ │ ├── finance_overview
32
+ │ ├── month_revenue
33
+ │ ├── profit_lose
34
+ │ ├── tej
35
+ │ └── value
36
+ └── utils
37
+ ```
38
+ - `neurostats_API`: 主要的package運行內容
39
+ - `async_mode`: \[新版新增\]以非同步方式進行DB資料的取得以及回傳資料
40
+ - `/db`: 連接到伺服器下的特定db
41
+ - `/db_extractor`: 決定取得db下的哪個collection的檔案,以及取得檔案內容
42
+ ` `/factory`: 使extractor的初始化變得通用
43
+ - `/fetchers`: 開發者將此套件用於其他專案的接口
44
+ - `fetchers`: (舊版)回傳service內容的fetcher檔案夾
45
+ - `transformers`: \[新版新增\] 處理從DB取出的資料,以dictionary的方式回傳需要的資料
46
+ - `config`: 【新舊通用】存放各種設定檔的dictionary,例如公司名單、各項指標對應的計算欄位、每個項目屬於哪份財報等設定
47
+ - `utils`: 【新舊通用】class之間通用的函式,例如讀取檔案、計算成長率函式、轉換格式與進位等
48
+
49
+ ## 下載
50
+ ```
51
+ pip install neurostats-API
52
+ ```
53
+ ### 確認下載成功
54
+ ```Python
55
+ >>> import neurostats_API
56
+ >>> print(neurostats_API.__version__)
57
+ 1.0.0
58
+ ```
59
+
60
+ ### 下載舊版
61
+ ```
62
+ pip install neurostats-API==0.0.25
63
+ ```
64
+
65
+ ## 使用方式 (以Balance_Sheet為例)
66
+ ### Async Mode
67
+ ```
68
+ from neurostats_API.async_mode.fetchers import AsyncBalanceSheetFetcher
69
+ from pymongo import AsyncMongoClient
70
+
71
+ db_client = AsyncMongoClient("<伺服器的MONGO_URI>")
72
+ ticker = "2330"
73
+
74
+ fetcher = AsyncBalanceSheetFetcher(ticker, db_client)
75
+
76
+ data = await fetcher.query_data()
77
+
78
+ print(data)
79
+ ```
80
+ 詳細各個fetcher的使用法請到[async_mode的fetchers資料夾下觀看](./neurostats_API/async_mode/fetchers/README.md)
81
+
82
+ ### Sync Mode
83
+ (#TODO)
84
+
85
+ > 舊版使用方法請到[fetchers資料夾下觀看](./neurostats_API/fetchers/README.md)
@@ -0,0 +1,29 @@
1
+ __version__='1.0.0'
2
+
3
+ from .fetchers import (
4
+ AgentFinanceOverviewFetcher,
5
+ BalanceSheetFetcher,
6
+ CashFlowFetcher,
7
+ FinanceOverviewFetcher,
8
+ FinanceReportFetcher,
9
+ InstitutionFetcher,
10
+ MarginTradingFetcher,
11
+ MonthRevenueFetcher,
12
+ TechFetcher,
13
+ TEJStockPriceFetcher,
14
+ ProfitLoseFetcher,
15
+ )
16
+
17
+ from .async_mode import (
18
+ AsyncAgentOverviewFetcher,
19
+ AsyncBalanceSheetFetcher,
20
+ AsyncCashFlowFetcher,
21
+ AsyncFinanceOverviewFetcher,
22
+ AsyncMonthlyRevenueFetcher,
23
+ AsyncProfitLoseFetcher,
24
+ AsyncTechFetcher,
25
+ AsyncTEJSeasonalFetcher,
26
+ AsyncTWSEInstitutionFetcher,
27
+ AsyncTWSEMarginFetcher,
28
+ AsyncTWSEStatsValueFetcher
29
+ )
@@ -0,0 +1,13 @@
1
+ from .fetchers import (
2
+ AsyncAgentOverviewFetcher,
3
+ AsyncBalanceSheetFetcher,
4
+ AsyncCashFlowFetcher,
5
+ AsyncFinanceOverviewFetcher,
6
+ AsyncMonthlyRevenueFetcher,
7
+ AsyncProfitLoseFetcher,
8
+ AsyncTechFetcher,
9
+ AsyncTEJSeasonalFetcher,
10
+ AsyncTWSEInstitutionFetcher,
11
+ AsyncTWSEMarginFetcher,
12
+ AsyncTWSEStatsValueFetcher
13
+ )
@@ -0,0 +1,3 @@
1
+ from .twse import TWSEDBClient
2
+ from .tej import TEJDBClient
3
+ from .us import USDBClient
@@ -0,0 +1,24 @@
1
+ from pymongo import AsyncMongoClient
2
+
3
+ class BaseDBClient:
4
+ def __init__(self, client: AsyncMongoClient, zone= None):
5
+ self.client = client
6
+ self.zone = zone or "tw" # 預設台灣
7
+ self.db = self._select_db()
8
+
9
+ def _select_db(self):
10
+ """
11
+ 根據 zone 選擇對應的資料庫
12
+ """
13
+ zone_db_map = {
14
+ "tw": "company_test",
15
+ "us": "company_us"
16
+ }
17
+ db_name = zone_db_map.get(self.zone, "company_test")
18
+ return self.client[db_name]
19
+
20
+ def get_collection(self, collection_name: str):
21
+ """
22
+ 傳回指定 collection
23
+ """
24
+ return self.db[collection_name]
@@ -0,0 +1,10 @@
1
+ from .base import BaseDBClient
2
+ import os
3
+ from pymongo import AsyncMongoClient
4
+ from dotenv import load_dotenv
5
+
6
+ class TEJDBClient(BaseDBClient):
7
+ def __init__(self, mongo_uri):
8
+ """初始化時接收 MongoDB 連接 URI"""
9
+ super().__init__(mongo_uri, zone = 'tw')
10
+ self.db = self.client["company_test"]
@@ -0,0 +1,8 @@
1
+ from .base import BaseDBClient
2
+ import os
3
+ from pymongo import AsyncMongoClient
4
+ from dotenv import load_dotenv
5
+
6
+ class TWSEDBClient(BaseDBClient):
7
+ def __init__(self, client):
8
+ super().__init__(client, zone= "tw")
@@ -0,0 +1,9 @@
1
+ from .base import BaseDBClient
2
+ import os
3
+ from pymongo import AsyncMongoClient
4
+ from dotenv import load_dotenv
5
+
6
+ class USDBClient(BaseDBClient):
7
+ def __init__(self, client):
8
+ """初始化時接收 MongoDB 連接 URI"""
9
+ super().__init__(client, zone = 'us')
@@ -0,0 +1,20 @@
1
+ from .daily import (
2
+ AsyncTEJDailyTechDBExtractor,
3
+ AsyncYFDailyTechDBExtractor,
4
+ AsyncDailyValueDBExtractor,
5
+ AsyncTEJDailyValueDBExtractor,
6
+ AsyncTWSEChipDBExtractor,
7
+
8
+ )
9
+
10
+ from .month_revenue import (
11
+ AsyncTWSEMonthlyRevenueExtractor
12
+ )
13
+
14
+ from .seasonal import (
15
+ AsyncBalanceSheetExtractor,
16
+ AsyncProfitLoseExtractor,
17
+ AsyncCashFlowExtractor,
18
+ AsyncTEJFinanceStatementDBExtractor,
19
+ AsyncTEJSelfSettlementDBExtractor
20
+ )
@@ -0,0 +1,66 @@
1
+ import abc
2
+ from datetime import datetime
3
+ from ..db import TWSEDBClient, USDBClient
4
+ import json
5
+ import pytz
6
+ from neurostats_API.utils import StatsDateTime, StatsProcessor, YoY_Calculator, NoCompanyError
7
+
8
+ class BaseDBExtractor(abc.ABC):
9
+ def __init__(self, ticker, client):
10
+ self.ticker = ticker
11
+ self.client = client
12
+ self.timezone = pytz.timezone("Asia/Taipei")
13
+ self.tw_company_list = StatsProcessor.load_json("company_list/tw.json")
14
+ self.us_company_list = StatsProcessor.load_json("company_list/us.json")
15
+
16
+ self.company_name, self.zone = self._set_company_name(self.ticker)
17
+
18
+ self.db_client = self._set_db_connection()
19
+
20
+ def _set_company_name(self, ticker):
21
+ company_lists = [
22
+ (self.tw_company_list, 'tw'),
23
+ (self.us_company_list, 'us')
24
+ ]
25
+
26
+ for company_list, zone in company_lists:
27
+ company_name = company_list.get(ticker, None)
28
+ if (company_name):
29
+ return company_name, zone
30
+ # 沒找到公司名稱
31
+ raise NoCompanyError(f"Ticker-{ticker} not found in any company lists")
32
+
33
+ def _set_db_connection(self):
34
+ db_map = {
35
+ 'tw': TWSEDBClient,
36
+ 'us': USDBClient
37
+ }
38
+ db_client = db_map.get(self.zone, TWSEDBClient)
39
+ return db_client(self.client)
40
+
41
+
42
+
43
+ async def query_data(self):
44
+ """
45
+ user使用的接口
46
+ """
47
+ return NotImplementedError()
48
+
49
+ @abc.abstractmethod
50
+ def _prepare_query(self):
51
+ pass
52
+
53
+ def get_company_name(self):
54
+ """
55
+ 回傳公司
56
+ """
57
+ return self.company_name
58
+
59
+ def get_zone(self):
60
+ """
61
+ 公司區域(TW, US)
62
+ """
63
+ return self.zone
64
+
65
+ def _get_today(self):
66
+ return datetime.today()
@@ -0,0 +1,7 @@
1
+ from .tej_tech import AsyncTEJDailyTechDBExtractor
2
+ from .twse_chip import AsyncTWSEChipDBExtractor
3
+ from .value import (
4
+ AsyncDailyValueDBExtractor,
5
+ AsyncTEJDailyValueDBExtractor
6
+ )
7
+ from .yf import AsyncYFDailyTechDBExtractor
@@ -0,0 +1,89 @@
1
+ from ..base import BaseDBExtractor
2
+ from datetime import datetime
3
+ from neurostats_API.utils import NotSupportedError
4
+ from pymongo import ASCENDING, DESCENDING
5
+
6
+
7
+ class BaseDailyTechDBExtractor(BaseDBExtractor):
8
+
9
+ def __init__(self, ticker, client):
10
+ super().__init__(ticker, client)
11
+
12
+ self.collection_name_map = None
13
+ self.collection_name = self._get_collection_name()
14
+
15
+ if (self.collection_name is None):
16
+ raise NotSupportedError(
17
+ f"{self.__class__.__name__} only supports {list(self.collection_name_map.keys())}, got {self.zone} with ticker = \"{self.ticker}\""
18
+ )
19
+
20
+ self.collection = self.db_client.get_collection(self.collection_name)
21
+
22
+ async def query_data(self, start_date=None, end_date=None, get_latest = False):
23
+ if (self.collection is None):
24
+ return []
25
+
26
+ if (start_date is None):
27
+ start_date = "1991-01-01"
28
+ if (end_date is None):
29
+ end_date = self._get_today()
30
+
31
+ query, projection, sort = self._prepare_query(
32
+ start_date=start_date, end_date=end_date, get_latest=get_latest
33
+ )
34
+
35
+ if (get_latest):
36
+ cursor = self.collection.find(query, projection).sort(sort).limit(1)
37
+ else:
38
+ cursor = self.collection.find(query, projection).sort(sort)
39
+
40
+ fetched_data = [data async for data in cursor]
41
+
42
+ return fetched_data
43
+
44
+ def _get_collection_name(self):
45
+ self.collection_name_map = {"tw": "twse_daily_share_price", "us": "us_technical"}
46
+ collection_name = self.collection_name_map.get(self.zone, None)
47
+
48
+ return collection_name
49
+
50
+ def _prepare_query(self, start_date=None, end_date=None, get_latest = False):
51
+ query = {"ticker": self.ticker}
52
+
53
+ query = self._update_query_with_date(query, start_date, end_date)
54
+
55
+ projection = {
56
+ "_id": 0,
57
+ }
58
+
59
+ if (get_latest):
60
+ sort = [("date", DESCENDING)]
61
+ else:
62
+ sort = [("date", ASCENDING)]
63
+
64
+ return query, projection, sort
65
+
66
+ def _update_query_with_date(self, query, start_date, end_date):
67
+ start_date = self._transform_date(start_date)
68
+ end_date = self._transform_date(end_date)
69
+
70
+ date_range = {"$gte": start_date, "$lte": end_date}
71
+
72
+ query.update({"date": date_range})
73
+
74
+ return query
75
+
76
+ def _transform_date(self, date):
77
+ if (isinstance(date, str)):
78
+ try:
79
+ return datetime.strptime(date, "%Y-%m-%d")
80
+ except Exception as e:
81
+ raise ValueError(
82
+ "date string format imcompatible, should be \"YYYY-MM-DD\""
83
+ )
84
+ elif (isinstance(date, datetime)):
85
+ return date
86
+ else:
87
+ raise ValueError(
88
+ "date type imcompatible, should be string(\"YYYY-MM-DD\") or datetime.datetime"
89
+ )
@@ -0,0 +1,14 @@
1
+ from .base import BaseDailyTechDBExtractor
2
+ from datetime import datetime
3
+ from pymongo import ASCENDING, DESCENDING
4
+
5
+
6
+ class AsyncTEJDailyChipDBExtractor(BaseDailyTechDBExtractor):
7
+
8
+ def __init__(self, ticker, client):
9
+ super().__init__(ticker, client)
10
+
11
+ def _get_collection_name(self):
12
+ self.collection_name_map = {"tw": "TEJ_chip"}
13
+
14
+ return self.collection_name_map.get(self.zone, None)
@@ -0,0 +1,12 @@
1
+ from .base import BaseDailyTechDBExtractor
2
+
3
+
4
+ class AsyncTEJDailyTechDBExtractor(BaseDailyTechDBExtractor):
5
+
6
+ def __init__(self, ticker, client):
7
+ super().__init__(ticker, client)
8
+
9
+ def _get_collection_name(self):
10
+ self.collection_name_map = {"tw": "TEJ_share_price"}
11
+
12
+ return self.collection_name_map.get(self.zone, None)
@@ -0,0 +1,49 @@
1
+ from .base import BaseDailyTechDBExtractor
2
+ from datetime import datetime
3
+ from pymongo import ASCENDING, DESCENDING
4
+ from neurostats_API.utils import NotSupportedError
5
+
6
+ class AsyncTWSEChipDBExtractor(BaseDailyTechDBExtractor):
7
+
8
+ def __init__(self, ticker, client, fetch_type = 'I'):
9
+
10
+ """
11
+ 擷取台股每日籌碼資料。
12
+
13
+ fetch_type:
14
+ - 'I' (INSTITUTION): 法人買賣
15
+ - 'M' (MARGIN): 融資融券餘額變化
16
+ - 'S' (SECURITY_LENDING): 借券債券
17
+
18
+ """
19
+ super().__init__(ticker, client)
20
+
21
+ column_name_map = {
22
+ 'tw': {
23
+ "I" : "institution_trading",
24
+ "M" : "margin_trading",
25
+ "S" : "security_lending"
26
+ },
27
+ }
28
+ self.target_column = column_name_map[self.zone][fetch_type]
29
+
30
+ def _get_collection_name(self):
31
+ self.collection_name_map = {"tw": "twse_chip"}
32
+ collection_name = self.collection_name_map.get(self.zone, None)
33
+ return collection_name
34
+
35
+ def _prepare_query(self, start_date=None, end_date=None, get_latest = False):
36
+ query, projection, sort = super()._prepare_query(start_date, end_date, get_latest)
37
+ query.update(
38
+ {
39
+ self.target_column: {"$exists" : True}
40
+ }
41
+ )
42
+ projection.update(
43
+ {
44
+ 'date': 1,
45
+ self.target_column: 1
46
+ }
47
+ )
48
+
49
+ return query, projection, sort
@@ -0,0 +1,93 @@
1
+ from .base import BaseDailyTechDBExtractor
2
+ from pymongo import ASCENDING, DESCENDING
3
+ from neurostats_API.utils import NotSupportedError
4
+
5
+ class AsyncDailyValueDBExtractor(BaseDailyTechDBExtractor):
6
+
7
+ def __init__(self, ticker, client, fetch_type='D'):
8
+ """
9
+ fetch_type:
10
+ 'D': daily
11
+ 'Y': yearly
12
+ """
13
+ self.fetch_type = fetch_type
14
+ super().__init__(ticker, client)
15
+
16
+ def _get_collection_name(self):
17
+ self.collection_name_map = {
18
+ "tw": {
19
+ "D":"twse_daily_share_price",
20
+ "Y": "twse_yearly_value"
21
+ }
22
+ }
23
+ collection_map = self.collection_name_map.get(self.zone)
24
+ if (collection_map is None):
25
+ raise NotSupportedError(f"AsyncDailyValueDBExtractor only supports {self.collection_name_map.keys}, but get {self.zone}")
26
+ collection_name = collection_map.get(self.fetch_type)
27
+ if (collection_name is None):
28
+ raise ValueError(f"AsyncDailyValueDBExtractor: Invalid fetch type : {self.fetch_type}")
29
+ return collection_name
30
+
31
+ def _prepare_query(self, start_date = None, end_date = None, get_latest = False):
32
+ query_fn_map = {
33
+ 'D': super()._prepare_query,
34
+ 'Y': self._prepare_annual_query
35
+ }
36
+
37
+ query_fn = query_fn_map.get(self.fetch_type)
38
+ query, projection, sorting = query_fn(start_date=start_date, end_date=end_date, get_latest=get_latest)
39
+
40
+ projection.update(
41
+ {
42
+ "date": 1,
43
+ "year": 1,
44
+ "close": 1,
45
+ "P_E": 1,
46
+ "P_B": 1,
47
+ "P_FCF": 1,
48
+ "P_S": 1,
49
+ "EV_S": 1,
50
+ "EV_OPI": 1,
51
+ "EV_EBIT": 1,
52
+ "EV_EBITDA": 1
53
+ }
54
+ )
55
+
56
+ return query, projection, sorting
57
+
58
+
59
+ def _prepare_annual_query(self, start_date, end_date, get_latest = False):
60
+ start_date = self._transform_date(start_date)
61
+ end_date = self._transform_date(end_date)
62
+
63
+ start_year = start_date.year - 1911
64
+ end_year = end_date.year - 1911
65
+ query = {
66
+ "ticker": self.ticker,
67
+ "year": {
68
+ "$gte": start_year,
69
+ "$lte": end_year
70
+ }
71
+ }
72
+
73
+ projection = {
74
+ "_id": 0,
75
+ }
76
+
77
+ if (get_latest):
78
+ sort = [("year", DESCENDING)]
79
+ else:
80
+ sort = [("year", ASCENDING)]
81
+
82
+ return query, projection, sort
83
+
84
+
85
+ class AsyncTEJDailyValueDBExtractor(BaseDailyTechDBExtractor):
86
+
87
+ def __init__(self, ticker, mongo_uri):
88
+ super().__init__(ticker, mongo_uri)
89
+
90
+ def _get_collection_name(self):
91
+ self.collection_name_map = {"tw": "TEJ_share_price"}
92
+
93
+ return self.collection_name_map.get(self.zone, None)
@@ -0,0 +1,12 @@
1
+ from .base import BaseDailyTechDBExtractor
2
+
3
+
4
+ class AsyncYFDailyTechDBExtractor(BaseDailyTechDBExtractor):
5
+
6
+ def __init__(self, ticker, client):
7
+ super().__init__(ticker, client)
8
+
9
+ def _get_collection_name(self):
10
+ self.collection_name_map = {"tw": "twse_daily_share_price", "us": "us_technical"}
11
+
12
+ return self.collection_name_map.get(self.zone, None)
@@ -0,0 +1 @@
1
+ from .twse import AsyncTWSEMonthlyRevenueExtractor