FinMind 2.0.5__tar.gz → 2.0.7__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 (60) hide show
  1. {finmind-2.0.5 → finmind-2.0.7}/FinMind/data/data_loader.py +182 -0
  2. {finmind-2.0.5 → finmind-2.0.7}/FinMind/schema/data.py +7 -0
  3. finmind-2.0.7/FinMind/strategies/utils.py +72 -0
  4. {finmind-2.0.5/finmind.egg-info → finmind-2.0.7}/PKG-INFO +1 -1
  5. {finmind-2.0.5 → finmind-2.0.7/finmind.egg-info}/PKG-INFO +1 -1
  6. finmind-2.0.5/FinMind/strategies/utils.py +0 -50
  7. {finmind-2.0.5 → finmind-2.0.7}/FinMind/__init__.py +0 -0
  8. {finmind-2.0.5 → finmind-2.0.7}/FinMind/_version.py +0 -0
  9. {finmind-2.0.5 → finmind-2.0.7}/FinMind/crawler/__init__.py +0 -0
  10. {finmind-2.0.5 → finmind-2.0.7}/FinMind/crawler/base.py +0 -0
  11. {finmind-2.0.5 → finmind-2.0.7}/FinMind/crawler/commodities.py +0 -0
  12. {finmind-2.0.5 → finmind-2.0.7}/FinMind/crawler/demo.py +0 -0
  13. {finmind-2.0.5 → finmind-2.0.7}/FinMind/crawler/government_bonds.py +0 -0
  14. {finmind-2.0.5 → finmind-2.0.7}/FinMind/data/__init__.py +0 -0
  15. {finmind-2.0.5 → finmind-2.0.7}/FinMind/data/data_subscriber.py +0 -0
  16. {finmind-2.0.5 → finmind-2.0.7}/FinMind/data/finmind_api.py +0 -0
  17. {finmind-2.0.5 → finmind-2.0.7}/FinMind/indicators/__init__.py +0 -0
  18. {finmind-2.0.5 → finmind-2.0.7}/FinMind/indicators/bias.py +0 -0
  19. {finmind-2.0.5 → finmind-2.0.7}/FinMind/indicators/continue_holding.py +0 -0
  20. {finmind-2.0.5 → finmind-2.0.7}/FinMind/indicators/institutional_investors_follower.py +0 -0
  21. {finmind-2.0.5 → finmind-2.0.7}/FinMind/indicators/institutional_investors_over_buy.py +0 -0
  22. {finmind-2.0.5 → finmind-2.0.7}/FinMind/indicators/kd.py +0 -0
  23. {finmind-2.0.5 → finmind-2.0.7}/FinMind/indicators/kd_crossover.py +0 -0
  24. {finmind-2.0.5 → finmind-2.0.7}/FinMind/indicators/ma_cross_orver.py +0 -0
  25. {finmind-2.0.5 → finmind-2.0.7}/FinMind/indicators/short_sale_margin_purchase_ratio.py +0 -0
  26. {finmind-2.0.5 → finmind-2.0.7}/FinMind/plotting/__init__.py +0 -0
  27. {finmind-2.0.5 → finmind-2.0.7}/FinMind/plotting/bar.py +0 -0
  28. {finmind-2.0.5 → finmind-2.0.7}/FinMind/plotting/kline.py +0 -0
  29. {finmind-2.0.5 → finmind-2.0.7}/FinMind/plotting/line.py +0 -0
  30. {finmind-2.0.5 → finmind-2.0.7}/FinMind/plotting/pie.py +0 -0
  31. {finmind-2.0.5 → finmind-2.0.7}/FinMind/schema/__init__.py +0 -0
  32. {finmind-2.0.5 → finmind-2.0.7}/FinMind/schema/indicators.py +0 -0
  33. {finmind-2.0.5 → finmind-2.0.7}/FinMind/schema/info.py +0 -0
  34. {finmind-2.0.5 → finmind-2.0.7}/FinMind/schema/plot.py +0 -0
  35. {finmind-2.0.5 → finmind-2.0.7}/FinMind/schema/rule.py +0 -0
  36. {finmind-2.0.5 → finmind-2.0.7}/FinMind/strategies/__init__.py +0 -0
  37. {finmind-2.0.5 → finmind-2.0.7}/FinMind/strategies/base.py +0 -0
  38. {finmind-2.0.5 → finmind-2.0.7}/FinMind/strategies/bias.py +0 -0
  39. {finmind-2.0.5 → finmind-2.0.7}/FinMind/strategies/continue_holding.py +0 -0
  40. {finmind-2.0.5 → finmind-2.0.7}/FinMind/strategies/institutional_investors_follower.py +0 -0
  41. {finmind-2.0.5 → finmind-2.0.7}/FinMind/strategies/kd.py +0 -0
  42. {finmind-2.0.5 → finmind-2.0.7}/FinMind/strategies/kd_crossover.py +0 -0
  43. {finmind-2.0.5 → finmind-2.0.7}/FinMind/strategies/ma_crossover.py +0 -0
  44. {finmind-2.0.5 → finmind-2.0.7}/FinMind/strategies/macd_crossover.py +0 -0
  45. {finmind-2.0.5 → finmind-2.0.7}/FinMind/strategies/max_min_period_bias.py +0 -0
  46. {finmind-2.0.5 → finmind-2.0.7}/FinMind/strategies/naive_kd.py +0 -0
  47. {finmind-2.0.5 → finmind-2.0.7}/FinMind/strategies/short_sale_margin_purchase_ratio.py +0 -0
  48. {finmind-2.0.5 → finmind-2.0.7}/FinMind/templates/post.html +0 -0
  49. {finmind-2.0.5 → finmind-2.0.7}/FinMind/utility/__init__.py +0 -0
  50. {finmind-2.0.5 → finmind-2.0.7}/FinMind/utility/request.py +0 -0
  51. {finmind-2.0.5 → finmind-2.0.7}/FinMind/utility/rule.py +0 -0
  52. {finmind-2.0.5 → finmind-2.0.7}/LICENSE +0 -0
  53. {finmind-2.0.5 → finmind-2.0.7}/README.md +0 -0
  54. {finmind-2.0.5 → finmind-2.0.7}/finmind.egg-info/SOURCES.txt +0 -0
  55. {finmind-2.0.5 → finmind-2.0.7}/finmind.egg-info/dependency_links.txt +0 -0
  56. {finmind-2.0.5 → finmind-2.0.7}/finmind.egg-info/requires.txt +0 -0
  57. {finmind-2.0.5 → finmind-2.0.7}/finmind.egg-info/top_level.txt +0 -0
  58. {finmind-2.0.5 → finmind-2.0.7}/pyproject.toml +0 -0
  59. {finmind-2.0.5 → finmind-2.0.7}/setup.cfg +0 -0
  60. {finmind-2.0.5 → finmind-2.0.7}/setup.py +0 -0
