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.
- lib_x17_fintech-2.1.3.dist-info/METADATA +633 -0
- lib_x17_fintech-2.1.3.dist-info/RECORD +282 -0
- lib_x17_fintech-2.1.3.dist-info/WHEEL +5 -0
- lib_x17_fintech-2.1.3.dist-info/licenses/LICENSE +1 -0
- lib_x17_fintech-2.1.3.dist-info/top_level.txt +1 -0
- xfintech/__init__.py +0 -0
- xfintech/connect/__init__.py +18 -0
- xfintech/connect/artifact/__init__.py +5 -0
- xfintech/connect/artifact/artifact.py +168 -0
- xfintech/connect/artifact/tests/__init__.py +3 -0
- xfintech/connect/artifact/tests/test_class_artifact_all.py +564 -0
- xfintech/connect/common/__init__.py +12 -0
- xfintech/connect/common/connect.py +49 -0
- xfintech/connect/common/connectref.py +119 -0
- xfintech/connect/common/error.py +62 -0
- xfintech/connect/common/tests/__init__.py +1 -0
- xfintech/connect/common/tests/test_class_connectlike_all.py +544 -0
- xfintech/connect/common/tests/test_class_connectref_all.py +586 -0
- xfintech/connect/common/tests/test_class_errors_all.py +524 -0
- xfintech/connect/instance/__init__.py +7 -0
- xfintech/connect/instance/macos.py +121 -0
- xfintech/connect/instance/s3.py +176 -0
- xfintech/connect/instance/tests/__init__.py +1 -0
- xfintech/connect/instance/tests/test_class_macosconnect_all.py +692 -0
- xfintech/connect/instance/tests/test_class_s3connect_all.py +603 -0
- xfintech/data/__init__.py +20 -0
- xfintech/data/common/__init__.py +15 -0
- xfintech/data/common/cache.py +186 -0
- xfintech/data/common/coolant.py +171 -0
- xfintech/data/common/metric.py +138 -0
- xfintech/data/common/paginate.py +132 -0
- xfintech/data/common/params.py +162 -0
- xfintech/data/common/retry.py +201 -0
- xfintech/data/common/tests/__init__.py +1 -0
- xfintech/data/common/tests/test_class_cache_all.py +681 -0
- xfintech/data/common/tests/test_class_coolant_all.py +534 -0
- xfintech/data/common/tests/test_class_metric_all.py +705 -0
- xfintech/data/common/tests/test_class_paginate_all.py +508 -0
- xfintech/data/common/tests/test_class_params_all.py +891 -0
- xfintech/data/common/tests/test_class_retry_all.py +714 -0
- xfintech/data/job/__init__.py +17 -0
- xfintech/data/job/errors.py +112 -0
- xfintech/data/job/house.py +156 -0
- xfintech/data/job/job.py +247 -0
- xfintech/data/job/joblike.py +47 -0
- xfintech/data/job/tests/__init__.py +1 -0
- xfintech/data/job/tests/test_class_errors_all.py +275 -0
- xfintech/data/job/tests/test_class_house_all.py +801 -0
- xfintech/data/job/tests/test_class_job_all.py +684 -0
- xfintech/data/job/tests/test_class_joblike_all.py +482 -0
- xfintech/data/relay/__init__.py +7 -0
- xfintech/data/relay/client.py +114 -0
- xfintech/data/relay/clientlike.py +45 -0
- xfintech/data/relay/tests/test_class_relayclient_all.py +484 -0
- xfintech/data/relay/tests/test_class_relayclientlike_all.py +500 -0
- xfintech/data/source/__init__.py +7 -0
- xfintech/data/source/baostock/__init__.py +21 -0
- xfintech/data/source/baostock/job/__init__.py +5 -0
- xfintech/data/source/baostock/job/job.py +217 -0
- xfintech/data/source/baostock/job/tests/__init__.py +0 -0
- xfintech/data/source/baostock/job/tests/test_class_baostockjob_all.py +547 -0
- xfintech/data/source/baostock/session/__init__.py +8 -0
- xfintech/data/source/baostock/session/relay.py +223 -0
- xfintech/data/source/baostock/session/session.py +241 -0
- xfintech/data/source/baostock/session/tests/__init__.py +0 -0
- xfintech/data/source/baostock/session/tests/test_class_relay_all.py +694 -0
- xfintech/data/source/baostock/session/tests/test_class_session_all.py +505 -0
- xfintech/data/source/baostock/stock/__init__.py +0 -0
- xfintech/data/source/baostock/stock/hs300stock/__init__.py +3 -0
- xfintech/data/source/baostock/stock/hs300stock/constant.py +49 -0
- xfintech/data/source/baostock/stock/hs300stock/hs300stock.py +133 -0
- xfintech/data/source/baostock/stock/hs300stock/tests/__init__.py +1 -0
- xfintech/data/source/baostock/stock/hs300stock/tests/test_class_hs300index_all.py +413 -0
- xfintech/data/source/baostock/stock/minuteline/__init__.py +19 -0
- xfintech/data/source/baostock/stock/minuteline/constant.py +89 -0
- xfintech/data/source/baostock/stock/minuteline/minuteline.py +163 -0
- xfintech/data/source/baostock/stock/minuteline/tests/__init__.py +0 -0
- xfintech/data/source/baostock/stock/minuteline/tests/test_class_minuteline_all.py +582 -0
- xfintech/data/source/baostock/stock/stock/__init__.py +19 -0
- xfintech/data/source/baostock/stock/stock/constant.py +55 -0
- xfintech/data/source/baostock/stock/stock/stock.py +149 -0
- xfintech/data/source/baostock/stock/stock/tests/__init__.py +0 -0
- xfintech/data/source/baostock/stock/stock/tests/test_class_stock_all.py +508 -0
- xfintech/data/source/baostock/stock/stockinfo/__init__.py +5 -0
- xfintech/data/source/baostock/stock/stockinfo/constant.py +66 -0
- xfintech/data/source/baostock/stock/stockinfo/stockinfo.py +176 -0
- xfintech/data/source/baostock/stock/stockinfo/tests/__init__.py +1 -0
- xfintech/data/source/baostock/stock/stockinfo/tests/test_class_stockinfo_all.py +617 -0
- xfintech/data/source/baostock/stock/sz50stock/__init__.py +3 -0
- xfintech/data/source/baostock/stock/sz50stock/constant.py +49 -0
- xfintech/data/source/baostock/stock/sz50stock/sz50stock.py +133 -0
- xfintech/data/source/baostock/stock/sz50stock/tests/__init__.py +1 -0
- xfintech/data/source/baostock/stock/sz50stock/tests/test_class_sz50stock_all.py +397 -0
- xfintech/data/source/baostock/stock/tradedate/__init__.py +19 -0
- xfintech/data/source/baostock/stock/tradedate/constant.py +72 -0
- xfintech/data/source/baostock/stock/tradedate/tests/__init__.py +0 -0
- xfintech/data/source/baostock/stock/tradedate/tests/test_class_tradedate_all.py +695 -0
- xfintech/data/source/baostock/stock/tradedate/tradedate.py +208 -0
- xfintech/data/source/baostock/stock/zz500stock/__init__.py +3 -0
- xfintech/data/source/baostock/stock/zz500stock/constant.py +55 -0
- xfintech/data/source/baostock/stock/zz500stock/tests/__init__.py +1 -0
- xfintech/data/source/baostock/stock/zz500stock/tests/test_class_zz500stock_all.py +421 -0
- xfintech/data/source/baostock/stock/zz500stock/zz500stock.py +133 -0
- xfintech/data/source/tushare/__init__.py +61 -0
- xfintech/data/source/tushare/job/__init__.py +5 -0
- xfintech/data/source/tushare/job/job.py +257 -0
- xfintech/data/source/tushare/job/tests/test_class_tusharejob_all.py +589 -0
- xfintech/data/source/tushare/session/__init__.py +5 -0
- xfintech/data/source/tushare/session/relay.py +231 -0
- xfintech/data/source/tushare/session/session.py +239 -0
- xfintech/data/source/tushare/session/tests/test_class_relay_all.py +719 -0
- xfintech/data/source/tushare/session/tests/test_class_session_all.py +705 -0
- xfintech/data/source/tushare/stock/__init__.py +55 -0
- xfintech/data/source/tushare/stock/adjfactor/__init__.py +19 -0
- xfintech/data/source/tushare/stock/adjfactor/adjfactor.py +150 -0
- xfintech/data/source/tushare/stock/adjfactor/constant.py +71 -0
- xfintech/data/source/tushare/stock/adjfactor/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/adjfactor/tests/test_class_adjfactor_all.py +372 -0
- xfintech/data/source/tushare/stock/capflow/__init__.py +19 -0
- xfintech/data/source/tushare/stock/capflow/capflow.py +171 -0
- xfintech/data/source/tushare/stock/capflow/constant.py +105 -0
- xfintech/data/source/tushare/stock/capflow/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/capflow/tests/test_class_capflow_all.py +589 -0
- xfintech/data/source/tushare/stock/capflowdc/__init__.py +19 -0
- xfintech/data/source/tushare/stock/capflowdc/capflowdc.py +167 -0
- xfintech/data/source/tushare/stock/capflowdc/constant.py +95 -0
- xfintech/data/source/tushare/stock/capflowdc/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/capflowdc/tests/test_class_capflowdc_all.py +814 -0
- xfintech/data/source/tushare/stock/capflowths/__init__.py +19 -0
- xfintech/data/source/tushare/stock/capflowths/capflowths.py +173 -0
- xfintech/data/source/tushare/stock/capflowths/constant.py +92 -0
- xfintech/data/source/tushare/stock/capflowths/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/capflowths/tests/test_class_capflowths_all.py +551 -0
- xfintech/data/source/tushare/stock/company/__init__.py +19 -0
- xfintech/data/source/tushare/stock/company/company.py +188 -0
- xfintech/data/source/tushare/stock/company/constant.py +92 -0
- xfintech/data/source/tushare/stock/company/tests/__init__.py +1 -0
- xfintech/data/source/tushare/stock/company/tests/test_class_company_all.py +829 -0
- xfintech/data/source/tushare/stock/companybusiness/__init__.py +21 -0
- xfintech/data/source/tushare/stock/companybusiness/companybusiness.py +183 -0
- xfintech/data/source/tushare/stock/companybusiness/constant.py +91 -0
- xfintech/data/source/tushare/stock/companybusiness/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/companybusiness/tests/test_class_companybusiness_all.py +633 -0
- xfintech/data/source/tushare/stock/companycashflow/__init__.py +21 -0
- xfintech/data/source/tushare/stock/companycashflow/companycashflow.py +277 -0
- xfintech/data/source/tushare/stock/companycashflow/constant.py +293 -0
- xfintech/data/source/tushare/stock/companycashflow/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/companycashflow/tests/test_class_companycashflow_all.py +619 -0
- xfintech/data/source/tushare/stock/companydebt/__init__.py +19 -0
- xfintech/data/source/tushare/stock/companydebt/companydebt.py +339 -0
- xfintech/data/source/tushare/stock/companydebt/constant.py +403 -0
- xfintech/data/source/tushare/stock/companydebt/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/companydebt/tests/test_class_companydebt_all.py +655 -0
- xfintech/data/source/tushare/stock/companyoverview/__init__.py +21 -0
- xfintech/data/source/tushare/stock/companyoverview/companyoverview.py +214 -0
- xfintech/data/source/tushare/stock/companyoverview/constant.py +152 -0
- xfintech/data/source/tushare/stock/companyoverview/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/companyoverview/tests/test_class_companyoverview_all.py +647 -0
- xfintech/data/source/tushare/stock/companyprofit/__init__.py +21 -0
- xfintech/data/source/tushare/stock/companyprofit/companyprofit.py +272 -0
- xfintech/data/source/tushare/stock/companyprofit/constant.py +259 -0
- xfintech/data/source/tushare/stock/companyprofit/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/companyprofit/tests/test_class_companyprofit_all.py +635 -0
- xfintech/data/source/tushare/stock/conceptcapflowdc/__init__.py +21 -0
- xfintech/data/source/tushare/stock/conceptcapflowdc/conceptcapflowdc.py +175 -0
- xfintech/data/source/tushare/stock/conceptcapflowdc/constant.py +106 -0
- xfintech/data/source/tushare/stock/conceptcapflowdc/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/conceptcapflowdc/tests/test_class_conceptcapflowdc_all.py +568 -0
- xfintech/data/source/tushare/stock/conceptcapflowths/__init__.py +21 -0
- xfintech/data/source/tushare/stock/conceptcapflowths/conceptcapflowths.py +188 -0
- xfintech/data/source/tushare/stock/conceptcapflowths/constant.py +89 -0
- xfintech/data/source/tushare/stock/conceptcapflowths/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/conceptcapflowths/tests/test_class_conceptcapflowths_all.py +516 -0
- xfintech/data/source/tushare/stock/dayline/__init__.py +19 -0
- xfintech/data/source/tushare/stock/dayline/constant.py +87 -0
- xfintech/data/source/tushare/stock/dayline/dayline.py +177 -0
- xfintech/data/source/tushare/stock/dayline/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/dayline/tests/test_class_dayline_all.py +585 -0
- xfintech/data/source/tushare/stock/industrycapflowths/__init__.py +21 -0
- xfintech/data/source/tushare/stock/industrycapflowths/constant.py +89 -0
- xfintech/data/source/tushare/stock/industrycapflowths/industrycapflowths.py +192 -0
- xfintech/data/source/tushare/stock/industrycapflowths/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/industrycapflowths/tests/test_class_industrycapflowths_all.py +683 -0
- xfintech/data/source/tushare/stock/marketindexcapflowdc/__init__.py +21 -0
- xfintech/data/source/tushare/stock/marketindexcapflowdc/constant.py +90 -0
- xfintech/data/source/tushare/stock/marketindexcapflowdc/marketindexcapflowdc.py +173 -0
- xfintech/data/source/tushare/stock/marketindexcapflowdc/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/marketindexcapflowdc/tests/test_class_marketindexcapflowdc_all.py +793 -0
- xfintech/data/source/tushare/stock/monthline/__init__.py +19 -0
- xfintech/data/source/tushare/stock/monthline/constant.py +87 -0
- xfintech/data/source/tushare/stock/monthline/monthline.py +180 -0
- xfintech/data/source/tushare/stock/monthline/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/monthline/tests/test_class_monthline_all.py +574 -0
- xfintech/data/source/tushare/stock/stock/__init__.py +19 -0
- xfintech/data/source/tushare/stock/stock/constant.py +105 -0
- xfintech/data/source/tushare/stock/stock/stock.py +193 -0
- xfintech/data/source/tushare/stock/stock/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stock/tests/test_class_stock_all.py +788 -0
- xfintech/data/source/tushare/stock/stockdividend/__init__.py +21 -0
- xfintech/data/source/tushare/stock/stockdividend/constant.py +111 -0
- xfintech/data/source/tushare/stock/stockdividend/stockdividend.py +180 -0
- xfintech/data/source/tushare/stock/stockdividend/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stockdividend/tests/test_class_stockdividend_all.py +725 -0
- xfintech/data/source/tushare/stock/stockinfo/__init__.py +19 -0
- xfintech/data/source/tushare/stock/stockinfo/constant.py +104 -0
- xfintech/data/source/tushare/stock/stockinfo/stockinfo.py +208 -0
- xfintech/data/source/tushare/stock/stockinfo/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stockinfo/tests/test_class_stockinfo_all.py +881 -0
- xfintech/data/source/tushare/stock/stockipo/__init__.py +19 -0
- xfintech/data/source/tushare/stock/stockipo/constant.py +90 -0
- xfintech/data/source/tushare/stock/stockipo/stockipo.py +234 -0
- xfintech/data/source/tushare/stock/stockipo/tests/__init__.py +1 -0
- xfintech/data/source/tushare/stock/stockipo/tests/test_class_stockipo_all.py +750 -0
- xfintech/data/source/tushare/stock/stockpledge/__init__.py +19 -0
- xfintech/data/source/tushare/stock/stockpledge/constant.py +72 -0
- xfintech/data/source/tushare/stock/stockpledge/stockpledge.py +158 -0
- xfintech/data/source/tushare/stock/stockpledge/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stockpledge/tests/test_class_stockpledge_all.py +664 -0
- xfintech/data/source/tushare/stock/stockpledgedetail/__init__.py +21 -0
- xfintech/data/source/tushare/stock/stockpledgedetail/constant.py +85 -0
- xfintech/data/source/tushare/stock/stockpledgedetail/stockpledgedetail.py +171 -0
- xfintech/data/source/tushare/stock/stockpledgedetail/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stockpledgedetail/tests/test_class_stockpledgedetail_all.py +112 -0
- xfintech/data/source/tushare/stock/stockst/__init__.py +19 -0
- xfintech/data/source/tushare/stock/stockst/constant.py +80 -0
- xfintech/data/source/tushare/stock/stockst/stockst.py +189 -0
- xfintech/data/source/tushare/stock/stockst/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stockst/tests/test_class_stockst_all.py +693 -0
- xfintech/data/source/tushare/stock/stocksuspend/__init__.py +21 -0
- xfintech/data/source/tushare/stock/stocksuspend/constant.py +75 -0
- xfintech/data/source/tushare/stock/stocksuspend/stocksuspend.py +151 -0
- xfintech/data/source/tushare/stock/stocksuspend/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stocksuspend/tests/test_class_stocksuspend_all.py +626 -0
- xfintech/data/source/tushare/stock/techindex/__init__.py +19 -0
- xfintech/data/source/tushare/stock/techindex/constant.py +600 -0
- xfintech/data/source/tushare/stock/techindex/techindex.py +314 -0
- xfintech/data/source/tushare/stock/techindex/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/techindex/tests/test_class_techindex_all.py +576 -0
- xfintech/data/source/tushare/stock/tradedate/__init__.py +19 -0
- xfintech/data/source/tushare/stock/tradedate/constant.py +93 -0
- xfintech/data/source/tushare/stock/tradedate/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/tradedate/tests/test_class_tradedate_all.py +947 -0
- xfintech/data/source/tushare/stock/tradedate/tradedate.py +234 -0
- xfintech/data/source/tushare/stock/weekline/__init__.py +19 -0
- xfintech/data/source/tushare/stock/weekline/constant.py +87 -0
- xfintech/data/source/tushare/stock/weekline/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/weekline/tests/test_class_weekline_all.py +575 -0
- xfintech/data/source/tushare/stock/weekline/weekline.py +182 -0
- xfintech/fabric/__init__.py +18 -0
- xfintech/fabric/column/__init__.py +7 -0
- xfintech/fabric/column/info.py +202 -0
- xfintech/fabric/column/kind.py +102 -0
- xfintech/fabric/column/tests/__init__.py +0 -0
- xfintech/fabric/column/tests/test_class_info_all.py +207 -0
- xfintech/fabric/column/tests/test_class_kind_all.py +80 -0
- xfintech/fabric/table/__init__.py +5 -0
- xfintech/fabric/table/info.py +263 -0
- xfintech/fabric/table/tests/__init__.py +0 -0
- xfintech/fabric/table/tests/test_class_info_all.py +547 -0
- xfintech/serde/__init__.py +35 -0
- xfintech/serde/common/__init__.py +9 -0
- xfintech/serde/common/dataformat.py +78 -0
- xfintech/serde/common/deserialiserlike.py +38 -0
- xfintech/serde/common/error.py +182 -0
- xfintech/serde/common/serialiserlike.py +38 -0
- xfintech/serde/common/tests/__init__.py +1 -0
- xfintech/serde/common/tests/test_class_dataformat_all.py +694 -0
- xfintech/serde/common/tests/test_class_deserialiserlike_all.py +500 -0
- xfintech/serde/common/tests/test_class_errors_all.py +518 -0
- xfintech/serde/common/tests/test_class_serialiserlike_all.py +401 -0
- xfintech/serde/deserialiser/__init__.py +7 -0
- xfintech/serde/deserialiser/pandas.py +113 -0
- xfintech/serde/deserialiser/python.py +68 -0
- xfintech/serde/deserialiser/tests/__init__.py +1 -0
- xfintech/serde/deserialiser/tests/test_class_pandasdeserialiser_all.py +503 -0
- xfintech/serde/deserialiser/tests/test_class_pythondeserialiser_all.py +570 -0
- xfintech/serde/serialiser/__init__.py +7 -0
- xfintech/serde/serialiser/pandas.py +116 -0
- xfintech/serde/serialiser/python.py +71 -0
- xfintech/serde/serialiser/tests/__init__.py +1 -0
- xfintech/serde/serialiser/tests/test_class_pandasserialiser_all.py +474 -0
- xfintech/serde/serialiser/tests/test_class_pythonserialiser_all.py +508 -0
|
@@ -0,0 +1,85 @@
|
|
|
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 = "tushare"
|
|
9
|
+
SOURCE_NAME = "pledge_detail"
|
|
10
|
+
URL = "https://tushare.pro/document/2?doc_id=111"
|
|
11
|
+
ARGS = {
|
|
12
|
+
"ts_code": {
|
|
13
|
+
"type": ColumnKind.STRING,
|
|
14
|
+
"required": "Y",
|
|
15
|
+
"desc": "股票代码",
|
|
16
|
+
},
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
# Exported constants
|
|
20
|
+
NAME = "stockpledgedetail"
|
|
21
|
+
KEY = "/tushare/stockpledgedetail"
|
|
22
|
+
PAGINATE = Paginate(
|
|
23
|
+
pagesize=1000,
|
|
24
|
+
pagelimit=1000,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
SOURCE = TableInfo(
|
|
28
|
+
desc="股权质押明细数据(Tushare格式)",
|
|
29
|
+
meta={
|
|
30
|
+
"provider": PROVIDER,
|
|
31
|
+
"source": SOURCE_NAME,
|
|
32
|
+
"url": URL,
|
|
33
|
+
"args": ARGS,
|
|
34
|
+
"type": "partitioned",
|
|
35
|
+
"scale": "individual",
|
|
36
|
+
},
|
|
37
|
+
name=SOURCE_NAME,
|
|
38
|
+
columns=[
|
|
39
|
+
ColumnInfo(name="ts_code", kind=ColumnKind.STRING, desc="TS股票代码"),
|
|
40
|
+
ColumnInfo(name="ann_date", kind=ColumnKind.STRING, desc="公告日期"),
|
|
41
|
+
ColumnInfo(name="holder_name", kind=ColumnKind.STRING, desc="股东名称"),
|
|
42
|
+
ColumnInfo(name="pledge_amount", kind=ColumnKind.FLOAT, desc="质押数量(万股)"),
|
|
43
|
+
ColumnInfo(name="start_date", kind=ColumnKind.STRING, desc="质押开始日期"),
|
|
44
|
+
ColumnInfo(name="end_date", kind=ColumnKind.STRING, desc="质押结束日期"),
|
|
45
|
+
ColumnInfo(name="is_release", kind=ColumnKind.STRING, desc="是否已解押"),
|
|
46
|
+
ColumnInfo(name="release_date", kind=ColumnKind.STRING, desc="解押日期"),
|
|
47
|
+
ColumnInfo(name="pledgor", kind=ColumnKind.STRING, desc="质押方"),
|
|
48
|
+
ColumnInfo(name="holding_amount", kind=ColumnKind.FLOAT, desc="持股总数(万股)"),
|
|
49
|
+
ColumnInfo(name="pledged_amount", kind=ColumnKind.FLOAT, desc="质押总数(万股)"),
|
|
50
|
+
ColumnInfo(name="p_total_ratio", kind=ColumnKind.FLOAT, desc="本次质押占总股本比例"),
|
|
51
|
+
ColumnInfo(name="h_total_ratio", kind=ColumnKind.FLOAT, desc="持股总数占总股本比例"),
|
|
52
|
+
ColumnInfo(name="is_buyback", kind=ColumnKind.STRING, desc="是否回购"),
|
|
53
|
+
],
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
TARGET = TableInfo(
|
|
57
|
+
desc="股权质押明细数据(标准格式)",
|
|
58
|
+
meta={
|
|
59
|
+
"key": KEY,
|
|
60
|
+
"name": NAME,
|
|
61
|
+
"type": "partitioned",
|
|
62
|
+
"scale": "individual",
|
|
63
|
+
},
|
|
64
|
+
name=NAME,
|
|
65
|
+
columns=[
|
|
66
|
+
ColumnInfo(name="code", kind=ColumnKind.STRING, desc="股票代码"),
|
|
67
|
+
ColumnInfo(name="ann_date", kind=ColumnKind.STRING, desc="公告日期"),
|
|
68
|
+
ColumnInfo(name="ann_datecode", kind=ColumnKind.STRING, desc="公告日期代码"),
|
|
69
|
+
ColumnInfo(name="holder_name", kind=ColumnKind.STRING, desc="股东名称"),
|
|
70
|
+
ColumnInfo(name="pledge_amount", kind=ColumnKind.FLOAT, desc="质押数量(万股)"),
|
|
71
|
+
ColumnInfo(name="start_date", kind=ColumnKind.STRING, desc="质押开始日期"),
|
|
72
|
+
ColumnInfo(name="start_datecode", kind=ColumnKind.STRING, desc="质押开始日期代码"),
|
|
73
|
+
ColumnInfo(name="end_date", kind=ColumnKind.STRING, desc="质押结束日期"),
|
|
74
|
+
ColumnInfo(name="end_datecode", kind=ColumnKind.STRING, desc="质押结束日期代码"),
|
|
75
|
+
ColumnInfo(name="is_release", kind=ColumnKind.STRING, desc="是否已解押"),
|
|
76
|
+
ColumnInfo(name="release_date", kind=ColumnKind.STRING, desc="解押日期"),
|
|
77
|
+
ColumnInfo(name="release_datecode", kind=ColumnKind.STRING, desc="解押日期代码"),
|
|
78
|
+
ColumnInfo(name="pledgor", kind=ColumnKind.STRING, desc="质押方"),
|
|
79
|
+
ColumnInfo(name="holding_amount", kind=ColumnKind.FLOAT, desc="持股总数(万股)"),
|
|
80
|
+
ColumnInfo(name="pledged_amount", kind=ColumnKind.FLOAT, desc="质押总数(万股)"),
|
|
81
|
+
ColumnInfo(name="p_total_ratio", kind=ColumnKind.FLOAT, desc="本次质押占总股本比例"),
|
|
82
|
+
ColumnInfo(name="h_total_ratio", kind=ColumnKind.FLOAT, desc="持股总数占总股本比例"),
|
|
83
|
+
ColumnInfo(name="is_buyback", kind=ColumnKind.STRING, desc="是否回购"),
|
|
84
|
+
],
|
|
85
|
+
)
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, 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.tushare.job import TushareJob
|
|
13
|
+
from xfintech.data.source.tushare.session.session import Session
|
|
14
|
+
from xfintech.data.source.tushare.stock.stockpledgedetail.constant import (
|
|
15
|
+
KEY,
|
|
16
|
+
NAME,
|
|
17
|
+
PAGINATE,
|
|
18
|
+
SOURCE,
|
|
19
|
+
TARGET,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@JobHouse.register(KEY, alias=KEY)
|
|
24
|
+
class StockPledgeDetail(TushareJob):
|
|
25
|
+
"""
|
|
26
|
+
描述:
|
|
27
|
+
- 获取A股上市公司股权质押明细数据
|
|
28
|
+
- API文档: https://tushare.pro/document/2?doc_id=111
|
|
29
|
+
- SCALE: CrossSection & Individual
|
|
30
|
+
- TYPE: Partitioned
|
|
31
|
+
- PAGINATE: 1000 rows / 1000 pages
|
|
32
|
+
|
|
33
|
+
属性:
|
|
34
|
+
- name: str, 作业名称 'stockpledgedetail'。
|
|
35
|
+
- key: str, 作业键 '/tushare/stockpledgedetail'。
|
|
36
|
+
- session: Session, Tushare会话对象。
|
|
37
|
+
- source: TableInfo, 源表信息(Tushare原始格式)。
|
|
38
|
+
- target: TableInfo, 目标表信息(转换后格式)。
|
|
39
|
+
- params: Params, 查询参数。
|
|
40
|
+
- ts_code: str, 必需, 股票代码
|
|
41
|
+
- coolant: Coolant, 请求冷却控制。
|
|
42
|
+
- paginate: Paginate, 分页控制(pagesize=1000, pagelimit=1000)。
|
|
43
|
+
- retry: Retry, 重试策略。
|
|
44
|
+
- cache: Cache, 缓存管理。
|
|
45
|
+
|
|
46
|
+
方法:
|
|
47
|
+
- run(): 执行作业,返回股权质押明细数据DataFrame。
|
|
48
|
+
- _run(): 内部执行逻辑,处理参数并调用API。
|
|
49
|
+
- transform(data): 转换数据格式,将源格式转为目标格式。
|
|
50
|
+
|
|
51
|
+
注意:
|
|
52
|
+
- 此数据为个股数据(scale='individual'),ts_code为必需参数
|
|
53
|
+
- 包含股东名称、质押数量、质押时间、解押情况等详细信息
|
|
54
|
+
- 需要至少500积分才可以调取
|
|
55
|
+
|
|
56
|
+
例子:
|
|
57
|
+
```python
|
|
58
|
+
from xfintech.data.source.tushare.session import Session
|
|
59
|
+
from xfintech.data.source.tushare.stock.stockpledgedetail import StockPledgeDetail
|
|
60
|
+
|
|
61
|
+
session = Session(credential="your_token")
|
|
62
|
+
detail = StockPledgeDetail(
|
|
63
|
+
session=session,
|
|
64
|
+
params={"ts_code": "000014.SZ"},
|
|
65
|
+
)
|
|
66
|
+
df = detail.run()
|
|
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
|
+
# Prepare payload dict
|
|
97
|
+
payload = self.params.to_dict()
|
|
98
|
+
payload = self._parse_string_params(
|
|
99
|
+
payload,
|
|
100
|
+
keys=["ts_code"],
|
|
101
|
+
)
|
|
102
|
+
fields = SOURCE.list_column_names()
|
|
103
|
+
payload["fields"] = ",".join(fields)
|
|
104
|
+
|
|
105
|
+
# Call Tushare API via session
|
|
106
|
+
data = self._fetchall(
|
|
107
|
+
api=self.connection.pledge_detail,
|
|
108
|
+
**payload,
|
|
109
|
+
)
|
|
110
|
+
result = self.transform(data)
|
|
111
|
+
self._save_cache(result)
|
|
112
|
+
return result
|
|
113
|
+
|
|
114
|
+
# Transform logic
|
|
115
|
+
def transform(
|
|
116
|
+
self,
|
|
117
|
+
data: pd.DataFrame,
|
|
118
|
+
) -> pd.DataFrame:
|
|
119
|
+
cols = self.target.list_column_names()
|
|
120
|
+
if data is None or data.empty:
|
|
121
|
+
return pd.DataFrame(columns=cols)
|
|
122
|
+
|
|
123
|
+
# Build transformed dictionary
|
|
124
|
+
transformed = {}
|
|
125
|
+
transformed["code"] = data["ts_code"].astype(str)
|
|
126
|
+
transformed["holder_name"] = data["holder_name"].astype(str)
|
|
127
|
+
transformed["is_release"] = data["is_release"].astype(str)
|
|
128
|
+
transformed["pledgor"] = data["pledgor"].astype(str)
|
|
129
|
+
transformed["is_buyback"] = data["is_buyback"].astype(str)
|
|
130
|
+
|
|
131
|
+
# Date field transformations
|
|
132
|
+
date_fields = [
|
|
133
|
+
("ann_date", "ann_date", "ann_datecode"),
|
|
134
|
+
("start_date", "start_date", "start_datecode"),
|
|
135
|
+
("end_date", "end_date", "end_datecode"),
|
|
136
|
+
("release_date", "release_date", "release_datecode"),
|
|
137
|
+
]
|
|
138
|
+
|
|
139
|
+
for source_field, target_field, datecode_field in date_fields:
|
|
140
|
+
if source_field in data.columns:
|
|
141
|
+
transformed[target_field] = pd.to_datetime(
|
|
142
|
+
data[source_field],
|
|
143
|
+
format="%Y%m%d",
|
|
144
|
+
errors="coerce",
|
|
145
|
+
).dt.strftime("%Y-%m-%d")
|
|
146
|
+
transformed[datecode_field] = data[source_field]
|
|
147
|
+
|
|
148
|
+
# Numeric field transformations
|
|
149
|
+
for field in [
|
|
150
|
+
"pledge_amount",
|
|
151
|
+
"holding_amount",
|
|
152
|
+
"pledged_amount",
|
|
153
|
+
"p_total_ratio",
|
|
154
|
+
"h_total_ratio",
|
|
155
|
+
]:
|
|
156
|
+
if field in data.columns:
|
|
157
|
+
transformed[field] = pd.to_numeric(
|
|
158
|
+
data[field],
|
|
159
|
+
errors="coerce",
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
for col in cols:
|
|
163
|
+
if col not in transformed:
|
|
164
|
+
transformed[col] = pd.NA
|
|
165
|
+
|
|
166
|
+
out = pd.DataFrame(transformed)
|
|
167
|
+
out = out[cols].drop_duplicates()
|
|
168
|
+
out = out.sort_values(by=["code"])
|
|
169
|
+
out = out.reset_index(drop=True)
|
|
170
|
+
self.markpoint("transform[OK]")
|
|
171
|
+
return out
|
|
File without changes
|
xfintech/data/source/tushare/stock/stockpledgedetail/tests/test_class_stockpledgedetail_all.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""Comprehensive tests for StockPledgeDetail class"""
|
|
2
|
+
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from xfintech.data.source.tushare.stock.stockpledgedetail import StockPledgeDetail
|
|
7
|
+
from xfintech.data.source.tushare.stock.stockpledgedetail.constant import (
|
|
8
|
+
KEY,
|
|
9
|
+
NAME,
|
|
10
|
+
SOURCE,
|
|
11
|
+
TARGET,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Test Fixtures
|
|
16
|
+
class FakeConnection:
|
|
17
|
+
"""Fake Tushare connection for testing"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, frame: pd.DataFrame):
|
|
20
|
+
self.frame = frame
|
|
21
|
+
|
|
22
|
+
def pledge_detail(self, **kwargs):
|
|
23
|
+
"""Mock pledge_detail API call"""
|
|
24
|
+
return self.frame
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class FakeSession:
|
|
28
|
+
"""Fake session for testing"""
|
|
29
|
+
|
|
30
|
+
def __init__(self, connection: FakeConnection):
|
|
31
|
+
self.connection = connection
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@pytest.fixture
|
|
35
|
+
def mock_session():
|
|
36
|
+
"""Create a mock session with empty data"""
|
|
37
|
+
fake_conn = FakeConnection(frame=pd.DataFrame())
|
|
38
|
+
return FakeSession(fake_conn)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@pytest.fixture
|
|
42
|
+
def sample_source_data():
|
|
43
|
+
"""Sample pledge detail data in Tushare format"""
|
|
44
|
+
return pd.DataFrame(
|
|
45
|
+
{
|
|
46
|
+
"ts_code": ["000014.SZ", "000014.SZ", "600848.SH"],
|
|
47
|
+
"ann_date": ["20180106", "20180115", "20180106"],
|
|
48
|
+
"holder_name": ["中科汇通", "中科汇通", "某股东"],
|
|
49
|
+
"pledge_amount": [500.0, 300.0, 200.0],
|
|
50
|
+
"start_date": ["20171114", "20180101", "20171114"],
|
|
51
|
+
"end_date": ["20191113", "20191113", "20191113"],
|
|
52
|
+
"is_release": ["0", "0", "1"],
|
|
53
|
+
"release_date": ["", "", "20190101"],
|
|
54
|
+
"pledgor": ["某质押机构", "某质押机构", "某质押方"],
|
|
55
|
+
"holding_amount": [2321.9955, 2021.9955, 800.0],
|
|
56
|
+
"pledged_amount": [1422.0055, 1122.0055, 200.0],
|
|
57
|
+
"p_total_ratio": [0.1564, 0.1064, 0.04],
|
|
58
|
+
"h_total_ratio": [0.7268, 0.6468, 0.15],
|
|
59
|
+
"is_buyback": ["0", "0", "0"],
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# Initialization Tests
|
|
65
|
+
def test_stockpledgedetail_init_basic(mock_session):
|
|
66
|
+
"""Test basic initialization"""
|
|
67
|
+
detail = StockPledgeDetail(session=mock_session)
|
|
68
|
+
assert detail.name == NAME
|
|
69
|
+
assert detail.key == KEY
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_stockpledgedetail_init_with_params(mock_session):
|
|
73
|
+
"""Test initialization with params"""
|
|
74
|
+
detail = StockPledgeDetail(session=mock_session, params={"ts_code": "000014.SZ"})
|
|
75
|
+
assert detail.params.get("ts_code") == "000014.SZ"
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# Transform Tests
|
|
79
|
+
def test_stockpledgedetail_transform_basic(mock_session, sample_source_data):
|
|
80
|
+
"""Test basic transform"""
|
|
81
|
+
detail = StockPledgeDetail(session=mock_session)
|
|
82
|
+
result = detail.transform(sample_source_data)
|
|
83
|
+
assert len(result) == 3
|
|
84
|
+
assert "code" in result.columns
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def test_stockpledgedetail_transform_dates(mock_session, sample_source_data):
|
|
88
|
+
"""Test date transformations"""
|
|
89
|
+
detail = StockPledgeDetail(session=mock_session)
|
|
90
|
+
result = detail.transform(sample_source_data)
|
|
91
|
+
assert result["ann_date"].iloc[0] == "2018-01-06"
|
|
92
|
+
assert result["ann_datecode"].iloc[0] == "20180106"
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# Run Tests
|
|
96
|
+
def test_stockpledgedetail_run_basic(sample_source_data):
|
|
97
|
+
"""Test basic run"""
|
|
98
|
+
fake_conn = FakeConnection(frame=sample_source_data)
|
|
99
|
+
session = FakeSession(fake_conn)
|
|
100
|
+
detail = StockPledgeDetail(session=session, params={"ts_code": "000014.SZ"}, cache=False)
|
|
101
|
+
result = detail.run()
|
|
102
|
+
assert isinstance(result, pd.DataFrame)
|
|
103
|
+
assert len(result) > 0
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# Module Tests
|
|
107
|
+
def test_stockpledgedetail_constants():
|
|
108
|
+
"""Test module constants"""
|
|
109
|
+
assert NAME == "stockpledgedetail"
|
|
110
|
+
assert KEY == "/tushare/stockpledgedetail"
|
|
111
|
+
assert len(SOURCE.columns) == 14
|
|
112
|
+
assert len(TARGET.columns) == 18
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from xfintech.data.source.tushare.stock.stockst.constant import (
|
|
4
|
+
KEY,
|
|
5
|
+
NAME,
|
|
6
|
+
PAGINATE,
|
|
7
|
+
SOURCE,
|
|
8
|
+
TARGET,
|
|
9
|
+
)
|
|
10
|
+
from xfintech.data.source.tushare.stock.stockst.stockst import StockSt
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"StockSt",
|
|
14
|
+
"KEY",
|
|
15
|
+
"NAME",
|
|
16
|
+
"PAGINATE",
|
|
17
|
+
"SOURCE",
|
|
18
|
+
"TARGET",
|
|
19
|
+
]
|
|
@@ -0,0 +1,80 @@
|
|
|
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 = "tushare"
|
|
9
|
+
SOURCE_NAME = "stock_st"
|
|
10
|
+
URL = "https://tushare.pro/document/2?doc_id=397"
|
|
11
|
+
ARGS = {
|
|
12
|
+
"ts_code": {
|
|
13
|
+
"type": ColumnKind.STRING,
|
|
14
|
+
"required": "N",
|
|
15
|
+
"desc": "TS股票代码",
|
|
16
|
+
},
|
|
17
|
+
"start_date": {
|
|
18
|
+
"type": ColumnKind.STRING,
|
|
19
|
+
"required": "N",
|
|
20
|
+
"desc": "开始日期(YYYYMMDD)",
|
|
21
|
+
},
|
|
22
|
+
"end_date": {
|
|
23
|
+
"type": ColumnKind.STRING,
|
|
24
|
+
"required": "N",
|
|
25
|
+
"desc": "结束日期(YYYYMMDD)",
|
|
26
|
+
},
|
|
27
|
+
"trade_date": {
|
|
28
|
+
"type": ColumnKind.STRING,
|
|
29
|
+
"required": "N",
|
|
30
|
+
"desc": "交易日期(YYYYMMDD)",
|
|
31
|
+
},
|
|
32
|
+
"year": {
|
|
33
|
+
"type": ColumnKind.STRING,
|
|
34
|
+
"required": "N",
|
|
35
|
+
"desc": "年份(YYYY)",
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# Exported constants
|
|
40
|
+
NAME = "stockst"
|
|
41
|
+
KEY = "/tushare/stockst"
|
|
42
|
+
PAGINATE = Paginate(
|
|
43
|
+
pagesize=1000,
|
|
44
|
+
pagelimit=1000,
|
|
45
|
+
)
|
|
46
|
+
SOURCE = TableInfo(
|
|
47
|
+
desc="ST股票列表(Tushare格式)",
|
|
48
|
+
meta={
|
|
49
|
+
"provider": PROVIDER,
|
|
50
|
+
"source": SOURCE_NAME,
|
|
51
|
+
"url": URL,
|
|
52
|
+
"args": ARGS,
|
|
53
|
+
"type": "partitioned",
|
|
54
|
+
"scale": "crosssection",
|
|
55
|
+
},
|
|
56
|
+
columns=[
|
|
57
|
+
ColumnInfo(name="ts_code", kind=ColumnKind.STRING, desc="TS股票代码"),
|
|
58
|
+
ColumnInfo(name="name", kind=ColumnKind.STRING, desc="股票名称"),
|
|
59
|
+
ColumnInfo(name="trade_date", kind=ColumnKind.STRING, desc="交易日期"),
|
|
60
|
+
ColumnInfo(name="type", kind=ColumnKind.STRING, desc="ST类型"),
|
|
61
|
+
ColumnInfo(name="type_name", kind=ColumnKind.STRING, desc="ST类型名称"),
|
|
62
|
+
],
|
|
63
|
+
)
|
|
64
|
+
TARGET = TableInfo(
|
|
65
|
+
desc="ST股票列表(xfintech格式)",
|
|
66
|
+
meta={
|
|
67
|
+
"key": KEY,
|
|
68
|
+
"name": NAME,
|
|
69
|
+
"type": "partitioned",
|
|
70
|
+
"scale": "crosssection",
|
|
71
|
+
},
|
|
72
|
+
columns=[
|
|
73
|
+
ColumnInfo(name="code", kind=ColumnKind.STRING, desc="股票代码"),
|
|
74
|
+
ColumnInfo(name="name", kind=ColumnKind.STRING, desc="股票名称"),
|
|
75
|
+
ColumnInfo(name="date", kind=ColumnKind.STRING, desc="交易日期"),
|
|
76
|
+
ColumnInfo(name="datecode", kind=ColumnKind.STRING, desc="交易日期字符串"),
|
|
77
|
+
ColumnInfo(name="type", kind=ColumnKind.STRING, desc="ST类型"),
|
|
78
|
+
ColumnInfo(name="type_name", kind=ColumnKind.STRING, desc="ST类型名称"),
|
|
79
|
+
],
|
|
80
|
+
)
|
|
@@ -0,0 +1,189 @@
|
|
|
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.tushare.job import TushareJob
|
|
13
|
+
from xfintech.data.source.tushare.session.session import Session
|
|
14
|
+
from xfintech.data.source.tushare.stock.stockst.constant import (
|
|
15
|
+
KEY,
|
|
16
|
+
NAME,
|
|
17
|
+
PAGINATE,
|
|
18
|
+
SOURCE,
|
|
19
|
+
TARGET,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@JobHouse.register(KEY, alias=KEY)
|
|
24
|
+
class StockSt(TushareJob):
|
|
25
|
+
"""
|
|
26
|
+
描述:
|
|
27
|
+
- 获取ST股票列表的作业类。
|
|
28
|
+
- 支持按日期范围、交易日期或年份查询ST股票数据。
|
|
29
|
+
- 包含ST类型、ST类型名称等详细信息。
|
|
30
|
+
- 提供股票代码和名称列表查询功能。
|
|
31
|
+
- 数据从2016年开始,每天上午9:20更新。
|
|
32
|
+
- API文档: https://tushare.pro/document/2?doc_id=397
|
|
33
|
+
- SCALE: CrossSection & Individual
|
|
34
|
+
- TYPE: Partitioned
|
|
35
|
+
- PAGINATE: 1000 rows / 1000 pages
|
|
36
|
+
|
|
37
|
+
属性:
|
|
38
|
+
- name: str, 作业名称 'st'。
|
|
39
|
+
- key: str, 作业键 '/tushare/st'。
|
|
40
|
+
- session: Session, Tushare会话对象。
|
|
41
|
+
- source: TableInfo, 源表信息(Tushare原始格式)。
|
|
42
|
+
- target: TableInfo, 目标表信息(转换后格式)。
|
|
43
|
+
- params: Params, 查询参数。
|
|
44
|
+
- ts_code: str, 可选, TS股票代码
|
|
45
|
+
- start_date: str, 可选, 开始日期(YYYYMMDD)
|
|
46
|
+
- end_date: str, 可选, 结束日期(YYYYMMDD)
|
|
47
|
+
- trade_date: str, 可选, 交易日期(YYYYMMDD)
|
|
48
|
+
- year: str, 可选, 年份(YYYY)
|
|
49
|
+
- coolant: Coolant, 请求冷却控制。
|
|
50
|
+
- paginate: Paginate, 分页控制(pagesize=1000, pagelimit=1000)。
|
|
51
|
+
- retry: Retry, 重试策略。
|
|
52
|
+
- cache: Cache, 缓存管理。
|
|
53
|
+
|
|
54
|
+
方法:
|
|
55
|
+
- run(): 执行作业,返回ST股票信息DataFrame。
|
|
56
|
+
- _run(): 内部执行逻辑,处理日期参数转换。
|
|
57
|
+
- transform(data): 转换数据格式,将源格式转为目标格式。
|
|
58
|
+
- list_codes(): 返回所有ST股票代码列表(排序)。
|
|
59
|
+
- list_names(): 返回所有ST股票名称列表(排序)。
|
|
60
|
+
|
|
61
|
+
例子:
|
|
62
|
+
```python
|
|
63
|
+
from xfintech.data.source.tushare.session import Session
|
|
64
|
+
from xfintech.data.source.tushare.stock.stockst import StockSt
|
|
65
|
+
|
|
66
|
+
# 创建会话
|
|
67
|
+
session = Session(credential="your_token")
|
|
68
|
+
|
|
69
|
+
# 查询2023年的ST股票信息
|
|
70
|
+
job = StockSt(session=session, params={"year": "2023"}, cache=True)
|
|
71
|
+
df = job.run()
|
|
72
|
+
print(f"2023年ST股票记录: {len(df)} 条")
|
|
73
|
+
|
|
74
|
+
# 查询特定日期范围
|
|
75
|
+
job = StockSt(
|
|
76
|
+
session=session,
|
|
77
|
+
params={"start_date": "20230101", "end_date": "20230630"}
|
|
78
|
+
)
|
|
79
|
+
df = job.run()
|
|
80
|
+
|
|
81
|
+
# 查询特定交易日
|
|
82
|
+
job = StockSt(session=session, params={"trade_date": "20230315"})
|
|
83
|
+
df = job.run()
|
|
84
|
+
|
|
85
|
+
# 查询特定股票的ST记录
|
|
86
|
+
job = StockSt(session=session, params={"ts_code": "600000.SH"})
|
|
87
|
+
df = job.run()
|
|
88
|
+
|
|
89
|
+
# 获取ST股票代码列表
|
|
90
|
+
codes = job.list_codes()
|
|
91
|
+
print(f"ST股票代码: {codes[:5]}")
|
|
92
|
+
|
|
93
|
+
# 获取ST股票名称列表
|
|
94
|
+
names = job.list_names()
|
|
95
|
+
print(f"ST股票名称: {names[:5]}")
|
|
96
|
+
```
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
def __init__(
|
|
100
|
+
self,
|
|
101
|
+
session: Session,
|
|
102
|
+
params: Optional[Params | Dict[str, Any]] = None,
|
|
103
|
+
coolant: Optional[Coolant | Dict[str, Any]] = None,
|
|
104
|
+
retry: Optional[Retry | Dict[str, Any]] = None,
|
|
105
|
+
cache: Optional[Cache | Dict[str, str] | bool] = None,
|
|
106
|
+
) -> None:
|
|
107
|
+
super().__init__(
|
|
108
|
+
name=NAME,
|
|
109
|
+
key=KEY,
|
|
110
|
+
session=session,
|
|
111
|
+
source=SOURCE,
|
|
112
|
+
target=TARGET,
|
|
113
|
+
params=params,
|
|
114
|
+
coolant=coolant,
|
|
115
|
+
paginate=PAGINATE,
|
|
116
|
+
retry=retry,
|
|
117
|
+
cache=cache,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
def _run(self) -> pd.DataFrame:
|
|
121
|
+
cached = self._load_cache()
|
|
122
|
+
if cached is not None:
|
|
123
|
+
return cached
|
|
124
|
+
|
|
125
|
+
# Prepare payload dict
|
|
126
|
+
payload = self.params.to_dict()
|
|
127
|
+
payload = self._parse_date_params(
|
|
128
|
+
payload,
|
|
129
|
+
keys=[
|
|
130
|
+
"trade_date",
|
|
131
|
+
"start_date",
|
|
132
|
+
"end_date",
|
|
133
|
+
],
|
|
134
|
+
)
|
|
135
|
+
payload = self._parse_year_params(
|
|
136
|
+
payload,
|
|
137
|
+
key="year",
|
|
138
|
+
)
|
|
139
|
+
all_fields = SOURCE.list_column_names()
|
|
140
|
+
payload["fields"] = ",".join(all_fields)
|
|
141
|
+
|
|
142
|
+
# Fetch data from Tushare API
|
|
143
|
+
df = self._fetchall(
|
|
144
|
+
api=self.connection.stock_st,
|
|
145
|
+
**payload,
|
|
146
|
+
)
|
|
147
|
+
result = self.transform(df)
|
|
148
|
+
self._save_cache(result)
|
|
149
|
+
return result
|
|
150
|
+
|
|
151
|
+
# Transform logic
|
|
152
|
+
def transform(
|
|
153
|
+
self,
|
|
154
|
+
data: pd.DataFrame,
|
|
155
|
+
) -> pd.DataFrame:
|
|
156
|
+
cols = self.target.list_column_names()
|
|
157
|
+
if data is None or data.empty:
|
|
158
|
+
return pd.DataFrame(columns=cols)
|
|
159
|
+
|
|
160
|
+
out = data.copy()
|
|
161
|
+
out["code"] = out["ts_code"].astype(str)
|
|
162
|
+
out["name"] = out["name"].astype(str)
|
|
163
|
+
|
|
164
|
+
# Trade date conversions
|
|
165
|
+
out["date"] = pd.to_datetime(
|
|
166
|
+
out["trade_date"],
|
|
167
|
+
format="%Y%m%d",
|
|
168
|
+
errors="coerce",
|
|
169
|
+
).dt.strftime("%Y-%m-%d")
|
|
170
|
+
out["datecode"] = out["trade_date"].astype(str)
|
|
171
|
+
|
|
172
|
+
# ST type fields
|
|
173
|
+
out["type"] = out["type"].astype(str)
|
|
174
|
+
out["type_name"] = out["type_name"].astype(str)
|
|
175
|
+
|
|
176
|
+
# Select target columns, drop duplicates, and sort
|
|
177
|
+
out = out[cols].drop_duplicates()
|
|
178
|
+
out = out.sort_values(by=["code"])
|
|
179
|
+
out = out.reset_index(drop=True)
|
|
180
|
+
self.markpoint("transform[OK]")
|
|
181
|
+
return out
|
|
182
|
+
|
|
183
|
+
def list_codes(self) -> List[str]:
|
|
184
|
+
df = self.run()
|
|
185
|
+
return sorted(df["code"].unique().tolist())
|
|
186
|
+
|
|
187
|
+
def list_names(self) -> List[str]:
|
|
188
|
+
df = self.run()
|
|
189
|
+
return sorted(df["name"].unique().tolist())
|
|
File without changes
|