lib-x17-fintech 2.1.3__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.
Files changed (282) hide show
  1. lib_x17_fintech-2.1.3.dist-info/METADATA +633 -0
  2. lib_x17_fintech-2.1.3.dist-info/RECORD +282 -0
  3. lib_x17_fintech-2.1.3.dist-info/WHEEL +5 -0
  4. lib_x17_fintech-2.1.3.dist-info/licenses/LICENSE +1 -0
  5. lib_x17_fintech-2.1.3.dist-info/top_level.txt +1 -0
  6. xfintech/__init__.py +0 -0
  7. xfintech/connect/__init__.py +18 -0
  8. xfintech/connect/artifact/__init__.py +5 -0
  9. xfintech/connect/artifact/artifact.py +168 -0
  10. xfintech/connect/artifact/tests/__init__.py +3 -0
  11. xfintech/connect/artifact/tests/test_class_artifact_all.py +564 -0
  12. xfintech/connect/common/__init__.py +12 -0
  13. xfintech/connect/common/connect.py +49 -0
  14. xfintech/connect/common/connectref.py +119 -0
  15. xfintech/connect/common/error.py +62 -0
  16. xfintech/connect/common/tests/__init__.py +1 -0
  17. xfintech/connect/common/tests/test_class_connectlike_all.py +544 -0
  18. xfintech/connect/common/tests/test_class_connectref_all.py +586 -0
  19. xfintech/connect/common/tests/test_class_errors_all.py +524 -0
  20. xfintech/connect/instance/__init__.py +7 -0
  21. xfintech/connect/instance/macos.py +121 -0
  22. xfintech/connect/instance/s3.py +176 -0
  23. xfintech/connect/instance/tests/__init__.py +1 -0
  24. xfintech/connect/instance/tests/test_class_macosconnect_all.py +692 -0
  25. xfintech/connect/instance/tests/test_class_s3connect_all.py +603 -0
  26. xfintech/data/__init__.py +20 -0
  27. xfintech/data/common/__init__.py +15 -0
  28. xfintech/data/common/cache.py +186 -0
  29. xfintech/data/common/coolant.py +171 -0
  30. xfintech/data/common/metric.py +138 -0
  31. xfintech/data/common/paginate.py +132 -0
  32. xfintech/data/common/params.py +162 -0
  33. xfintech/data/common/retry.py +201 -0
  34. xfintech/data/common/tests/__init__.py +1 -0
  35. xfintech/data/common/tests/test_class_cache_all.py +681 -0
  36. xfintech/data/common/tests/test_class_coolant_all.py +534 -0
  37. xfintech/data/common/tests/test_class_metric_all.py +705 -0
  38. xfintech/data/common/tests/test_class_paginate_all.py +508 -0
  39. xfintech/data/common/tests/test_class_params_all.py +891 -0
  40. xfintech/data/common/tests/test_class_retry_all.py +714 -0
  41. xfintech/data/job/__init__.py +17 -0
  42. xfintech/data/job/errors.py +112 -0
  43. xfintech/data/job/house.py +156 -0
  44. xfintech/data/job/job.py +247 -0
  45. xfintech/data/job/joblike.py +47 -0
  46. xfintech/data/job/tests/__init__.py +1 -0
  47. xfintech/data/job/tests/test_class_errors_all.py +275 -0
  48. xfintech/data/job/tests/test_class_house_all.py +801 -0
  49. xfintech/data/job/tests/test_class_job_all.py +684 -0
  50. xfintech/data/job/tests/test_class_joblike_all.py +482 -0
  51. xfintech/data/relay/__init__.py +7 -0
  52. xfintech/data/relay/client.py +114 -0
  53. xfintech/data/relay/clientlike.py +45 -0
  54. xfintech/data/relay/tests/test_class_relayclient_all.py +484 -0
  55. xfintech/data/relay/tests/test_class_relayclientlike_all.py +500 -0
  56. xfintech/data/source/__init__.py +7 -0
  57. xfintech/data/source/baostock/__init__.py +21 -0
  58. xfintech/data/source/baostock/job/__init__.py +5 -0
  59. xfintech/data/source/baostock/job/job.py +217 -0
  60. xfintech/data/source/baostock/job/tests/__init__.py +0 -0
  61. xfintech/data/source/baostock/job/tests/test_class_baostockjob_all.py +547 -0
  62. xfintech/data/source/baostock/session/__init__.py +8 -0
  63. xfintech/data/source/baostock/session/relay.py +223 -0
  64. xfintech/data/source/baostock/session/session.py +241 -0
  65. xfintech/data/source/baostock/session/tests/__init__.py +0 -0
  66. xfintech/data/source/baostock/session/tests/test_class_relay_all.py +694 -0
  67. xfintech/data/source/baostock/session/tests/test_class_session_all.py +505 -0
  68. xfintech/data/source/baostock/stock/__init__.py +0 -0
  69. xfintech/data/source/baostock/stock/hs300stock/__init__.py +3 -0
  70. xfintech/data/source/baostock/stock/hs300stock/constant.py +49 -0
  71. xfintech/data/source/baostock/stock/hs300stock/hs300stock.py +133 -0
  72. xfintech/data/source/baostock/stock/hs300stock/tests/__init__.py +1 -0
  73. xfintech/data/source/baostock/stock/hs300stock/tests/test_class_hs300index_all.py +413 -0
  74. xfintech/data/source/baostock/stock/minuteline/__init__.py +19 -0
  75. xfintech/data/source/baostock/stock/minuteline/constant.py +89 -0
  76. xfintech/data/source/baostock/stock/minuteline/minuteline.py +163 -0
  77. xfintech/data/source/baostock/stock/minuteline/tests/__init__.py +0 -0
  78. xfintech/data/source/baostock/stock/minuteline/tests/test_class_minuteline_all.py +582 -0
  79. xfintech/data/source/baostock/stock/stock/__init__.py +19 -0
  80. xfintech/data/source/baostock/stock/stock/constant.py +55 -0
  81. xfintech/data/source/baostock/stock/stock/stock.py +149 -0
  82. xfintech/data/source/baostock/stock/stock/tests/__init__.py +0 -0
  83. xfintech/data/source/baostock/stock/stock/tests/test_class_stock_all.py +508 -0
  84. xfintech/data/source/baostock/stock/stockinfo/__init__.py +5 -0
  85. xfintech/data/source/baostock/stock/stockinfo/constant.py +66 -0
  86. xfintech/data/source/baostock/stock/stockinfo/stockinfo.py +176 -0
  87. xfintech/data/source/baostock/stock/stockinfo/tests/__init__.py +1 -0
  88. xfintech/data/source/baostock/stock/stockinfo/tests/test_class_stockinfo_all.py +617 -0
  89. xfintech/data/source/baostock/stock/sz50stock/__init__.py +3 -0
  90. xfintech/data/source/baostock/stock/sz50stock/constant.py +49 -0
  91. xfintech/data/source/baostock/stock/sz50stock/sz50stock.py +133 -0
  92. xfintech/data/source/baostock/stock/sz50stock/tests/__init__.py +1 -0
  93. xfintech/data/source/baostock/stock/sz50stock/tests/test_class_sz50stock_all.py +397 -0
  94. xfintech/data/source/baostock/stock/tradedate/__init__.py +19 -0
  95. xfintech/data/source/baostock/stock/tradedate/constant.py +72 -0
  96. xfintech/data/source/baostock/stock/tradedate/tests/__init__.py +0 -0
  97. xfintech/data/source/baostock/stock/tradedate/tests/test_class_tradedate_all.py +695 -0
  98. xfintech/data/source/baostock/stock/tradedate/tradedate.py +208 -0
  99. xfintech/data/source/baostock/stock/zz500stock/__init__.py +3 -0
  100. xfintech/data/source/baostock/stock/zz500stock/constant.py +55 -0
  101. xfintech/data/source/baostock/stock/zz500stock/tests/__init__.py +1 -0
  102. xfintech/data/source/baostock/stock/zz500stock/tests/test_class_zz500stock_all.py +421 -0
  103. xfintech/data/source/baostock/stock/zz500stock/zz500stock.py +133 -0
  104. xfintech/data/source/tushare/__init__.py +61 -0
  105. xfintech/data/source/tushare/job/__init__.py +5 -0
  106. xfintech/data/source/tushare/job/job.py +257 -0
  107. xfintech/data/source/tushare/job/tests/test_class_tusharejob_all.py +589 -0
  108. xfintech/data/source/tushare/session/__init__.py +5 -0
  109. xfintech/data/source/tushare/session/relay.py +231 -0
  110. xfintech/data/source/tushare/session/session.py +239 -0
  111. xfintech/data/source/tushare/session/tests/test_class_relay_all.py +719 -0
  112. xfintech/data/source/tushare/session/tests/test_class_session_all.py +705 -0
  113. xfintech/data/source/tushare/stock/__init__.py +55 -0
  114. xfintech/data/source/tushare/stock/adjfactor/__init__.py +19 -0
  115. xfintech/data/source/tushare/stock/adjfactor/adjfactor.py +150 -0
  116. xfintech/data/source/tushare/stock/adjfactor/constant.py +71 -0
  117. xfintech/data/source/tushare/stock/adjfactor/tests/__init__.py +0 -0
  118. xfintech/data/source/tushare/stock/adjfactor/tests/test_class_adjfactor_all.py +372 -0
  119. xfintech/data/source/tushare/stock/capflow/__init__.py +19 -0
  120. xfintech/data/source/tushare/stock/capflow/capflow.py +171 -0
  121. xfintech/data/source/tushare/stock/capflow/constant.py +105 -0
  122. xfintech/data/source/tushare/stock/capflow/tests/__init__.py +0 -0
  123. xfintech/data/source/tushare/stock/capflow/tests/test_class_capflow_all.py +589 -0
  124. xfintech/data/source/tushare/stock/capflowdc/__init__.py +19 -0
  125. xfintech/data/source/tushare/stock/capflowdc/capflowdc.py +167 -0
  126. xfintech/data/source/tushare/stock/capflowdc/constant.py +95 -0
  127. xfintech/data/source/tushare/stock/capflowdc/tests/__init__.py +0 -0
  128. xfintech/data/source/tushare/stock/capflowdc/tests/test_class_capflowdc_all.py +814 -0
  129. xfintech/data/source/tushare/stock/capflowths/__init__.py +19 -0
  130. xfintech/data/source/tushare/stock/capflowths/capflowths.py +173 -0
  131. xfintech/data/source/tushare/stock/capflowths/constant.py +92 -0
  132. xfintech/data/source/tushare/stock/capflowths/tests/__init__.py +0 -0
  133. xfintech/data/source/tushare/stock/capflowths/tests/test_class_capflowths_all.py +551 -0
  134. xfintech/data/source/tushare/stock/company/__init__.py +19 -0
  135. xfintech/data/source/tushare/stock/company/company.py +188 -0
  136. xfintech/data/source/tushare/stock/company/constant.py +92 -0
  137. xfintech/data/source/tushare/stock/company/tests/__init__.py +1 -0
  138. xfintech/data/source/tushare/stock/company/tests/test_class_company_all.py +829 -0
  139. xfintech/data/source/tushare/stock/companybusiness/__init__.py +21 -0
  140. xfintech/data/source/tushare/stock/companybusiness/companybusiness.py +183 -0
  141. xfintech/data/source/tushare/stock/companybusiness/constant.py +91 -0
  142. xfintech/data/source/tushare/stock/companybusiness/tests/__init__.py +0 -0
  143. xfintech/data/source/tushare/stock/companybusiness/tests/test_class_companybusiness_all.py +633 -0
  144. xfintech/data/source/tushare/stock/companycashflow/__init__.py +21 -0
  145. xfintech/data/source/tushare/stock/companycashflow/companycashflow.py +277 -0
  146. xfintech/data/source/tushare/stock/companycashflow/constant.py +293 -0
  147. xfintech/data/source/tushare/stock/companycashflow/tests/__init__.py +0 -0
  148. xfintech/data/source/tushare/stock/companycashflow/tests/test_class_companycashflow_all.py +619 -0
  149. xfintech/data/source/tushare/stock/companydebt/__init__.py +19 -0
  150. xfintech/data/source/tushare/stock/companydebt/companydebt.py +339 -0
  151. xfintech/data/source/tushare/stock/companydebt/constant.py +403 -0
  152. xfintech/data/source/tushare/stock/companydebt/tests/__init__.py +0 -0
  153. xfintech/data/source/tushare/stock/companydebt/tests/test_class_companydebt_all.py +655 -0
  154. xfintech/data/source/tushare/stock/companyoverview/__init__.py +21 -0
  155. xfintech/data/source/tushare/stock/companyoverview/companyoverview.py +214 -0
  156. xfintech/data/source/tushare/stock/companyoverview/constant.py +152 -0
  157. xfintech/data/source/tushare/stock/companyoverview/tests/__init__.py +0 -0
  158. xfintech/data/source/tushare/stock/companyoverview/tests/test_class_companyoverview_all.py +647 -0
  159. xfintech/data/source/tushare/stock/companyprofit/__init__.py +21 -0
  160. xfintech/data/source/tushare/stock/companyprofit/companyprofit.py +272 -0
  161. xfintech/data/source/tushare/stock/companyprofit/constant.py +259 -0
  162. xfintech/data/source/tushare/stock/companyprofit/tests/__init__.py +0 -0
  163. xfintech/data/source/tushare/stock/companyprofit/tests/test_class_companyprofit_all.py +635 -0
  164. xfintech/data/source/tushare/stock/conceptcapflowdc/__init__.py +21 -0
  165. xfintech/data/source/tushare/stock/conceptcapflowdc/conceptcapflowdc.py +175 -0
  166. xfintech/data/source/tushare/stock/conceptcapflowdc/constant.py +106 -0
  167. xfintech/data/source/tushare/stock/conceptcapflowdc/tests/__init__.py +0 -0
  168. xfintech/data/source/tushare/stock/conceptcapflowdc/tests/test_class_conceptcapflowdc_all.py +568 -0
  169. xfintech/data/source/tushare/stock/conceptcapflowths/__init__.py +21 -0
  170. xfintech/data/source/tushare/stock/conceptcapflowths/conceptcapflowths.py +188 -0
  171. xfintech/data/source/tushare/stock/conceptcapflowths/constant.py +89 -0
  172. xfintech/data/source/tushare/stock/conceptcapflowths/tests/__init__.py +0 -0
  173. xfintech/data/source/tushare/stock/conceptcapflowths/tests/test_class_conceptcapflowths_all.py +516 -0
  174. xfintech/data/source/tushare/stock/dayline/__init__.py +19 -0
  175. xfintech/data/source/tushare/stock/dayline/constant.py +87 -0
  176. xfintech/data/source/tushare/stock/dayline/dayline.py +177 -0
  177. xfintech/data/source/tushare/stock/dayline/tests/__init__.py +0 -0
  178. xfintech/data/source/tushare/stock/dayline/tests/test_class_dayline_all.py +585 -0
  179. xfintech/data/source/tushare/stock/industrycapflowths/__init__.py +21 -0
  180. xfintech/data/source/tushare/stock/industrycapflowths/constant.py +89 -0
  181. xfintech/data/source/tushare/stock/industrycapflowths/industrycapflowths.py +192 -0
  182. xfintech/data/source/tushare/stock/industrycapflowths/tests/__init__.py +0 -0
  183. xfintech/data/source/tushare/stock/industrycapflowths/tests/test_class_industrycapflowths_all.py +683 -0
  184. xfintech/data/source/tushare/stock/marketindexcapflowdc/__init__.py +21 -0
  185. xfintech/data/source/tushare/stock/marketindexcapflowdc/constant.py +90 -0
  186. xfintech/data/source/tushare/stock/marketindexcapflowdc/marketindexcapflowdc.py +173 -0
  187. xfintech/data/source/tushare/stock/marketindexcapflowdc/tests/__init__.py +0 -0
  188. xfintech/data/source/tushare/stock/marketindexcapflowdc/tests/test_class_marketindexcapflowdc_all.py +793 -0
  189. xfintech/data/source/tushare/stock/monthline/__init__.py +19 -0
  190. xfintech/data/source/tushare/stock/monthline/constant.py +87 -0
  191. xfintech/data/source/tushare/stock/monthline/monthline.py +180 -0
  192. xfintech/data/source/tushare/stock/monthline/tests/__init__.py +0 -0
  193. xfintech/data/source/tushare/stock/monthline/tests/test_class_monthline_all.py +574 -0
  194. xfintech/data/source/tushare/stock/stock/__init__.py +19 -0
  195. xfintech/data/source/tushare/stock/stock/constant.py +105 -0
  196. xfintech/data/source/tushare/stock/stock/stock.py +193 -0
  197. xfintech/data/source/tushare/stock/stock/tests/__init__.py +0 -0
  198. xfintech/data/source/tushare/stock/stock/tests/test_class_stock_all.py +788 -0
  199. xfintech/data/source/tushare/stock/stockdividend/__init__.py +21 -0
  200. xfintech/data/source/tushare/stock/stockdividend/constant.py +111 -0
  201. xfintech/data/source/tushare/stock/stockdividend/stockdividend.py +180 -0
  202. xfintech/data/source/tushare/stock/stockdividend/tests/__init__.py +0 -0
  203. xfintech/data/source/tushare/stock/stockdividend/tests/test_class_stockdividend_all.py +725 -0
  204. xfintech/data/source/tushare/stock/stockinfo/__init__.py +19 -0
  205. xfintech/data/source/tushare/stock/stockinfo/constant.py +104 -0
  206. xfintech/data/source/tushare/stock/stockinfo/stockinfo.py +208 -0
  207. xfintech/data/source/tushare/stock/stockinfo/tests/__init__.py +0 -0
  208. xfintech/data/source/tushare/stock/stockinfo/tests/test_class_stockinfo_all.py +881 -0
  209. xfintech/data/source/tushare/stock/stockipo/__init__.py +19 -0
  210. xfintech/data/source/tushare/stock/stockipo/constant.py +90 -0
  211. xfintech/data/source/tushare/stock/stockipo/stockipo.py +234 -0
  212. xfintech/data/source/tushare/stock/stockipo/tests/__init__.py +1 -0
  213. xfintech/data/source/tushare/stock/stockipo/tests/test_class_stockipo_all.py +750 -0
  214. xfintech/data/source/tushare/stock/stockpledge/__init__.py +19 -0
  215. xfintech/data/source/tushare/stock/stockpledge/constant.py +72 -0
  216. xfintech/data/source/tushare/stock/stockpledge/stockpledge.py +158 -0
  217. xfintech/data/source/tushare/stock/stockpledge/tests/__init__.py +0 -0
  218. xfintech/data/source/tushare/stock/stockpledge/tests/test_class_stockpledge_all.py +664 -0
  219. xfintech/data/source/tushare/stock/stockpledgedetail/__init__.py +21 -0
  220. xfintech/data/source/tushare/stock/stockpledgedetail/constant.py +85 -0
  221. xfintech/data/source/tushare/stock/stockpledgedetail/stockpledgedetail.py +171 -0
  222. xfintech/data/source/tushare/stock/stockpledgedetail/tests/__init__.py +0 -0
  223. xfintech/data/source/tushare/stock/stockpledgedetail/tests/test_class_stockpledgedetail_all.py +112 -0
  224. xfintech/data/source/tushare/stock/stockst/__init__.py +19 -0
  225. xfintech/data/source/tushare/stock/stockst/constant.py +80 -0
  226. xfintech/data/source/tushare/stock/stockst/stockst.py +189 -0
  227. xfintech/data/source/tushare/stock/stockst/tests/__init__.py +0 -0
  228. xfintech/data/source/tushare/stock/stockst/tests/test_class_stockst_all.py +693 -0
  229. xfintech/data/source/tushare/stock/stocksuspend/__init__.py +21 -0
  230. xfintech/data/source/tushare/stock/stocksuspend/constant.py +75 -0
  231. xfintech/data/source/tushare/stock/stocksuspend/stocksuspend.py +151 -0
  232. xfintech/data/source/tushare/stock/stocksuspend/tests/__init__.py +0 -0
  233. xfintech/data/source/tushare/stock/stocksuspend/tests/test_class_stocksuspend_all.py +626 -0
  234. xfintech/data/source/tushare/stock/techindex/__init__.py +19 -0
  235. xfintech/data/source/tushare/stock/techindex/constant.py +600 -0
  236. xfintech/data/source/tushare/stock/techindex/techindex.py +314 -0
  237. xfintech/data/source/tushare/stock/techindex/tests/__init__.py +0 -0
  238. xfintech/data/source/tushare/stock/techindex/tests/test_class_techindex_all.py +576 -0
  239. xfintech/data/source/tushare/stock/tradedate/__init__.py +19 -0
  240. xfintech/data/source/tushare/stock/tradedate/constant.py +93 -0
  241. xfintech/data/source/tushare/stock/tradedate/tests/__init__.py +0 -0
  242. xfintech/data/source/tushare/stock/tradedate/tests/test_class_tradedate_all.py +947 -0
  243. xfintech/data/source/tushare/stock/tradedate/tradedate.py +234 -0
  244. xfintech/data/source/tushare/stock/weekline/__init__.py +19 -0
  245. xfintech/data/source/tushare/stock/weekline/constant.py +87 -0
  246. xfintech/data/source/tushare/stock/weekline/tests/__init__.py +0 -0
  247. xfintech/data/source/tushare/stock/weekline/tests/test_class_weekline_all.py +575 -0
  248. xfintech/data/source/tushare/stock/weekline/weekline.py +182 -0
  249. xfintech/fabric/__init__.py +18 -0
  250. xfintech/fabric/column/__init__.py +7 -0
  251. xfintech/fabric/column/info.py +202 -0
  252. xfintech/fabric/column/kind.py +102 -0
  253. xfintech/fabric/column/tests/__init__.py +0 -0
  254. xfintech/fabric/column/tests/test_class_info_all.py +207 -0
  255. xfintech/fabric/column/tests/test_class_kind_all.py +80 -0
  256. xfintech/fabric/table/__init__.py +5 -0
  257. xfintech/fabric/table/info.py +263 -0
  258. xfintech/fabric/table/tests/__init__.py +0 -0
  259. xfintech/fabric/table/tests/test_class_info_all.py +547 -0
  260. xfintech/serde/__init__.py +35 -0
  261. xfintech/serde/common/__init__.py +9 -0
  262. xfintech/serde/common/dataformat.py +78 -0
  263. xfintech/serde/common/deserialiserlike.py +38 -0
  264. xfintech/serde/common/error.py +182 -0
  265. xfintech/serde/common/serialiserlike.py +38 -0
  266. xfintech/serde/common/tests/__init__.py +1 -0
  267. xfintech/serde/common/tests/test_class_dataformat_all.py +694 -0
  268. xfintech/serde/common/tests/test_class_deserialiserlike_all.py +500 -0
  269. xfintech/serde/common/tests/test_class_errors_all.py +518 -0
  270. xfintech/serde/common/tests/test_class_serialiserlike_all.py +401 -0
  271. xfintech/serde/deserialiser/__init__.py +7 -0
  272. xfintech/serde/deserialiser/pandas.py +113 -0
  273. xfintech/serde/deserialiser/python.py +68 -0
  274. xfintech/serde/deserialiser/tests/__init__.py +1 -0
  275. xfintech/serde/deserialiser/tests/test_class_pandasdeserialiser_all.py +503 -0
  276. xfintech/serde/deserialiser/tests/test_class_pythondeserialiser_all.py +570 -0
  277. xfintech/serde/serialiser/__init__.py +7 -0
  278. xfintech/serde/serialiser/pandas.py +116 -0
  279. xfintech/serde/serialiser/python.py +71 -0
  280. xfintech/serde/serialiser/tests/__init__.py +1 -0
  281. xfintech/serde/serialiser/tests/test_class_pandasserialiser_all.py +474 -0
  282. xfintech/serde/serialiser/tests/test_class_pythonserialiser_all.py +508 -0