@@ -2172,6 +2172,50 @@ class DataLoader(FinMindApi):
2172
2172
  )
2173
2173
  return tw_total_exchange_mMargin_maintenance
2174
2174
 
2175
+ def taiwan_stock_margin_maintenance(
2176
+ self,
2177
+ stock_id: str = "",
2178
+ start_date: str = "",
2179
+ end_date: str = "",
2180
+ timeout: int = None,
2181
+ use_async: bool = False,
2182
+ stock_id_list: typing.List[str] = None,
2183
+ ) -> pd.DataFrame:
2184
+ """get 個股融資維持率(Sponsor)
2185
+
2186
+ 個股融資維持率為估算指標:僅個股融資餘額張數為公開資訊,個股融資
2187
+ 金額並未公開,因此本資料集無官方真值可對照,與其他服務的估算結果
2188
+ 不會完全一致。融資成數以法定上限計(上市六成;上櫃 2014-11-10 起
2189
+ 六成、之前五成),警示股/處置股實際成數可能較低。融資成本線為
2190
+ 名目值,已調整股數事件(分割/面額變更/減資/配股)並扣除現金
2191
+ 股利。上市自 2001-01-05 起、上櫃自 2007-01-04 起。
2192
+
2193
+ :param stock_id (str): 股票代號("2330")
2194
+ :param start_date (str): 起始日期("2024-01-02")
2195
+ :param end_date (str): 結束日期("2024-01-31")
2196
+ :param timeout (int): timeout seconds, default None
2197
+
2198
+ :return: 個股融資維持率 TaiwanStockMarginMaintenance
2199
+ :rtype pd.DataFrame
2200
+ :rtype column date (str): 日期
2201
+ :rtype column stock_id (str): 股票代號
2202
+ :rtype column margin_balance (int): 融資餘額(張)
2203
+ :rtype column margin_cost (float): 融資成本線,
2204
+ 估算的融資部位移動加權平均成本
2205
+ :rtype column margin_ratio (float): 融資成數,實際採用值(0.6 / 0.5)
2206
+ :rtype column margin_maintenance (float): 融資維持率(%),例 156.1
2207
+ """
2208
+ stock_margin_maintenance = self.get_data(
2209
+ dataset=Dataset.TaiwanStockMarginMaintenance,
2210
+ data_id=stock_id,
2211
+ start_date=start_date,
2212
+ end_date=end_date,
2213
+ timeout=timeout,
2214
+ use_async=use_async,
2215
+ data_id_list=stock_id_list,
2216
+ )
2217
+ return stock_margin_maintenance
2218
+
2175
2219
  def us_stock_info(self, timeout: int = None) -> pd.DataFrame:
