akshare 1.12.99__py3-none-any.whl → 1.15.72__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.

Potentially problematic release.


This version of akshare might be problematic. Click here for more details.

Files changed (236) hide show
  1. akshare/__init__.py +441 -138
  2. akshare/air/air_hebei.py +79 -53
  3. akshare/air/air_zhenqi.py +29 -43
  4. akshare/air/sunrise_tad.py +32 -17
  5. akshare/bank/bank_cbirc_2020.py +12 -9
  6. akshare/bond/bond_cb_ths.py +17 -9
  7. akshare/bond/bond_china.py +38 -39
  8. akshare/bond/bond_china_money.py +75 -48
  9. akshare/bond/bond_info_cm.py +28 -8
  10. akshare/bond/bond_issue_cninfo.py +73 -30
  11. akshare/bond/bond_zh_cov.py +1 -1
  12. akshare/bond/bond_zh_sina.py +57 -51
  13. akshare/cal/__init__.py +0 -0
  14. akshare/cal/rv.py +170 -0
  15. akshare/cost/cost_living.py +7 -5
  16. akshare/currency/currency_safe.py +7 -6
  17. akshare/data/cninfo.js +15 -0
  18. akshare/datasets.py +10 -21
  19. akshare/economic/macro_bank.py +95 -653
  20. akshare/economic/macro_china.py +772 -1024
  21. akshare/economic/macro_china_hk.py +65 -243
  22. akshare/economic/macro_china_nbs.py +24 -7
  23. akshare/economic/macro_constitute.py +17 -12
  24. akshare/economic/macro_euro.py +13 -6
  25. akshare/economic/macro_finance_ths.py +133 -0
  26. akshare/economic/macro_info_ws.py +100 -0
  27. akshare/economic/macro_japan.py +5 -4
  28. akshare/economic/macro_other.py +12 -9
  29. akshare/economic/macro_usa.py +376 -1940
  30. akshare/economic/marco_cnbs.py +11 -6
  31. akshare/energy/energy_carbon.py +94 -125
  32. akshare/event/migration.py +3 -2
  33. akshare/exceptions.py +43 -0
  34. akshare/file_fold/calendar.json +245 -2
  35. akshare/fortune/fortune_500.py +15 -48
  36. akshare/fund/fund_amac.py +157 -75
  37. akshare/fund/fund_em.py +191 -184
  38. akshare/fund/fund_etf_em.py +16 -15
  39. akshare/fund/fund_etf_sina.py +71 -23
  40. akshare/fund/fund_etf_ths.py +93 -0
  41. akshare/fund/fund_fee_em.py +98 -0
  42. akshare/fund/fund_portfolio_em.py +60 -50
  43. akshare/fund/fund_rank_em.py +91 -82
  44. akshare/fund/fund_report_cninfo.py +63 -48
  45. akshare/fund/fund_scale_sina.py +20 -10
  46. akshare/fund/fund_xq.py +139 -109
  47. akshare/futures/cons.py +8 -31
  48. akshare/futures/cot.py +185 -137
  49. akshare/futures/futures_basis.py +97 -32
  50. akshare/futures/futures_comm_ctp.py +37 -0
  51. akshare/futures/futures_comm_qihuo.py +74 -45
  52. akshare/futures/futures_daily_bar.py +121 -184
  53. akshare/futures/futures_hf_em.py +66 -61
  54. akshare/futures/futures_hq_sina.py +79 -61
  55. akshare/futures/futures_index_ccidx.py +6 -3
  56. akshare/futures/futures_inventory_99.py +61 -272
  57. akshare/futures/futures_news_shmet.py +4 -2
  58. akshare/futures/futures_roll_yield.py +12 -25
  59. akshare/futures/futures_spot_stock_em.py +19 -13
  60. akshare/futures/futures_stock_js.py +14 -12
  61. akshare/futures/futures_to_spot.py +38 -33
  62. akshare/futures/futures_warehouse_receipt.py +75 -71
  63. akshare/futures/futures_zh_sina.py +5 -5
  64. akshare/futures/symbol_var.py +18 -13
  65. akshare/futures_derivative/futures_contract_info_czce.py +60 -52
  66. akshare/futures_derivative/futures_contract_info_ine.py +43 -34
  67. akshare/futures_derivative/futures_contract_info_shfe.py +46 -35
  68. akshare/futures_derivative/futures_cot_sina.py +26 -19
  69. akshare/futures_derivative/futures_spot_sys.py +21 -8
  70. akshare/fx/currency_investing.py +19 -285
  71. akshare/index/index_cflp.py +29 -26
  72. akshare/index/index_cni.py +86 -88
  73. akshare/index/index_cons.py +26 -10
  74. akshare/index/index_cx.py +248 -47
  75. akshare/index/index_drewry.py +17 -16
  76. akshare/index/index_option_qvix.py +329 -0
  77. akshare/index/index_research_fund_sw.py +134 -0
  78. akshare/index/{index_sw_research.py → index_research_sw.py} +122 -58
  79. akshare/index/index_spot.py +9 -5
  80. akshare/index/index_stock_hk.py +35 -16
  81. akshare/index/index_stock_us_sina.py +1 -1
  82. akshare/index/index_stock_zh.py +180 -89
  83. akshare/index/index_stock_zh_csindex.py +15 -369
  84. akshare/index/index_sw.py +62 -34
  85. akshare/index/index_yw.py +46 -23
  86. akshare/index/index_zh_a_scope.py +48 -0
  87. akshare/index/index_zh_em.py +6 -4
  88. akshare/interest_rate/interbank_rate_em.py +14 -9
  89. akshare/movie/artist_yien.py +32 -5
  90. akshare/movie/movie_yien.py +92 -18
  91. akshare/movie/video_yien.py +28 -5
  92. akshare/news/news_baidu.py +78 -44
  93. akshare/news/news_cctv.py +38 -38
  94. akshare/news/news_stock.py +6 -3
  95. akshare/nlp/nlp_interface.py +7 -8
  96. akshare/option/cons.py +11 -11
  97. akshare/option/option_comm_qihuo.py +86 -0
  98. akshare/option/option_commodity.py +178 -51
  99. akshare/option/option_daily_stats_sse_szse.py +146 -0
  100. akshare/option/option_em.py +147 -138
  101. akshare/option/option_finance_sina.py +160 -137
  102. akshare/option/option_lhb_em.py +62 -56
  103. akshare/option/option_risk_indicator_sse.py +17 -14
  104. akshare/other/other_car_cpca.py +934 -0
  105. akshare/other/{other_car.py → other_car_gasgoo.py} +15 -54
  106. akshare/qdii/__init__.py +0 -0
  107. akshare/qdii/qdii_jsl.py +233 -0
  108. akshare/request.py +117 -0
  109. akshare/spot/spot_hog_soozhu.py +232 -0
  110. akshare/spot/spot_price_qh.py +121 -0
  111. akshare/spot/spot_sge.py +63 -10
  112. akshare/stock/stock_allotment_cninfo.py +10 -9
  113. akshare/stock/stock_board_concept_em.py +23 -14
  114. akshare/stock/stock_board_industry_em.py +40 -34
  115. akshare/stock/stock_cg_equity_mortgage.py +15 -11
  116. akshare/stock/stock_cg_guarantee.py +41 -51
  117. akshare/stock/stock_cg_lawsuit.py +36 -35
  118. akshare/stock/stock_dividend_cninfo.py +12 -6
  119. akshare/stock/stock_dzjy_em.py +347 -260
  120. akshare/stock/stock_fund_em.py +332 -84
  121. akshare/stock/stock_hk_famous.py +108 -0
  122. akshare/stock/stock_hk_sina.py +8 -7
  123. akshare/stock/stock_hold_control_cninfo.py +100 -15
  124. akshare/stock/stock_hold_control_em.py +4 -3
  125. akshare/stock/stock_hold_num_cninfo.py +18 -12
  126. akshare/stock/stock_hot_rank_em.py +2 -1
  127. akshare/stock/stock_hot_search_baidu.py +5 -2
  128. akshare/stock/stock_industry_cninfo.py +24 -18
  129. akshare/stock/stock_industry_pe_cninfo.py +45 -31
  130. akshare/stock/stock_industry_sw.py +9 -10
  131. akshare/stock/stock_info.py +25 -15
  132. akshare/stock/stock_info_em.py +5 -2
  133. akshare/stock/stock_intraday_em.py +5 -2
  134. akshare/stock/stock_intraday_sina.py +22 -18
  135. akshare/stock/stock_ipo_summary_cninfo.py +25 -10
  136. akshare/stock/stock_new_cninfo.py +32 -19
  137. akshare/stock/stock_news_cx.py +39 -0
  138. akshare/stock/stock_profile_cninfo.py +9 -8
  139. akshare/stock/stock_rank_forecast.py +8 -6
  140. akshare/stock/stock_share_changes_cninfo.py +18 -14
  141. akshare/stock/stock_share_hold.py +24 -19
  142. akshare/stock/stock_summary.py +54 -26
  143. akshare/stock/stock_us_famous.py +15 -6
  144. akshare/stock/stock_us_pink.py +7 -5
  145. akshare/stock/stock_us_sina.py +15 -12
  146. akshare/stock/stock_xq.py +38 -12
  147. akshare/stock/stock_zh_a_sina.py +53 -78
  148. akshare/stock/stock_zh_b_sina.py +32 -55
  149. akshare/stock/stock_zh_kcb_report.py +11 -9
  150. akshare/stock/stock_zh_kcb_sina.py +67 -64
  151. akshare/stock_feature/stock_a_below_net_asset_statistics.py +5 -2
  152. akshare/stock_feature/stock_a_high_low.py +5 -2
  153. akshare/stock_feature/stock_a_indicator.py +12 -9
  154. akshare/stock_feature/stock_a_pe_and_pb.py +27 -6
  155. akshare/stock_feature/stock_account_em.py +58 -40
  156. akshare/stock_feature/stock_analyst_em.py +36 -27
  157. akshare/stock_feature/stock_board_industry_ths.py +136 -400
  158. akshare/stock_feature/stock_comment_em.py +118 -85
  159. akshare/stock_feature/stock_concept_futu.py +183 -0
  160. akshare/stock_feature/stock_cyq_em.py +58 -54
  161. akshare/stock_feature/stock_disclosure_cninfo.py +147 -102
  162. akshare/stock_feature/stock_esg_sina.py +216 -11
  163. akshare/stock_feature/stock_fhps_em.py +60 -25
  164. akshare/stock_feature/stock_fhps_ths.py +25 -6
  165. akshare/stock_feature/stock_fund_flow.py +38 -25
  166. akshare/stock_feature/stock_gdfx_em.py +180 -95
  167. akshare/stock_feature/stock_gdhs.py +73 -49
  168. akshare/stock_feature/stock_gpzy_em.py +78 -46
  169. akshare/stock_feature/stock_hist_em.py +55 -23
  170. akshare/stock_feature/stock_hk_valuation_baidu.py +20 -8
  171. akshare/stock_feature/stock_hsgt_em.py +184 -452
  172. akshare/stock_feature/stock_info.py +52 -29
  173. akshare/stock_feature/stock_inner_trade_xq.py +39 -31
  174. akshare/stock_feature/stock_irm_cninfo.py +32 -9
  175. akshare/stock_feature/stock_jgdy_em.py +41 -38
  176. akshare/stock_feature/stock_lh_yybpm.py +36 -37
  177. akshare/stock_feature/stock_lhb_em.py +135 -71
  178. akshare/stock_feature/stock_lhb_sina.py +93 -46
  179. akshare/stock_feature/stock_margin_em.py +102 -0
  180. akshare/stock_feature/{stock_sse_margin.py → stock_margin_sse.py} +21 -15
  181. akshare/stock_feature/{stock_szse_margin.py → stock_margin_szse.py} +23 -19
  182. akshare/stock_feature/stock_market_legu.py +13 -8
  183. akshare/stock_feature/stock_pankou_em.py +72 -34
  184. akshare/stock_feature/stock_report_em.py +244 -54
  185. akshare/stock_feature/stock_research_report_em.py +48 -19
  186. akshare/stock_feature/stock_sns_sseinfo.py +15 -12
  187. akshare/stock_feature/stock_sy_em.py +86 -33
  188. akshare/stock_feature/stock_technology_ths.py +152 -120
  189. akshare/stock_feature/stock_tfp_em.py +35 -13
  190. akshare/stock_feature/stock_three_report_em.py +119 -77
  191. akshare/stock_feature/stock_ttm_lyr.py +4 -7
  192. akshare/stock_feature/stock_value_em.py +83 -0
  193. akshare/stock_feature/stock_wencai.py +21 -9
  194. akshare/stock_feature/stock_yjyg_em.py +63 -28
  195. akshare/stock_feature/stock_zf_pg.py +61 -38
  196. akshare/stock_feature/stock_zh_valuation_baidu.py +3 -2
  197. akshare/stock_feature/stock_ztb_em.py +62 -40
  198. akshare/stock_fundamental/stock_finance.py +150 -58
  199. akshare/stock_fundamental/stock_finance_ths.py +116 -31
  200. akshare/stock_fundamental/stock_mda_ym.py +5 -3
  201. akshare/stock_fundamental/stock_notice.py +29 -15
  202. akshare/stock_fundamental/stock_profit_forecast_em.py +31 -13
  203. akshare/stock_fundamental/stock_profit_forecast_ths.py +19 -10
  204. akshare/stock_fundamental/stock_register_em.py +448 -0
  205. akshare/stock_fundamental/stock_restricted_em.py +79 -32
  206. akshare/stock_fundamental/stock_zygc.py +10 -8
  207. akshare/stock_fundamental/stock_zyjs_ths.py +5 -3
  208. akshare/tool/trade_date_hist.py +4 -3
  209. akshare/utils/cons.py +10 -0
  210. akshare/utils/context.py +43 -0
  211. akshare/utils/demjson.py +2 -2
  212. akshare/utils/func.py +26 -0
  213. akshare/utils/tqdm.py +13 -3
  214. {akshare-1.12.99.dist-info → akshare-1.15.72.dist-info}/METADATA +52 -69
  215. akshare-1.15.72.dist-info/RECORD +385 -0
  216. {akshare-1.12.99.dist-info → akshare-1.15.72.dist-info}/WHEEL +1 -1
  217. tests/test_func.py +3 -5
  218. akshare/bond/bond_futures.py +0 -50
  219. akshare/bond/bond_investing.py +0 -139
  220. akshare/crypto/crypto_hist_investing.py +0 -249
  221. akshare/fortune/fortune_it_juzi.py +0 -123
  222. akshare/futures/futures_international.py +0 -170
  223. akshare/futures/futures_news_baidu.py +0 -54
  224. akshare/futures/inventory_data.py +0 -100
  225. akshare/futures_derivative/futures_index_price_nh.py +0 -61
  226. akshare/futures_derivative/futures_index_return_nh.py +0 -47
  227. akshare/futures_derivative/futures_index_volatility_nh.py +0 -51
  228. akshare/futures_derivative/futures_other_index_nh.py +0 -145
  229. akshare/index/index_fear_greed_funddb.py +0 -71
  230. akshare/index/index_investing.py +0 -232
  231. akshare/sport/sport_olympic_winter.py +0 -39
  232. akshare/stock_feature/stock_board_concept_ths.py +0 -422
  233. akshare/stock_fundamental/stock_register.py +0 -292
  234. akshare-1.12.99.dist-info/RECORD +0 -374
  235. {akshare-1.12.99.dist-info → akshare-1.15.72.dist-info}/LICENSE +0 -0
  236. {akshare-1.12.99.dist-info → akshare-1.15.72.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python
2
2
  # -*- coding:utf-8 -*-
3
3
  """
4
- Date: 2023/5/11 17:30
4
+ Date: 2024/12/12 17:00
5
5
  Desc: 生意社网站采集大宗商品现货价格及相应基差数据, 数据时间段从 20110104-至今
6
6
  备注:现期差 = 现货价格 - 期货价格(这里的期货价格为结算价)
7
7
  黄金为 元/克, 白银为 元/千克, 玻璃现货为 元/平方米, 鸡蛋现货为 元/公斤, 鸡蛋期货为 元/500千克, 其余为 元/吨.
@@ -12,6 +12,7 @@ Desc: 生意社网站采集大宗商品现货价格及相应基差数据, 数据
12
12
  发现生意社的 bugs:
13
13
  1. 2018-09-12 周三 数据缺失是因为生意社源数据在该交易日缺失: https://www.100ppi.com/sf/day-2018-09-12.html
14
14
  """
15
+
15
16
  import datetime
16
17
  import re
17
18
  import time
@@ -74,7 +75,9 @@ def futures_spot_price_daily(
74
75
  return temp_df
75
76
 
76
77
 
77
- def futures_spot_price(date: str = "20230509", vars_list: list = cons.contract_symbols) -> pd.DataFrame:
78
+ def futures_spot_price(
79
+ date: str = "20240430", vars_list: list = cons.contract_symbols
80
+ ) -> pd.DataFrame:
78
81
  """
79
82
  指定交易日大宗商品现货价格及相应基差
80
83
  https://www.100ppi.com/sf/day-2017-09-12.html
@@ -96,12 +99,14 @@ def futures_spot_price(date: str = "20230509", vars_list: list = cons.contract_s
96
99
  """
97
100
  date = cons.convert_date(date) if date is not None else datetime.date.today()
98
101
  if date < datetime.date(2011, 1, 4):
99
- raise Exception("数据源开始日期为 20110104, 请将获取数据时间点设置在 20110104 后")
102
+ raise Exception(
103
+ "数据源开始日期为 20110104, 请将获取数据时间点设置在 20110104 后"
104
+ )
100
105
  if date.strftime("%Y%m%d") not in calendar:
101
106
  warnings.warn(f"{date.strftime('%Y%m%d')}非交易日")
102
107
  return pd.DataFrame()
103
- u1 = "http://www.100ppi.com/sf/"
104
- u2 = f'http://www.100ppi.com/sf/day-{date.strftime("%Y-%m-%d")}.html'
108
+ u1 = "https://www.100ppi.com/sf/"
109
+ u2 = f'https://www.100ppi.com/sf/day-{date.strftime("%Y-%m-%d")}.html'
105
110
  i = 1
106
111
  while True:
107
112
  for url in [u2, u1]:
@@ -119,12 +124,16 @@ def futures_spot_price(date: str = "20230509", vars_list: list = cons.contract_s
119
124
  return temp_df
120
125
  else:
121
126
  time.sleep(3)
122
- except:
123
- print(f"{date.strftime('%Y-%m-%d')}日生意社数据连接失败,第{str(i)}次尝试,最多5次")
127
+ except Exception as e: # noqa: E722
128
+ print(
129
+ f"{date.strftime('%Y-%m-%d')}日生意社数据连接失败[错误信息:{e}],第{str(i)}次尝试,最多5次"
130
+ )
124
131
  i += 1
125
132
  if i > 5:
126
133
  print(
127
- f"{date.strftime('%Y-%m-%d')}日生意社数据连接失败, 如果当前交易日是 2018-09-12, 由于生意社源数据缺失, 无法访问, 否则为重复访问已超过5次,您的地址被网站墙了,请保存好返回数据,稍后从该日期起重试"
134
+ f"{date.strftime('%Y-%m-%d')}日生意社数据连接失败, 如果当前交易日是 2018-09-12, "
135
+ f"由于生意社源数据缺失, 无法访问, 否则为重复访问已超过5次,您的地址被网站墙了,"
136
+ f"请保存好返回数据,稍后从该日期起重试"
128
137
  )
129
138
  return pd.DataFrame()
130
139
 
@@ -160,11 +169,27 @@ def _check_information(df_data, date):
160
169
  ]
161
170
  records = pd.DataFrame()
162
171
  for string in df_data["symbol"].tolist():
172
+ news = "".join(re.findall(r"[\u4e00-\u9fa5]", string))
173
+ if news == "":
174
+ news = string.strip()
175
+
176
+ """
163
177
  if string == "PTA":
164
178
  news = "PTA"
165
179
  else:
166
180
  news = "".join(re.findall(r"[\u4e00-\u9fa5]", string))
167
- if news != "" and news not in ["商品", "价格", "上海期货交易所", "郑州商品交易所", "大连商品交易所", "广州期货交易所"]:
181
+ """
182
+
183
+ if news != "" and news not in [
184
+ "商品",
185
+ "价格",
186
+ "上海期货交易所",
187
+ "郑州商品交易所",
188
+ "大连商品交易所",
189
+ "广州期货交易所",
190
+ # 某些天网站没有数据,比如 20180912,此时返回"暂无数据",但并不是网站被墙了
191
+ "暂无数据",
192
+ ]:
168
193
  symbol = chinese_to_english(news)
169
194
  record = pd.DataFrame(df_data[df_data["symbol"] == string])
170
195
  record.loc[:, "symbol"] = symbol
@@ -177,14 +202,26 @@ def _check_information(df_data, date):
177
202
  symbol == "FG"
178
203
  ): # 上表中现货单位为元/平方米, 期货单位为元/吨. 换算公式:元/平方米*80=元/吨(http://www.100ppi.com/sf/959.html)
179
204
  record.loc[:, "spot_price"] = float(record["spot_price"].iloc[0]) * 80
205
+ elif (
206
+ symbol == "LH"
207
+ ): # 上表中现货单位为元/公斤, 期货单位为元/吨. 换算公式:元/公斤*1000=元/吨(http://www.100ppi.com/sf/959.html)
208
+ record.loc[:, "spot_price"] = float(record["spot_price"].iloc[0]) * 1000
180
209
  records = pd.concat([records, record])
181
210
 
182
- records.loc[
183
- :, ["near_contract_price", "dominant_contract_price", "spot_price"]
184
- ] = records.loc[
185
- :, ["near_contract_price", "dominant_contract_price", "spot_price"]
186
- ].astype(
187
- "float"
211
+ # 20241129:如果某日没有数据,直接返回返回空表
212
+ if records.empty:
213
+ records = df_data.iloc[0:0]
214
+ records["near_basis"] = pd.Series(dtype="float")
215
+ records["dom_basis"] = pd.Series(dtype="float")
216
+ records["near_basis_rate"] = pd.Series(dtype="float")
217
+ records["dom_basis_rate"] = pd.Series(dtype="float")
218
+ records["date"] = pd.Series(dtype="object")
219
+ return records
220
+
221
+ records.loc[:, ["near_contract_price", "dominant_contract_price", "spot_price"]] = (
222
+ records.loc[
223
+ :, ["near_contract_price", "dominant_contract_price", "spot_price"]
224
+ ].astype("float")
188
225
  )
189
226
 
190
227
  records.loc[:, "near_contract"] = records["near_contract"].replace(
@@ -194,9 +231,11 @@ def _check_information(df_data, date):
194
231
  r"[^0-9]*(\d*)$", r"\g<1>", regex=True
195
232
  )
196
233
 
234
+ records.loc[:, "near_month"] = records.loc[:, "near_contract"]
197
235
  records.loc[:, "near_contract"] = records["symbol"] + records.loc[
198
236
  :, "near_contract"
199
237
  ].astype("int").astype("str")
238
+ records.loc[:, "dominant_month"] = records.loc[:, "dominant_contract"]
200
239
  records.loc[:, "dominant_contract"] = records["symbol"] + records.loc[
201
240
  :, "dominant_contract"
202
241
  ].astype("int").astype("str")
@@ -232,7 +271,8 @@ def _check_information(df_data, date):
232
271
  records["dom_basis_rate"] = (
233
272
  records["dominant_contract_price"] / records["spot_price"] - 1
234
273
  )
235
- records.loc[:, "date"] = date.strftime("%Y%m%d")
274
+ # records.loc[:, "date"] = date.strftime("%Y%m%d")
275
+ records.insert(0, "date", date.strftime("%Y%m%d"))
236
276
  return records
237
277
 
238
278
 
@@ -240,17 +280,17 @@ def _join_head(content: pd.DataFrame) -> List:
240
280
  headers = []
241
281
  for s1, s2 in zip(content.iloc[0], content.iloc[1]):
242
282
  if s1 != s2:
243
- s = f'{s1}{s2}'
283
+ s = f"{s1}{s2}"
244
284
  else:
245
285
  s = s1
246
286
  headers.append(s)
247
287
  return headers
248
288
 
249
289
 
250
- def futures_spot_price_previous(date: str = "20220209") -> pd.DataFrame:
290
+ def futures_spot_price_previous(date: str = "20240430") -> pd.DataFrame:
251
291
  """
252
292
  具体交易日大宗商品现货价格及相应基差
253
- http://www.100ppi.com/sf/day-2017-09-12.html
293
+ https://www.100ppi.com/sf/day-2017-09-12.html
254
294
  :param date: 交易日; 历史日期
255
295
  :type date: str
256
296
  :return: 现货价格及相应基差
@@ -258,24 +298,49 @@ def futures_spot_price_previous(date: str = "20220209") -> pd.DataFrame:
258
298
  """
259
299
  date = cons.convert_date(date) if date is not None else datetime.date.today()
260
300
  if date < datetime.date(2011, 1, 4):
261
- raise Exception("数据源开始日期为 20110104, 请将获取数据时间点设置在 20110104 后")
301
+ raise Exception(
302
+ "数据源开始日期为 20110104, 请将获取数据时间点设置在 20110104 后"
303
+ )
262
304
  if date.strftime("%Y%m%d") not in calendar:
263
305
  warnings.warn(f"{date.strftime('%Y%m%d')}非交易日")
264
- return
265
- url = date.strftime('http://www.100ppi.com/sf2/day-%Y-%m-%d.html')
306
+ return pd.DataFrame()
307
+ url = date.strftime("https://www.100ppi.com/sf2/day-%Y-%m-%d.html")
266
308
  content = pandas_read_html_link(url)
267
309
  main = content[1]
268
310
  # Header
269
311
  header = _join_head(main)
270
312
  # Values
271
- values = main[main[4].str.endswith('%')]
313
+ values = main[main[4].str.endswith("%")]
272
314
  values.columns = header
273
315
  # Basis
274
- basis = pd.concat(content[2:-1])
275
- basis.columns = ['主力合约基差', '主力合约基差(%)']
276
- basis['商品'] = values['商品'].tolist()
277
- basis = pd.merge(values[["商品", "现货价格", "主力合约代码", "主力合约价格"]], basis)
278
- basis = pd.merge(basis, values[["商品", "180日内主力基差最高", "180日内主力基差最低", "180日内主力基差平均"]])
316
+ # 对于没有数据的天,xml文件中没有数据,所以content[2:-1]可能为空
317
+ if len(content[2:-1]) > 0:
318
+ basis = pd.concat(content[2:-1])
319
+ else:
320
+ basis = pd.DataFrame(columns=["主力合约基差", "主力合约基差(%)"])
321
+
322
+ basis.columns = ["主力合约基差", "主力合约基差(%)"]
323
+ # 20241125(jasonudu):因为部分日期,存在多个品种的现货价格,比如20151125的白糖、豆粕、豆油等,如果用商品名来merge,会出现重复列名,所以改用index来merge
324
+ # basis["商品"] = values["商品"].tolist()
325
+ basis.index = values.index
326
+ basis = pd.merge(
327
+ values[["商品", "现货价格", "主力合约代码", "主力合约价格"]],
328
+ basis,
329
+ left_index=True,
330
+ right_index=True,
331
+ )
332
+ basis = pd.merge(
333
+ basis,
334
+ values[
335
+ [
336
+ "180日内主力基差最高",
337
+ "180日内主力基差最低",
338
+ "180日内主力基差平均",
339
+ ]
340
+ ],
341
+ left_index=True,
342
+ right_index=True,
343
+ )
279
344
  basis.columns = [
280
345
  "商品",
281
346
  "现货价格",
@@ -287,18 +352,18 @@ def futures_spot_price_previous(date: str = "20220209") -> pd.DataFrame:
287
352
  "180日内主力基差最低",
288
353
  "180日内主力基差平均",
289
354
  ]
290
- basis['主力合约变动百分比'] = basis['主力合约变动百分比'].str.strip("%")
355
+ basis["主力合约变动百分比"] = basis["主力合约变动百分比"].str.strip("%")
291
356
  return basis
292
357
 
293
358
 
294
359
  if __name__ == "__main__":
295
360
  futures_spot_price_daily_df = futures_spot_price_daily(
296
- start_day="20230919", end_day="20230927", vars_list=['SR']
361
+ start_day="20240415", end_day="20240418", vars_list=["CU", "RB"]
297
362
  )
298
363
  print(futures_spot_price_daily_df)
299
364
 
300
- futures_spot_price_df = futures_spot_price(date="20230919")
365
+ futures_spot_price_df = futures_spot_price(date="20240430")
301
366
  print(futures_spot_price_df)
302
367
 
303
- futures_spot_price_previous_df = futures_spot_price_previous(date='20230807')
368
+ futures_spot_price_previous_df = futures_spot_price_previous(date="20240430")
304
369
  print(futures_spot_price_previous_df)
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding:utf-8 -*-
3
+ """
4
+ Date: 2024/7/6 18:00
5
+ Desc: openctp 期货交易费用参照表
6
+ http://openctp.cn/fees.html
7
+ """
8
+
9
+ from datetime import datetime
10
+ from io import StringIO
11
+
12
+ import pandas as pd
13
+ import requests
14
+ from bs4 import BeautifulSoup
15
+
16
+
17
+ def futures_fees_info() -> pd.DataFrame:
18
+ """
19
+ openctp 期货交易费用参照表
20
+ http://openctp.cn/fees.html
21
+ :return: 期货交易费用参照表
22
+ :rtype: pandas.DataFrame
23
+ """
24
+ url = "http://openctp.cn/fees.html"
25
+ r = requests.get(url)
26
+ r.encoding = "gb2312"
27
+ soup = BeautifulSoup(r.text, features="lxml")
28
+ datetime_str = soup.find("p").string.strip("Generated at ").strip(".")
29
+ datetime_raw = datetime.strptime(datetime_str, "%Y-%m-%d %H:%M:%S")
30
+ temp_df = pd.read_html(StringIO(r.text))[0]
31
+ temp_df["更新时间"] = datetime_raw.strftime("%Y-%m-%d %H:%M:%S")
32
+ return temp_df
33
+
34
+
35
+ if __name__ == "__main__":
36
+ futures_fees_info_df = futures_fees_info()
37
+ print(futures_fees_info_df)
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env python
2
2
  # -*- coding:utf-8 -*-
3
3
  """
4
- Date: 2023/12/22 11:20
4
+ Date: 2024/4/11 17:00
5
5
  Desc: 九期网-期货手续费
6
6
  https://www.9qihuo.com/qihuoshouxufei
7
7
  """
8
+
8
9
  from io import StringIO
9
10
 
10
11
  import pandas as pd
@@ -23,6 +24,9 @@ def _futures_comm_qihuo_process(df: pd.DataFrame, name: str = None) -> pd.DataFr
23
24
  :return: 处理后的数据
24
25
  :rtype: pandas.DataFrame
25
26
  """
27
+ import urllib3
28
+
29
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
26
30
  common_temp_df = df.copy()
27
31
  common_temp_df["合约名称"] = (
28
32
  common_temp_df["合约品种"].str.split("(", expand=True).iloc[:, 0].str.strip()
@@ -42,13 +46,15 @@ def _futures_comm_qihuo_process(df: pd.DataFrame, name: str = None) -> pd.DataFr
42
46
  common_temp_df["手续费"] = common_temp_df["手续费(开+平)"].str.strip("元")
43
47
  try:
44
48
  temp_df_ratio = (
45
- common_temp_df["手续费标准-开仓"][common_temp_df["手续费标准-开仓"].str.contains("万分之")]
46
- .str.split("/", expand=True)
47
- .iloc[:, 0]
48
- .astype(float)
49
- / 10000
49
+ common_temp_df["手续费标准-开仓"][
50
+ common_temp_df["手续费标准-开仓"].str.contains("万分之")
51
+ ]
52
+ .str.split("/", expand=True)
53
+ .iloc[:, 0]
54
+ .astype(float)
55
+ / 10000
50
56
  )
51
- except IndexError as e:
57
+ except IndexError:
52
58
  temp_df_ratio = pd.NA
53
59
  temp_df_yuan = common_temp_df["手续费标准-开仓"][
54
60
  common_temp_df["手续费标准-开仓"].str.contains("元")
@@ -57,13 +63,15 @@ def _futures_comm_qihuo_process(df: pd.DataFrame, name: str = None) -> pd.DataFr
57
63
  common_temp_df["手续费标准-开仓-元"] = temp_df_yuan.str.strip("元")
58
64
  try:
59
65
  temp_df_ratio = (
60
- common_temp_df["手续费标准-平昨"][common_temp_df["手续费标准-平昨"].str.contains("万分之")]
61
- .str.split("/", expand=True)
62
- .iloc[:, 0]
63
- .astype(float)
64
- / 10000
66
+ common_temp_df["手续费标准-平昨"][
67
+ common_temp_df["手续费标准-平昨"].str.contains("万分之")
68
+ ]
69
+ .str.split("/", expand=True)
70
+ .iloc[:, 0]
71
+ .astype(float)
72
+ / 10000
65
73
  )
66
- except IndexError as e:
74
+ except IndexError:
67
75
  temp_df_ratio = pd.NA
68
76
  temp_df_yuan = common_temp_df["手续费标准-平昨"][
69
77
  common_temp_df["手续费标准-平昨"].str.contains("元")
@@ -72,13 +80,15 @@ def _futures_comm_qihuo_process(df: pd.DataFrame, name: str = None) -> pd.DataFr
72
80
  common_temp_df["手续费标准-平昨-元"] = temp_df_yuan.str.strip("元")
73
81
  try:
74
82
  temp_df_ratio = (
75
- common_temp_df["手续费标准-平今"][common_temp_df["手续费标准-平今"].str.contains("万分之")]
76
- .str.split("/", expand=True)
77
- .iloc[:, 0]
78
- .astype(float)
79
- / 10000
83
+ common_temp_df["手续费标准-平今"][
84
+ common_temp_df["手续费标准-平今"].str.contains("万分之")
85
+ ]
86
+ .str.split("/", expand=True)
87
+ .iloc[:, 0]
88
+ .astype(float)
89
+ / 10000
80
90
  )
81
- except IndexError as e:
91
+ except IndexError:
82
92
  temp_df_ratio = pd.NA
83
93
  temp_df_yuan = common_temp_df["手续费标准-平今"][
84
94
  common_temp_df["手续费标准-平今"].str.contains("元")
@@ -128,12 +138,14 @@ def _futures_comm_qihuo_process(df: pd.DataFrame, name: str = None) -> pd.DataFr
128
138
  common_temp_df["每跳毛利"] = pd.to_numeric(common_temp_df["每跳毛利"])
129
139
  common_temp_df["手续费"] = pd.to_numeric(common_temp_df["手续费"])
130
140
  common_temp_df["每跳净利"] = pd.to_numeric(common_temp_df["每跳净利"])
131
- url = "http://www.9qihuo.com/qihuoshouxufei"
132
- r = requests.get(url)
133
- soup = BeautifulSoup(r.text, "lxml")
134
- raw_date_text = soup.find("a", attrs={"id": "dlink"}).previous
141
+ url = "https://www.9qihuo.com/qihuoshouxufei"
142
+ r = requests.get(url, verify=False)
143
+ soup = BeautifulSoup(r.text, features="lxml")
144
+ raw_date_text = soup.find(name="a", attrs={"id": "dlink"}).previous
135
145
  comm_update_time = raw_date_text.split(",")[0].strip("(手续费更新时间:")
136
- price_update_time = raw_date_text.split(",")[1].strip("价格更新时间:").strip("。)")
146
+ price_update_time = (
147
+ raw_date_text.split(",")[1].strip("价格更新时间:").strip("。)")
148
+ )
137
149
  common_temp_df["手续费更新时间"] = comm_update_time
138
150
  common_temp_df["价格更新时间"] = price_update_time
139
151
  return common_temp_df
@@ -148,8 +160,11 @@ def futures_comm_info(symbol: str = "所有") -> pd.DataFrame:
148
160
  :return: 期货手续费
149
161
  :rtype: pandas.DataFrame
150
162
  """
163
+ import urllib3
164
+
165
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
151
166
  url = "https://www.9qihuo.com/qihuoshouxufei"
152
- r = requests.get(url)
167
+ r = requests.get(url, verify=False)
153
168
  temp_df = pd.read_html(StringIO(r.text))[0]
154
169
  temp_df.columns = [
155
170
  "合约品种",
@@ -171,47 +186,61 @@ def futures_comm_info(symbol: str = "所有") -> pd.DataFrame:
171
186
  df_0 = temp_df[temp_df["合约品种"].str.contains("上海期货交易所")].index.values[0]
172
187
  df_1 = temp_df[temp_df["合约品种"].str.contains("大连商品交易所")].index.values[0]
173
188
  df_2 = temp_df[temp_df["合约品种"].str.contains("郑州商品交易所")].index.values[0]
174
- df_3 = temp_df[temp_df["合约品种"].str.contains("上海国际能源交易中心")].index.values[0]
189
+ df_3 = temp_df[
190
+ temp_df["合约品种"].str.contains("上海国际能源交易中心")
191
+ ].index.values[0]
175
192
  df_4 = temp_df[temp_df["合约品种"].str.contains("广州期货交易所")].index.values[0]
176
- df_5 = temp_df[temp_df["合约品种"].str.contains("中国金融期货交易所")].index.values[0]
177
- shfe_df = temp_df.iloc[df_0 + 3: df_1, :].reset_index(drop=True)
178
- dce_df = temp_df.iloc[df_1 + 3: df_2, :].reset_index(drop=True)
179
- czce_df = temp_df.iloc[df_2 + 3: df_3, :].reset_index(drop=True)
180
- ine_df = temp_df.iloc[df_3 + 3: df_4, :].reset_index(drop=True)
181
- gfex_df = temp_df.iloc[df_4 + 3: df_5, :].reset_index(drop=True)
182
- cffex_df = temp_df.iloc[df_5 + 3:, :].reset_index(drop=True)
193
+ df_5 = temp_df[temp_df["合约品种"].str.contains("中国金融期货交易所")].index.values[
194
+ 0
195
+ ]
196
+ shfe_df = temp_df.iloc[df_0 + 3 : df_1, :].reset_index(drop=True)
197
+ dce_df = temp_df.iloc[df_1 + 3 : df_2, :].reset_index(drop=True)
198
+ czce_df = temp_df.iloc[df_2 + 3 : df_3, :].reset_index(drop=True)
199
+ ine_df = temp_df.iloc[df_3 + 3 : df_4, :].reset_index(drop=True)
200
+ gfex_df = temp_df.iloc[df_4 + 3 : df_5, :].reset_index(drop=True)
201
+ cffex_df = temp_df.iloc[df_5 + 3 :, :].reset_index(drop=True)
183
202
  if symbol == "上海期货交易所":
184
- return _futures_comm_qihuo_process(shfe_df, "上海期货交易所")
203
+ return _futures_comm_qihuo_process(shfe_df, name="上海期货交易所")
185
204
  elif symbol == "大连商品交易所":
186
- return _futures_comm_qihuo_process(dce_df, "大连商品交易所")
205
+ return _futures_comm_qihuo_process(dce_df, name="大连商品交易所")
187
206
  elif symbol == "郑州商品交易所":
188
- return _futures_comm_qihuo_process(czce_df, "郑州商品交易所")
207
+ return _futures_comm_qihuo_process(czce_df, name="郑州商品交易所")
189
208
  elif symbol == "上海国际能源交易中心":
190
- return _futures_comm_qihuo_process(ine_df, "上海国际能源交易中心")
209
+ return _futures_comm_qihuo_process(ine_df, name="上海国际能源交易中心")
191
210
  elif symbol == "广州期货交易所":
192
- return _futures_comm_qihuo_process(gfex_df, "广州期货交易所")
211
+ return _futures_comm_qihuo_process(gfex_df, name="广州期货交易所")
193
212
  elif symbol == "中国金融期货交易所":
194
- return _futures_comm_qihuo_process(cffex_df, "中国金融期货交易所")
213
+ return _futures_comm_qihuo_process(cffex_df, name="中国金融期货交易所")
195
214
  else:
196
215
  big_df = pd.DataFrame()
197
216
  big_df = pd.concat(
198
- [big_df, _futures_comm_qihuo_process(shfe_df, "上海期货交易所")], ignore_index=True
217
+ objs=[big_df, _futures_comm_qihuo_process(shfe_df, name="上海期货交易所")],
218
+ ignore_index=True,
199
219
  )
200
220
  big_df = pd.concat(
201
- [big_df, _futures_comm_qihuo_process(dce_df, "大连商品交易所")], ignore_index=True
221
+ objs=[big_df, _futures_comm_qihuo_process(dce_df, name="大连商品交易所")],
222
+ ignore_index=True,
202
223
  )
203
224
  big_df = pd.concat(
204
- [big_df, _futures_comm_qihuo_process(czce_df, "郑州商品交易所")], ignore_index=True
225
+ objs=[big_df, _futures_comm_qihuo_process(czce_df, name="郑州商品交易所")],
226
+ ignore_index=True,
205
227
  )
206
228
  big_df = pd.concat(
207
- [big_df, _futures_comm_qihuo_process(ine_df, "上海国际能源交易中心")],
229
+ objs=[
230
+ big_df,
231
+ _futures_comm_qihuo_process(ine_df, name="上海国际能源交易中心"),
232
+ ],
208
233
  ignore_index=True,
209
234
  )
210
235
  big_df = pd.concat(
211
- [big_df, _futures_comm_qihuo_process(gfex_df, "广州期货交易所")], ignore_index=True
236
+ objs=[big_df, _futures_comm_qihuo_process(gfex_df, name="广州期货交易所")],
237
+ ignore_index=True,
212
238
  )
213
239
  big_df = pd.concat(
214
- [big_df, _futures_comm_qihuo_process(cffex_df, "中国金融期货交易所")],
240
+ objs=[
241
+ big_df,
242
+ _futures_comm_qihuo_process(cffex_df, name="中国金融期货交易所"),
243
+ ],
215
244
  ignore_index=True,
216
245
  )
217
246
  return big_df