@@ -0,0 +1,133 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Dict, List, Optional
4
+
5
+ import pandas as pd
6
+
7
+ from xfintech.data.common.cache import Cache
8
+ from xfintech.data.common.coolant import Coolant
9
+ from xfintech.data.common.params import Params
10
+ from xfintech.data.common.retry import Retry
11
+ from xfintech.data.job import JobHouse
12
+ from xfintech.data.source.baostock.job import BaostockJob
13
+ from xfintech.data.source.baostock.session.session import Session
14
+ from xfintech.data.source.baostock.stock.sz50stock.constant import (
15
+ KEY,
16
+ NAME,
17
+ PAGINATE,
18
+ SOURCE,
19
+ TARGET,
20
+ )
21
+
22
+
23
+ @JobHouse.register(KEY, alias=KEY)
24
+ class SZ50Stock(BaostockJob):
25
+ """
26
+ 描述:
27
+ - 获取上证50成分股
28
+ - 返回上证50指数的50只成份股信息
29
+ - 每周一更新
30
+ - API文档: http://www.baostock.com/mainContent?file=sz50Stock.md
31
+ - SCALE: CrossSection
32
+ - TYPE: Static
33
+ - PAGINATE: 10000 rows / 100 pages
34
+
35
+ 属性:
36
+ - name: str, 作业名称 'sz50index'。
37
+ - key: str, 作业键 '/baostock/sz50index'。
38
+ - session: Session, Baostock会话对象。
39
+ - source: TableInfo, 源表信息(BaoStock原始格式)。
40
+ - target: TableInfo, 目标表信息(xfintech格式)。
41
+ - params: Params, 查询参数(此API无需参数)。
42
+ - coolant: Coolant, 请求冷却控制。
43
+ - paginate: Paginate, 分页控制(pagesize=10000, pagelimit=100)。
44
+ - retry: Retry, 重试策略。
45
+ - cache: Cache, 缓存管理。
46
+
47
+ 方法:
48
+ - run(): 执行作业,返回上证50成分股DataFrame。
49
+ - _run(): 内部执行逻辑,处理参数并调用API。
50
+ - transform(data): 转换数据格式,将源格式转为目标格式。
51
+ - list_codes(): 返回所有股票代码列表。
52
+ - list_names(): 返回所有股票名称列表。
53
+
54
+ 例子:
55
+ ```python
56
+ from xfintech.data.source.baostock.session import Session
57
+ from xfintech.data.source.baostock.stock.sz50index import SZ50Stock
58
+
59
+ session = Session()
60
+
61
+ # 获取上证50成分股
62
+ job = SZ50Stock(session=session)
63
+ df = job.run()
64
+
65
+ # 获取代码列表
66
+ codes = job.list_codes()
67
+ ```
68
+ """
69
+
70
+ def __init__(
71
+ self,
72
+ session: Session,
73
+ params: Optional[Params | Dict[str, Any]] = None,
74
+ coolant: Optional[Coolant | Dict[str, Any]] = None,
75
+ retry: Optional[Retry | Dict[str, Any]] = None,
76
+ cache: Optional[Cache | Dict[str, str] | bool] = None,
77
+ ) -> None:
78
+ super().__init__(
79
+ name=NAME,
80
+ key=KEY,
81
+ session=session,
82
+ source=SOURCE,
83
+ target=TARGET,
84
+ params=params,
85
+ coolant=coolant,
86
+ paginate=PAGINATE,
87
+ retry=retry,
88
+ cache=cache,
89
+ )
90
+
91
+ def _run(self) -> pd.DataFrame:
92
+ cached = self._load_cache()
93
+ if cached is not None:
94
+ return cached
95
+
96
+ payload = self.params.to_dict()
97
+ payload = self._parse_date_params(payload, keys=["date"])
98
+ # Fetch data from API
99
+ data = self._fetchall(
100
+ api=self.connection.query_sz50_stocks,
101
+ **payload,
102
+ )
103
+ result = self.transform(data)
104
+ self._save_cache(result)
105
+ return result
106
+
107
+ def transform(
108
+ self,
109
+ data: pd.DataFrame,
110
+ ) -> pd.DataFrame:
111
+ cols = self.target.list_column_names()
112
+ if data is None or data.empty:
113
+ return pd.DataFrame(columns=cols)
114
+
115
+ out = data.copy()
116
+ out["update_date"] = out["updateDate"].astype(str)
117
+ out["code"] = out["code"].astype(str)
118
+ out["name"] = out["code_name"].astype(str)
119
+
120
+ # Finalize output
121
+ out = out[cols].drop_duplicates()
122
+ out = out.sort_values(by=["code"])
123
+ out = out.reset_index(drop=True)
124
+ self.markpoint("transform[OK]")
125
+ return out
126
+
127
+ def list_codes(self) -> List[str]:
128
+ df = self.run()
129
+ return sorted(df["code"].unique().tolist())
130
+
131
+ def list_names(self) -> List[str]:
132
+ df = self.run()
133
+ return sorted(df["name"].unique().tolist())
@@ -0,0 +1 @@
1
+ """Tests for sz50index module."""
@@ -0,0 +1,397 @@
1
+ from unittest.mock import MagicMock, patch
2
+
3
+ import pandas as pd
4
+ import pytest
5
+
6
+ from xfintech.data.common.cache import Cache
7
+ from xfintech.data.common.coolant import Coolant
8
+ from xfintech.data.common.retry import Retry
9
+ from xfintech.data.source.baostock.session.session import Session
10
+ from xfintech.data.source.baostock.stock.sz50stock.constant import (
11
+ KEY,
12
+ NAME,
13
+ SOURCE,
14
+ TARGET,
15
+ )
16
+ from xfintech.data.source.baostock.stock.sz50stock.sz50stock import SZ50Stock
17
+
18
+ # ============================================================================
19
+ # Fixtures
20
+ # ============================================================================
21
+
22
+
23
+ @pytest.fixture
24
+ def mock_session():
25
+ """Create a mock Baostock session"""
26
+ session = MagicMock(spec=Session)
27
+ session._credential = None
28
+ session.id = "test1234"
29
+ session.mode = "direct"
30
+ session.relay_url = None
31
+ session.relay_secret = None
32
+ session.connected = True
33
+
34
+ # Mock the connection object
35
+ mock_connection = MagicMock()
36
+ mock_connection.query_sz50_stocks = MagicMock()
37
+ session.connection = mock_connection
38
+
39
+ return session
40
+
41
+
42
+ @pytest.fixture
43
+ def sample_source_data():
44
+ """Create sample source data in Baostock format"""
45
+ return pd.DataFrame(
46
+ {
47
+ "updateDate": ["2018-11-26"] * 10,
48
+ "code": [
49
+ "sh.600000",
50
+ "sh.600016",
51
+ "sh.600019",
52
+ "sh.600028",
53
+ "sh.600030",
54
+ "sh.600036",
55
+ "sh.600048",
56
+ "sh.600050",
57
+ "sh.600104",
58
+ "sh.600109",
59
+ ],
60
+ "code_name": [
61
+ "浦发银行",
62
+ "民生银行",
63
+ "宝钢股份",
64
+ "中国石化",
65
+ "中信证券",
66
+ "招商银行",
67
+ "保利地产",
68
+ "中国联通",
69
+ "上汽集团",
70
+ "国金证券",
71
+ ],
72
+ }
73
+ )
74
+
75
+
76
+ # ============================================================================
77
+ # Initialization Tests
78
+ # ============================================================================
79
+
80
+
81
+ def test_sz50stock_initialization_basic(mock_session):
82
+ """Test basic initialization"""
83
+ job = SZ50Stock(session=mock_session)
84
+
85
+ assert job.name == NAME
86
+ assert job.key == KEY
87
+ assert job.source == SOURCE
88
+ assert job.target == TARGET
89
+
90
+
91
+ def test_sz50stock_initialization_with_params(mock_session):
92
+ """Test initialization with params (not used for this API)"""
93
+ params = {}
94
+ job = SZ50Stock(session=mock_session, params=params)
95
+
96
+ # No specific params needed for SZ50 API
97
+ assert job.params is not None
98
+
99
+
100
+ def test_sz50stock_initialization_with_all_components(mock_session):
101
+ """Test initialization with all components"""
102
+ coolant = Coolant(interval=0.2)
103
+ retry = Retry(retry=3)
104
+ cache = Cache(path="/tmp/test_cache")
105
+
106
+ job = SZ50Stock(
107
+ session=mock_session,
108
+ coolant=coolant,
109
+ retry=retry,
110
+ cache=cache,
111
+ )
112
+
113
+ assert job.coolant.interval == 0.2
114
+ assert job.retry.retry == 3
115
+ assert job.cache is not None
116
+ assert isinstance(job.cache, Cache)
117
+
118
+
119
+ def test_sz50stock_name_and_key():
120
+ """Test name and key constants"""
121
+ assert NAME == "sz50stock"
122
+ assert KEY == "/baostock/sz50stock"
123
+
124
+
125
+ def test_sz50stock_source_schema():
126
+ """Test source schema has all required columns"""
127
+ assert SOURCE is not None
128
+ assert "上证50成分股" in SOURCE.desc
129
+
130
+ column_names = SOURCE.columns
131
+ assert "updatedate" in column_names
132
+ assert "code" in column_names
133
+ assert "code_name" in column_names
134
+
135
+
136
+ def test_sz50stock_target_schema():
137
+ """Test target schema has all required columns"""
138
+ assert TARGET is not None
139
+ assert "上证50成分股" in TARGET.desc
140
+
141
+ column_names = TARGET.columns
142
+ assert "update_date" in column_names
143
+ assert "code" in column_names
144
+ assert "name" in column_names
145
+
146
+
147
+ # ============================================================================
148
+ # Transform Tests
149
+ # ============================================================================
150
+
151
+
152
+ def test_sz50stock_transform_basic(mock_session, sample_source_data):
153
+ """Test basic data transformation"""
154
+ job = SZ50Stock(session=mock_session)
155
+ result = job.transform(sample_source_data)
156
+
157
+ assert len(result) == 10
158
+ assert "update_date" in result.columns
159
+ assert "code" in result.columns
160
+ assert "name" in result.columns
161
+ assert result.iloc[0]["code"] == "sh.600000"
162
+ assert result.iloc[0]["name"] == "浦发银行"
163
+
164
+
165
+ def test_sz50stock_transform_field_types(mock_session, sample_source_data):
166
+ """Test field type conversions"""
167
+ job = SZ50Stock(session=mock_session)
168
+ result = job.transform(sample_source_data)
169
+
170
+ # Check string fields
171
+ assert isinstance(result.iloc[0]["update_date"], str)
172
+ assert isinstance(result.iloc[0]["code"], str)
173
+ assert isinstance(result.iloc[0]["name"], str)
174
+
175
+
176
+ def test_sz50stock_transform_field_mapping(mock_session, sample_source_data):
177
+ """Test field name mappings"""
178
+ job = SZ50Stock(session=mock_session)
179
+ result = job.transform(sample_source_data)
180
+
181
+ # Verify field mappings
182
+ row = result[result["code"] == "sh.600000"].iloc[0]
183
+ assert row["update_date"] == "2018-11-26" # from updateDate
184
+ assert row["name"] == "浦发银行" # from code_name
185
+ assert row["code"] == "sh.600000"
186
+
187
+
188
+ def test_sz50stock_transform_empty_data(mock_session):
189
+ """Test transform with empty data"""
190
+ job = SZ50Stock(session=mock_session)
191
+
192
+ # Test with None
193
+ result = job.transform(None)
194
+ assert result.empty
195
+ assert len(result.columns) == len(TARGET.columns)
196
+
197
+ # Test with empty DataFrame
198
+ empty_df = pd.DataFrame()
199
+ result = job.transform(empty_df)
200
+ assert result.empty
201
+ assert len(result.columns) == len(TARGET.columns)
202
+
203
+
204
+ def test_sz50stock_transform_duplicate_removal(mock_session):
205
+ """Test that duplicates are removed"""
206
+ data = pd.DataFrame(
207
+ {
208
+ "updateDate": ["2018-11-26", "2018-11-26", "2018-11-26"],
209
+ "code": ["sh.600000", "sh.600000", "sh.600016"],
210
+ "code_name": ["浦发银行", "浦发银行", "民生银行"],
211
+ }
212
+ )
213
+ job = SZ50Stock(session=mock_session)
214
+ result = job.transform(data)
215
+
216
+ assert len(result) == 2 # Duplicates removed
217
+
218
+
219
+ def test_sz50stock_transform_sorting(mock_session):
220
+ """Test that results are sorted by code"""
221
+ data = pd.DataFrame(
222
+ {
223
+ "updateDate": ["2018-11-26", "2018-11-26", "2018-11-26"],
224
+ "code": ["sh.600050", "sh.600000", "sh.600030"],
225
+ "code_name": ["中国联通", "浦发银行", "中信证券"],
226
+ }
227
+ )
228
+ job = SZ50Stock(session=mock_session)
229
+ result = job.transform(data)
230
+
231
+ # Should be sorted by code
232
+ assert result.iloc[0]["code"] == "sh.600000"
233
+ assert result.iloc[1]["code"] == "sh.600030"
234
+ assert result.iloc[2]["code"] == "sh.600050"
235
+
236
+
237
+ # ============================================================================
238
+ # Run Tests
239
+ # ============================================================================
240
+
241
+
242
+ def test_sz50stock_run_basic(mock_session, sample_source_data):
243
+ """Test basic run functionality"""
244
+ job = SZ50Stock(session=mock_session)
245
+
246
+ # Mock _fetchall to return sample data
247
+ with patch.object(job, "_fetchall", return_value=sample_source_data):
248
+ with patch.object(job, "_load_cache", return_value=None):
249
+ with patch.object(job, "_save_cache"):
250
+ result = job._run()
251
+
252
+ assert isinstance(result, pd.DataFrame)
253
+ assert len(result) == 10
254
+ assert "update_date" in result.columns
255
+ assert "code" in result.columns
256
+ assert "name" in result.columns
257
+
258
+
259
+ def test_sz50stock_run_calls_api(mock_session, sample_source_data):
260
+ """Test that run calls the correct API"""
261
+ job = SZ50Stock(session=mock_session)
262
+
263
+ with patch.object(job, "_fetchall", return_value=sample_source_data) as mock_fetchall:
264
+ with patch.object(job, "_load_cache", return_value=None):
265
+ with patch.object(job, "_save_cache"):
266
+ job._run()
267
+
268
+ # Verify API was called
269
+ mock_fetchall.assert_called_once()
270
+ call_kwargs = mock_fetchall.call_args[1]
271
+ assert call_kwargs["api"] == job.connection.query_sz50_stocks
272
+
273
+
274
+ def test_sz50stock_run_with_cache(mock_session, sample_source_data):
275
+ """Test that cache is used when available"""
276
+ job = SZ50Stock(session=mock_session)
277
+ cached_data = sample_source_data.copy()
278
+
279
+ with patch.object(job, "_load_cache", return_value=cached_data):
280
+ with patch.object(job, "_fetchall") as mock_fetchall:
281
+ result = job._run()
282
+
283
+ # Should return cached data without calling API
284
+ mock_fetchall.assert_not_called()
285
+ assert len(result) == 10
286
+
287
+
288
+ # ============================================================================
289
+ # List Methods Tests
290
+ # ============================================================================
291
+
292
+
293
+ def test_sz50stock_list_codes(mock_session, sample_source_data):
294
+ """Test list_codes method"""
295
+ job = SZ50Stock(session=mock_session)
296
+
297
+ with patch.object(job, "run", return_value=job.transform(sample_source_data)):
298
+ codes = job.list_codes()
299
+
300
+ assert isinstance(codes, list)
301
+ assert len(codes) == 10
302
+ assert "sh.600000" in codes
303
+ assert "sh.600109" in codes
304
+ # Should be sorted
305
+ assert codes == sorted(codes)
306
+
307
+
308
+ def test_sz50stock_list_names(mock_session, sample_source_data):
309
+ """Test list_names method"""
310
+ job = SZ50Stock(session=mock_session)
311
+
312
+ with patch.object(job, "run", return_value=job.transform(sample_source_data)):
313
+ names = job.list_names()
314
+
315
+ assert isinstance(names, list)
316
+ assert len(names) == 10
317
+ assert "浦发银行" in names
318
+ assert "国金证券" in names
319
+ # Should be sorted
320
+ assert names == sorted(names)
321
+
322
+
323
+ def test_sz50stock_list_codes_with_duplicates(mock_session):
324
+ """Test list_codes with duplicate codes"""
325
+ data = pd.DataFrame(
326
+ {
327
+ "updateDate": ["2018-11-26", "2018-11-26", "2018-11-26"],
328
+ "code": ["sh.600000", "sh.600000", "sh.600016"],
329
+ "code_name": ["浦发银行", "浦发银行", "民生银行"],
330
+ }
331
+ )
332
+ job = SZ50Stock(session=mock_session)
333
+ transformed = job.transform(data)
334
+
335
+ with patch.object(job, "run", return_value=transformed):
336
+ codes = job.list_codes()
337
+
338
+ # Should return unique codes only
339
+ assert len(codes) == 2
340
+ assert "sh.600000" in codes
341
+ assert "sh.600016" in codes
342
+
343
+
344
+ # ============================================================================
345
+ # Integration Tests
346
+ # ============================================================================
347
+
348
+
349
+ def test_sz50stock_full_workflow(mock_session, sample_source_data):
350
+ """Test full workflow from initialization to result"""
351
+ job = SZ50Stock(session=mock_session)
352
+
353
+ with patch.object(job, "_fetchall", return_value=sample_source_data):
354
+ with patch.object(job, "_load_cache", return_value=None):
355
+ with patch.object(job, "_save_cache"):
356
+ result = job._run()
357
+
358
+ # Verify result structure
359
+ assert isinstance(result, pd.DataFrame)
360
+ assert len(result) == 10
361
+ assert "update_date" in result.columns
362
+ assert "code" in result.columns
363
+ assert "name" in result.columns
364
+
365
+ # Verify data types
366
+ assert isinstance(result.iloc[0]["update_date"], str)
367
+ assert isinstance(result.iloc[0]["code"], str)
368
+ assert isinstance(result.iloc[0]["name"], str)
369
+
370
+ # Verify sorting
371
+ codes = result["code"].tolist()
372
+ assert codes == sorted(codes)
373
+
374
+
375
+ def test_sz50stock_same_update_date(mock_session, sample_source_data):
376
+ """Test that all stocks have the same update date"""
377
+ job = SZ50Stock(session=mock_session)
378
+ result = job.transform(sample_source_data)
379
+
380
+ # All stocks should have the same update date
381
+ unique_dates = result["update_date"].unique()
382
+ assert len(unique_dates) == 1
383
+ assert unique_dates[0] == "2018-11-26"
384
+
385
+
386
+ def test_sz50stock_code_format(mock_session, sample_source_data):
387
+ """Test that codes follow sh.XXXXXX format"""
388
+ job = SZ50Stock(session=mock_session)
389
+ result = job.transform(sample_source_data)
390
+
391
+ # All codes should start with "sh."
392
+ for code in result["code"]:
393
+ assert code.startswith("sh.")
394
+ assert len(code) == 9 # sh. + 6 digits
395
+
396
+
397
+ # ============================================================================
@@ -0,0 +1,19 @@
1
+ from __future__ import annotations
2
+
3
+ from xfintech.data.source.tushare.stock.tradedate.constant import (
4
+ KEY,
5
+ NAME,
6
+ PAGINATE,
7
+ SOURCE,
8
+ TARGET,
9
+ )
10
+ from xfintech.data.source.tushare.stock.tradedate.tradedate import TradeDate
11
+
12
+ __all__ = [
13
+ "TradeDate",
14
+ "KEY",
15
+ "NAME",
16
+ "PAGINATE",
17
+ "SOURCE",
18
+ "TARGET",
19
+ ]
@@ -0,0 +1,72 @@
1
+ from __future__ import annotations
2
+
3
+ from xfintech.data.common.paginate import Paginate
4
+ from xfintech.fabric.column.info import ColumnInfo
5
+ from xfintech.fabric.column.kind import ColumnKind
6
+ from xfintech.fabric.table.info import TableInfo
7
+
8
+ PROVIDER = "baostock"
9
+ SOURCE_NAME = "query_trade_dates"
10
+ URL = "http://www.baostock.com/mainContent?file=stockKData.md"
11
+ ARGS = {
12
+ "start_date": {
13
+ "type": ColumnKind.STRING,
14
+ "required": "N",
15
+ "desc": "开始日期: YYYY-MM-DD",
16
+ },
17
+ "end_date": {
18
+ "type": ColumnKind.STRING,
19
+ "required": "N",
20
+ "desc": "结束日期: YYYY-MM-DD",
21
+ },
22
+ "year": {
23
+ "type": ColumnKind.STRING,
24
+ "required": "N",
25
+ "desc": "年份(YYYY)",
26
+ },
27
+ }
28
+
29
+ # Exported constants
30
+ NAME = "tradedate"
31
+ KEY = "/baostock/tradedate"
32
+ PAGINATE = Paginate(
33
+ pagesize=10000,
34
+ pagelimit=100,
35
+ )
36
+ SOURCE = TableInfo(
37
+ desc="交易日历数据,包括交易所的交易日期和非交易日期",
38
+ meta={
39
+ "provider": PROVIDER,
40
+ "source": SOURCE_NAME,
41
+ "url": URL,
42
+ "args": ARGS,
43
+ "type": "static",
44
+ "scale": "crosssection",
45
+ },
46
+ columns=[
47
+ ColumnInfo(name="calendar_date", kind=ColumnKind.STRING, desc="交易日期:YYYY-MM-DD"),
48
+ ColumnInfo(name="is_trading_day", kind=ColumnKind.BOOLEAN, desc="是否交易"),
49
+ ],
50
+ )
51
+ TARGET = TableInfo(
52
+ desc="交易日历数据,包括日期信息和交易状态",
53
+ meta={
54
+ "key": KEY,
55
+ "name": NAME,
56
+ "type": "static",
57
+ "scale": "crosssection",
58
+ },
59
+ columns=[
60
+ ColumnInfo(name="datecode", kind=ColumnKind.STRING, desc="日期代码:YYYYMMDD"),
61
+ ColumnInfo(name="date", kind=ColumnKind.STRING, desc="日期:YYYY-MM-DD"),
62
+ ColumnInfo(name="exchange", kind=ColumnKind.STRING, desc="交易所"),
63
+ ColumnInfo(name="previous", kind=ColumnKind.STRING, desc="前一个交易日"),
64
+ ColumnInfo(name="is_open", kind=ColumnKind.BOOLEAN, desc="是否交易日"),
65
+ ColumnInfo(name="year", kind=ColumnKind.INTEGER, desc="年份"),
66
+ ColumnInfo(name="month", kind=ColumnKind.INTEGER, desc="月份"),
67
+ ColumnInfo(name="day", kind=ColumnKind.INTEGER, desc="日"),
68
+ ColumnInfo(name="week", kind=ColumnKind.INTEGER, desc="周数"),
69
+ ColumnInfo(name="weekday", kind=ColumnKind.STRING, desc="星期几"),
70
+ ColumnInfo(name="quarter", kind=ColumnKind.INTEGER, desc="季度"),
71
+ ],
72
+ )