2176
2220
  """get 美國股票代碼總覽
2177
2221
  :param timeout (int): timeout seconds, default None
@@ -2755,6 +2799,38 @@ class DataLoader(FinMindApi):
2755
2799
  )
2756
2800
  return stock_industry_chain
2757
2801
 
2802
+ def taiwan_stock_industry_chain_money_flow(
2803
+ self,
2804
+ date: str = "",
2805
+ timeout: int = None,
2806
+ ) -> pd.DataFrame:
2807
+ """get 台股產業鏈資金流向(Sponsor)
2808
+
2809
+ 計算每日交易資金在各產業鏈的分佈:以個體公司所屬產業鏈
2810
+ (industry/sub_industry)彙總每日個股成交。sub_industry 為空字串的
2811
+ 列為該產業鏈總計(成分股不重複計算,不等於子產業列加總);一檔股票
2812
+ 可屬多條產業鏈,各產業鏈佔比加總會超過 100%。
2813
+
2814
+ :param date (str): 資料日期("2026-07-17");資料量大,一次提供一天
2815
+ :param timeout (int): timeout seconds, default None
2816
+
2817
+ :return: 台股產業鏈資金流向 TaiwanStockIndustryChainMoneyFlow
2818
+ :rtype pd.DataFrame
2819
+ :rtype column date (str): 日期
2820
+ :rtype column industry (str): 產業鏈
2821
+ :rtype column sub_industry (str): 子產業;空字串代表該產業鏈總計列
2822
+ :rtype column stock_count (int): 成分股數(當日有成交)
2823
+ :rtype column trading_volume (int): 成交股數合計
2824
+ :rtype column trading_money (int): 成交金額合計
2825
+ :rtype column trading_money_pct (float): 佔當日全市場個股成交金額比重(%)
2826
+ """
2827
+ industry_chain_money_flow = self.get_data(
2828
+ dataset=Dataset.TaiwanStockIndustryChainMoneyFlow,
2829
+ start_date=date,
2830
+ timeout=timeout,
2831
+ )
2832
+ return industry_chain_money_flow
2833
+
2758
2834
  def cnn_fear_greed_index(
2759
2835
  self,
2760
2836
  start_date: str = "",
@@ -3053,6 +3129,36 @@ class DataLoader(FinMindApi):
3053
3129
  )
3054
3130
  return taiwan_stock_convertible_bond_monthly_analysis
3055
3131
 
3132
+ def taiwan_stock_convertible_bond_put_provision(
3133
+ self,
3134
+ cb_id: str = "",
3135
+ start_date: str = "",
3136
+ end_date: str = "",
3137
+ timeout: int = None,
3138
+ ) -> pd.DataFrame:
3139
+ """get 可轉債賣回權時程(含未來已公告場次)
3140
+ :param cb_id (str): 可轉債代號("14773")
3141
+ :param start_date (str): 起始日期("2011-06-01")
3142
+ :param end_date (str): 結束日期("2011-06-30"),可設未來日期查詢即將到來的賣回場次
3143
+ :param timeout (int): timeout seconds, default None
3144
+
3145
+ :return: 可轉債賣回權時程 TaiwanStockConvertibleBondPutProvision
3146
+ :rtype pd.DataFrame
3147
+ :rtype column date (str): 賣回基準日
3148
+ :rtype column cb_id (str): 可轉債代號
3149
+ :rtype column cb_name (str): 可轉債名稱
3150
+ :rtype column PutPrice (float): 賣回金額
3151
+ :rtype column PutYieldRate (float): 賣回收益率
3152
+ """
3153
+ taiwan_stock_convertible_bond_put_provision = self.get_data(
3154
+ dataset=Dataset.TaiwanStockConvertibleBondPutProvision,
3155
+ data_id=cb_id,
3156
+ start_date=start_date,
3157
+ end_date=end_date,
3158
+ timeout=timeout,
3159
+ )
3160
+ return taiwan_stock_convertible_bond_put_provision
3161
+
3056
3162
  def taiwan_option_vix(
3057
3163
  self,
3058
3164
  start_date: str = "",
@@ -3079,6 +3185,82 @@ class DataLoader(FinMindApi):
3079
3185
  )
3080
3186
  return taiwan_option_vix
3081
3187
 
3188
+ def taiwan_asset_swap_fixed_income_daily(
3189
+ self,
3190
+ stock_id: str = "",
3191
+ start_date: str = "",
3192
+ end_date: str = "",
3193
+ timeout: int = None,
3194
+ use_async: bool = False,
3195
+ stock_id_list: typing.List[str] = None,
3196
+ ) -> pd.DataFrame:
3197
+ """get 資產交換固定收益日成交資訊
3198
+ :param stock_id: 股票代號("17172")
3199
+ :param start_date (str): 起始日期("2025-01-01")
3200
+ :param end_date (str): 結束日期("2025-12-31")
3201
+ :param timeout (int): timeout seconds, default None
3202
+
3203
+ :return: 資產交換固定收益日成交資訊 TaiwanAssetSwapFixedIncomeDaily
3204
+ :rtype pd.DataFrame
3205
+ :rtype column date (str): 日期
3206
+ :rtype column stock_id (str): 股票代碼
3207
+ :rtype column stock_name (str): 股票名稱
3208
+ :rtype column notional_amount (int): 名目本金
3209
+ :rtype column number_of_transactions (int): 成交筆數
3210
+ :rtype column rate_lowest (float): 最低利率
3211
+ :rtype column rate_highest (float): 最高利率
3212
+ :rtype column rate_average (float): 平均利率
3213
+ :rtype column contract_term_years (float): 合約期間(年)
3214
+ """
3215
+ data = self.get_data(
3216
+ dataset=Dataset.TaiwanAssetSwapFixedIncomeDaily,
3217
+ data_id=stock_id,
3218
+ start_date=start_date,
3219
+ end_date=end_date,
3220
+ timeout=timeout,
3221
+ use_async=use_async,
3222
+ data_id_list=stock_id_list,
3223
+ )
3224
+ return data
3225
+
3226
+ def taiwan_asset_swap_option_daily(
3227
+ self,
3228
+ stock_id: str = "",
3229
+ start_date: str = "",
3230
+ end_date: str = "",
3231
+ timeout: int = None,
3232
+ use_async: bool = False,
3233
+ stock_id_list: typing.List[str] = None,
3234
+ ) -> pd.DataFrame:
3235
+ """get 資產交換選擇權日成交資訊
3236
+ :param stock_id: 股票代號("17172")
3237
+ :param start_date (str): 起始日期("2025-01-01")
3238
+ :param end_date (str): 結束日期("2025-12-31")
3239
+ :param timeout (int): timeout seconds, default None
3240
+
3241
+ :return: 資產交換選擇權日成交資訊 TaiwanAssetSwapOptionDaily
3242
+ :rtype pd.DataFrame
3243
+ :rtype column date (str): 日期
3244
+ :rtype column stock_id (str): 股票代碼
3245
+ :rtype column stock_name (str): 股票名稱
3246
+ :rtype column notional_amount (int): 名目本金
3247
+ :rtype column number_of_transactions (int): 成交筆數
3248
+ :rtype column premium_lowest (float): 最低權利金
3249
+ :rtype column premium_highest (float): 最高權利金
3250
+ :rtype column premium_average (float): 平均權利金
3251
+ :rtype column contract_term_years (float): 合約期間(年)
3252
+ """
3253
+ data = self.get_data(
3254
+ dataset=Dataset.TaiwanAssetSwapOptionDaily,
3255
+ data_id=stock_id,
3256
+ start_date=start_date,
3257
+ end_date=end_date,
3258
+ timeout=timeout,
3259
+ use_async=use_async,
3260
+ data_id_list=stock_id_list,
3261
+ )
3262
+ return data
3263
+
3082
3264
  def _get_stock_id_list(
3083
3265
  self, date: str, timeout: int = None
3084
3266
  ) -> typing.List[str]:
@@ -124,6 +124,7 @@ class Dataset(str, Enum):
124
124
  "TaiwanStockDispositionSecuritiesPeriod"
125
125
  )
126
126
  TaiwanStockIndustryChain = "TaiwanStockIndustryChain"
127
+ TaiwanStockIndustryChainMoneyFlow = "TaiwanStockIndustryChainMoneyFlow"
127
128
  TaiwanStockTradingDate = "TaiwanStockTradingDate"
128
129
  TaiwanStockInfoWithWarrantSummary = "TaiwanStockInfoWithWarrantSummary"
129
130
  TaiwanStockSplitPrice = "TaiwanStockSplitPrice"
@@ -143,7 +144,13 @@ class Dataset(str, Enum):
143
144
  TaiwanStockConvertibleBondMonthlyAnalysis = (
144
145
  "TaiwanStockConvertibleBondMonthlyAnalysis"
145
146
  )
147
+ TaiwanStockConvertibleBondPutProvision = (
148
+ "TaiwanStockConvertibleBondPutProvision"
149
+ )
146
150
  TaiwanOptionVix = "TaiwanOptionVix"
151
+ TaiwanAssetSwapFixedIncomeDaily = "TaiwanAssetSwapFixedIncomeDaily"
152
+ TaiwanAssetSwapOptionDaily = "TaiwanAssetSwapOptionDaily"
153
+ TaiwanStockMarginMaintenance = "TaiwanStockMarginMaintenance"
147
154
 
148
155
 
149
156
  class Version(str, Enum):
@@ -0,0 +1,72 @@
1
+ import datetime
2
+
3
+ import numpy as np
4
+
5
+ from FinMind.data import DataLoader
6
+
7
+
8
+ # TaiwanStockInfo 對部分上市股票會回超過一列,industry_category 不只放產業別:
9
+ # 電子工業 / 化學生技醫療 是 TWSE 類股選單裡的「產業總稱」,各自是底下子類的
10
+ # 聯集(電子工業 = 半導體業~其他電子業、化學生技醫療 = 化學工業+生技醫療業),
11
+ # 所以 2330 會同時有「半導體業」和「電子工業」兩列
12
+ # 創新板股票 是板別不是產業,該檔在自己的產業別也還有一列
13
+ # 創新版股票 是舊資料的錯字(板 vs 版)
14
+ # 直接取第一列會因為回傳順序而不穩定,先把這些非產業別的值排掉。
15
+ NOT_INDUSTRY_CATEGORY = [
16
+ "電子工業",
17
+ "化學生技醫療",
18
+ "創新板股票",
19
+ "創新版股票",
20
+ ]
21
+
22
+
23
+ def get_asset_underlying_type(stock_id: str, data_loader: DataLoader) -> str:
24
+ taiwan_stock_info = data_loader.taiwan_stock_info()
25
+ industry_category = taiwan_stock_info[
26
+ taiwan_stock_info["stock_id"] == stock_id
27
+ ]["industry_category"]
28
+ real_industry_category = industry_category[
29
+ ~industry_category.isin(NOT_INDUSTRY_CATEGORY)
30
+ ]
31
+ # 全部都被排掉時(例如只收到總稱那列)就退回原本的值,寧可回總稱也不要回空
32
+ if len(real_industry_category) > 0:
33
+ industry_category = real_industry_category
34
+ # 排序後取第一個,確保同一檔股票每次都回一樣的結果
35
+ return sorted(industry_category.values)[0]
36
+
37
+
38
+ def get_underlying_trading_tax(underlying_type: str) -> float:
39
+ mapping = {"ETF": 0.001, "上櫃指數股票型基金(ETF)": 0.001}
40
+ return mapping.get(underlying_type, 0.003)
41
+
42
+
43
+ def calculate_datenbr(day1: str, day2: str) -> int:
44
+ assert day1 <= day2, "day2 必須大於等於 day1"
45
+
46
+ dis_day = datetime.datetime.strptime(
47
+ day2, "%Y-%m-%d"
48
+ ) - datetime.datetime.strptime(day1, "%Y-%m-%d")
49
+ return int(dis_day.days)
50
+
51
+
52
+ def calculate_sharp_ratio(strategy_return: float, std: float) -> float:
53
+ risk_free_rate = 0
54
+ return (
55
+ 0
56
+ if std == 0
57
+ else round(((strategy_return - risk_free_rate) / std) * np.sqrt(252), 2)
58
+ )
59
+
60
+
61
+ def period_return2annual_return(
62
+ period_return: float, period_years: float
63
+ ) -> float:
64
+ annual_return = round(
65
+ ((period_return + 1) ** (1 / period_years) - 1),
66
+ 4,
67
+ )
68
+ return annual_return
69
+
70
+
71
+ def days2years(days: int) -> float:
72
+ return days / 365
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: finmind
3
- Version: 2.0.5
3
+ Version: 2.0.7
4
4
  Summary: financial mining
5
5
  Author-email: linsam <finmind.tw@gmail.com>
6
6
  License: Apache License
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: finmind
3
- Version: 2.0.5
3
+ Version: 2.0.7
4
4
  Summary: financial mining
5
5
  Author-email: linsam <finmind.tw@gmail.com>
6
6
  License: Apache License
@@ -1,50 +0,0 @@
1
- import datetime
2
-
3
- import numpy as np
4
-
5
- from FinMind.data import DataLoader
6
-
7
-
8
- def get_asset_underlying_type(stock_id: str, data_loader: DataLoader) -> str:
9
- taiwan_stock_info = data_loader.taiwan_stock_info()
10
- underlying_type = taiwan_stock_info[
11
- taiwan_stock_info["stock_id"] == stock_id
12
- ]["industry_category"].values[0]
13
- return underlying_type
14
-
15
-
16
- def get_underlying_trading_tax(underlying_type: str) -> float:
17
- mapping = {"ETF": 0.001, "上櫃指數股票型基金(ETF)": 0.001}
18
- return mapping.get(underlying_type, 0.003)
19
-
20
-
21
- def calculate_datenbr(day1: str, day2: str) -> int:
22
- assert day1 <= day2, "day2 必須大於等於 day1"
23
-
24
- dis_day = datetime.datetime.strptime(
25
- day2, "%Y-%m-%d"
26
- ) - datetime.datetime.strptime(day1, "%Y-%m-%d")
27
- return int(dis_day.days)
28
-
29
-
30
- def calculate_sharp_ratio(strategy_return: float, std: float) -> float:
31
- risk_free_rate = 0
32
- return (
33
- 0
34
- if std == 0
35
- else round(((strategy_return - risk_free_rate) / std) * np.sqrt(252), 2)
36
- )
37
-
38
-
39
- def period_return2annual_return(
40
- period_return: float, period_years: float
41
- ) -> float:
42
- annual_return = round(
43
- ((period_return + 1) ** (1 / period_years) - 1),
44
- 4,
45
- )
46
- return annual_return
47
-
48
-
49
- def days2years(days: int) -> float:
50
- return days / 365
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes