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,55 @@
|
|
|
1
|
+
from .adjfactor.adjfactor import AdjFactor
|
|
2
|
+
from .capflow.capflow import Capflow
|
|
3
|
+
from .capflowdc.capflowdc import CapflowDC
|
|
4
|
+
from .capflowths.capflowths import CapflowTHS
|
|
5
|
+
from .company.company import Company
|
|
6
|
+
from .companycashflow.companycashflow import CompanyCashflow
|
|
7
|
+
from .companydebt.companydebt import CompanyDebt
|
|
8
|
+
from .companyoverview.companyoverview import CompanyOverview
|
|
9
|
+
from .companyprofit.companyprofit import CompanyProfit
|
|
10
|
+
from .conceptcapflowdc.conceptcapflowdc import ConceptCapflowDC
|
|
11
|
+
from .conceptcapflowths.conceptcapflowths import ConceptCapflowTHS
|
|
12
|
+
from .dayline.dayline import Dayline
|
|
13
|
+
from .industrycapflowths.industrycapflowths import IndustryCapflowTHS
|
|
14
|
+
from .marketindexcapflowdc.marketindexcapflowdc import MarketIndexCapflowDC
|
|
15
|
+
from .monthline.monthline import Monthline
|
|
16
|
+
from .stock.stock import Stock
|
|
17
|
+
from .stockdividend.stockdividend import StockDividend
|
|
18
|
+
from .stockinfo.stockinfo import StockInfo
|
|
19
|
+
from .stockipo.stockipo import StockIpo
|
|
20
|
+
from .stockpledge.stockpledge import StockPledge
|
|
21
|
+
from .stockpledgedetail.stockpledgedetail import StockPledgeDetail
|
|
22
|
+
from .stockst.stockst import StockSt
|
|
23
|
+
from .stocksuspend.stocksuspend import StockSuspend
|
|
24
|
+
from .techindex.techindex import TechIndex
|
|
25
|
+
from .tradedate.tradedate import TradeDate
|
|
26
|
+
from .weekline.weekline import Weekline
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"AdjFactor",
|
|
30
|
+
"Capflow",
|
|
31
|
+
"CapflowDC",
|
|
32
|
+
"CapflowTHS",
|
|
33
|
+
"Company",
|
|
34
|
+
"CompanyCashflow",
|
|
35
|
+
"CompanyDebt",
|
|
36
|
+
"CompanyOverview",
|
|
37
|
+
"CompanyProfit",
|
|
38
|
+
"ConceptCapflowDC",
|
|
39
|
+
"ConceptCapflowTHS",
|
|
40
|
+
"Dayline",
|
|
41
|
+
"IndustryCapflowTHS",
|
|
42
|
+
"MarketIndexCapflowDC",
|
|
43
|
+
"Monthline",
|
|
44
|
+
"Stock",
|
|
45
|
+
"StockDividend",
|
|
46
|
+
"StockInfo",
|
|
47
|
+
"StockIpo",
|
|
48
|
+
"StockPledge",
|
|
49
|
+
"StockPledgeDetail",
|
|
50
|
+
"StockSt",
|
|
51
|
+
"StockSuspend",
|
|
52
|
+
"TechIndex",
|
|
53
|
+
"TradeDate",
|
|
54
|
+
"Weekline",
|
|
55
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from xfintech.data.source.tushare.stock.adjfactor.adjfactor import AdjFactor
|
|
4
|
+
from xfintech.data.source.tushare.stock.adjfactor.constant import (
|
|
5
|
+
KEY,
|
|
6
|
+
NAME,
|
|
7
|
+
PAGINATE,
|
|
8
|
+
SOURCE,
|
|
9
|
+
TARGET,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"AdjFactor",
|
|
14
|
+
"KEY",
|
|
15
|
+
"NAME",
|
|
16
|
+
"PAGINATE",
|
|
17
|
+
"SOURCE",
|
|
18
|
+
"TARGET",
|
|
19
|
+
]
|
|
@@ -0,0 +1,150 @@
|
|
|
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.adjfactor.constant import (
|
|
15
|
+
KEY,
|
|
16
|
+
NAME,
|
|
17
|
+
PAGINATE,
|
|
18
|
+
SOURCE,
|
|
19
|
+
TARGET,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@JobHouse.register(KEY, alias=KEY)
|
|
24
|
+
class AdjFactor(TushareJob):
|
|
25
|
+
"""
|
|
26
|
+
描述:
|
|
27
|
+
- 获取A股复权因子数据
|
|
28
|
+
- 盘前9点15~20分完成当日复权因子入库
|
|
29
|
+
- 2000积分起,5000以上可高频调取
|
|
30
|
+
- API文档: https://tushare.pro/document/2?doc_id=28
|
|
31
|
+
- SCALE: CrossSection & Individual
|
|
32
|
+
- TYPE: Partitioned
|
|
33
|
+
- PAGINATE: 2000 rows / 1000 pages
|
|
34
|
+
|
|
35
|
+
属性:
|
|
36
|
+
- name: str, 作业名称 'adjfactor'。
|
|
37
|
+
- key: str, 作业键 '/tushare/adjfactor'。
|
|
38
|
+
- session: Session, Tushare会话对象。
|
|
39
|
+
- source: TableInfo, 源表信息(Tushare原始格式)。
|
|
40
|
+
- target: TableInfo, 目标表信息(转换后格式)。
|
|
41
|
+
- params: Params, 查询参数。
|
|
42
|
+
- ts_code: str, 可选, 股票代码
|
|
43
|
+
- trade_date: str, 可选, 特定交易日期(YYYYMMDD)
|
|
44
|
+
- start_date: str, 可选, 开始日期(YYYYMMDD)
|
|
45
|
+
- end_date: str, 可选, 结束日期(YYYYMMDD)
|
|
46
|
+
- coolant: Coolant, 请求冷却控制。
|
|
47
|
+
- paginate: Paginate, 分页控制(pagesize=2000, pagelimit=10)。
|
|
48
|
+
- retry: Retry, 重试策略。
|
|
49
|
+
- cache: Cache, 缓存管理。
|
|
50
|
+
|
|
51
|
+
方法:
|
|
52
|
+
- run(): 执行作业,返回复权因子DataFrame。
|
|
53
|
+
- _run(): 内部执行逻辑,处理日期参数。
|
|
54
|
+
- transform(data): 转换数据格式,将源格式转为目标格式。
|
|
55
|
+
|
|
56
|
+
例子:
|
|
57
|
+
```python
|
|
58
|
+
from xfintech.data.source.tushare.session import Session
|
|
59
|
+
from xfintech.data.source.tushare.stock.adjfactor import AdjFactor
|
|
60
|
+
|
|
61
|
+
session = Session(credential="your_token")
|
|
62
|
+
job = AdjFactor(
|
|
63
|
+
session=session,
|
|
64
|
+
params={
|
|
65
|
+
"start_date": "20241101",
|
|
66
|
+
"end_date": "20241231",
|
|
67
|
+
},
|
|
68
|
+
)
|
|
69
|
+
df = job.run()
|
|
70
|
+
print(df)
|
|
71
|
+
```
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
def __init__(
|
|
75
|
+
self,
|
|
76
|
+
session: Session,
|
|
77
|
+
params: Optional[Params | Dict[str, Any]] = None,
|
|
78
|
+
coolant: Optional[Coolant | Dict[str, Any]] = None,
|
|
79
|
+
retry: Optional[Retry | Dict[str, Any]] = None,
|
|
80
|
+
cache: Optional[Cache | Dict[str, str] | bool] = None,
|
|
81
|
+
) -> None:
|
|
82
|
+
super().__init__(
|
|
83
|
+
name=NAME,
|
|
84
|
+
key=KEY,
|
|
85
|
+
session=session,
|
|
86
|
+
source=SOURCE,
|
|
87
|
+
target=TARGET,
|
|
88
|
+
params=params,
|
|
89
|
+
coolant=coolant,
|
|
90
|
+
paginate=PAGINATE,
|
|
91
|
+
retry=retry,
|
|
92
|
+
cache=cache,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
def _run(self) -> pd.DataFrame:
|
|
96
|
+
cached = self._load_cache()
|
|
97
|
+
if cached is not None:
|
|
98
|
+
return cached
|
|
99
|
+
|
|
100
|
+
# Prepare payload dict
|
|
101
|
+
payload = self.params.to_dict()
|
|
102
|
+
payload = self._parse_date_params(
|
|
103
|
+
payload,
|
|
104
|
+
keys=["trade_date", "start_date", "end_date"],
|
|
105
|
+
)
|
|
106
|
+
payload = self._parse_string_params(
|
|
107
|
+
payload,
|
|
108
|
+
keys=["ts_code"],
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# Fetch data from API
|
|
112
|
+
data = self._fetchall(
|
|
113
|
+
api=self.connection.adj_factor,
|
|
114
|
+
**payload,
|
|
115
|
+
)
|
|
116
|
+
result = self.transform(data)
|
|
117
|
+
self._save_cache(result)
|
|
118
|
+
return result
|
|
119
|
+
|
|
120
|
+
def transform(
|
|
121
|
+
self,
|
|
122
|
+
data: pd.DataFrame,
|
|
123
|
+
) -> pd.DataFrame:
|
|
124
|
+
cols = self.target.list_column_names()
|
|
125
|
+
if data is None or data.empty:
|
|
126
|
+
return pd.DataFrame(columns=cols)
|
|
127
|
+
|
|
128
|
+
# Transform logic
|
|
129
|
+
out = data.copy()
|
|
130
|
+
out["code"] = out["ts_code"].astype(str)
|
|
131
|
+
out["date"] = pd.to_datetime(
|
|
132
|
+
out["trade_date"],
|
|
133
|
+
format="%Y%m%d",
|
|
134
|
+
errors="coerce",
|
|
135
|
+
).dt.strftime("%Y-%m-%d")
|
|
136
|
+
out["datecode"] = out["trade_date"].astype(str)
|
|
137
|
+
|
|
138
|
+
# Convert numeric fields
|
|
139
|
+
for field in ["adj_factor"]:
|
|
140
|
+
out[field] = pd.to_numeric(
|
|
141
|
+
out[field],
|
|
142
|
+
errors="coerce",
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# Finalize output
|
|
146
|
+
out = out[cols].drop_duplicates()
|
|
147
|
+
out = out.sort_values(by=["code", "date"])
|
|
148
|
+
out = out.reset_index(drop=True)
|
|
149
|
+
self.markpoint("transform[OK]")
|
|
150
|
+
return out
|
|
@@ -0,0 +1,71 @@
|
|
|
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 = "adj_factor"
|
|
10
|
+
URL = "https://tushare.pro/document/2?doc_id=28"
|
|
11
|
+
ARGS = {
|
|
12
|
+
"ts_code": {
|
|
13
|
+
"type": ColumnKind.STRING,
|
|
14
|
+
"required": "N",
|
|
15
|
+
"desc": "股票代码",
|
|
16
|
+
},
|
|
17
|
+
"trade_date": {
|
|
18
|
+
"type": ColumnKind.STRING,
|
|
19
|
+
"required": "N",
|
|
20
|
+
"desc": "特定交易日期(YYYYMMDD)",
|
|
21
|
+
},
|
|
22
|
+
"start_date": {
|
|
23
|
+
"type": ColumnKind.STRING,
|
|
24
|
+
"required": "N",
|
|
25
|
+
"desc": "开始日期(YYYYMMDD)",
|
|
26
|
+
},
|
|
27
|
+
"end_date": {
|
|
28
|
+
"type": ColumnKind.STRING,
|
|
29
|
+
"required": "N",
|
|
30
|
+
"desc": "结束日期(YYYYMMDD)",
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Exported constants
|
|
35
|
+
NAME = "adjfactor"
|
|
36
|
+
KEY = "/tushare/adjfactor"
|
|
37
|
+
PAGINATE = Paginate(
|
|
38
|
+
pagesize=2000,
|
|
39
|
+
pagelimit=1000,
|
|
40
|
+
)
|
|
41
|
+
SOURCE = TableInfo(
|
|
42
|
+
desc="A股复权因子数据(Tushare格式)",
|
|
43
|
+
meta={
|
|
44
|
+
"provider": PROVIDER,
|
|
45
|
+
"source": SOURCE_NAME,
|
|
46
|
+
"url": URL,
|
|
47
|
+
"args": ARGS,
|
|
48
|
+
"type": "partitioned",
|
|
49
|
+
"scale": "crosssection",
|
|
50
|
+
},
|
|
51
|
+
columns=[
|
|
52
|
+
ColumnInfo(name="ts_code", kind=ColumnKind.STRING, desc="股票代码"),
|
|
53
|
+
ColumnInfo(name="trade_date", kind=ColumnKind.STRING, desc="交易日期"),
|
|
54
|
+
ColumnInfo(name="adj_factor", kind=ColumnKind.FLOAT, desc="复权因子"),
|
|
55
|
+
],
|
|
56
|
+
)
|
|
57
|
+
TARGET = TableInfo(
|
|
58
|
+
desc="A股复权因子数据(xfintech格式)",
|
|
59
|
+
meta={
|
|
60
|
+
"key": KEY,
|
|
61
|
+
"name": NAME,
|
|
62
|
+
"type": "partitioned",
|
|
63
|
+
"scale": "crosssection",
|
|
64
|
+
},
|
|
65
|
+
columns=[
|
|
66
|
+
ColumnInfo(name="code", kind=ColumnKind.STRING, desc="股票代码"),
|
|
67
|
+
ColumnInfo(name="date", kind=ColumnKind.STRING, desc="交易日期"),
|
|
68
|
+
ColumnInfo(name="datecode", kind=ColumnKind.STRING, desc="交易日期代码(YYYYMMDD)"),
|
|
69
|
+
ColumnInfo(name="adj_factor", kind=ColumnKind.FLOAT, desc="复权因子"),
|
|
70
|
+
],
|
|
71
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from datetime import date, datetime
|
|
4
|
+
from unittest.mock import MagicMock, patch
|
|
5
|
+
|
|
6
|
+
import pandas as pd
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
from xfintech.data.source.tushare.stock.adjfactor import (
|
|
10
|
+
KEY,
|
|
11
|
+
NAME,
|
|
12
|
+
PAGINATE,
|
|
13
|
+
SOURCE,
|
|
14
|
+
TARGET,
|
|
15
|
+
AdjFactor,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.fixture
|
|
20
|
+
def mock_session():
|
|
21
|
+
session = MagicMock()
|
|
22
|
+
mock_connection = MagicMock()
|
|
23
|
+
mock_connection.adj_factor = MagicMock()
|
|
24
|
+
session.connection = mock_connection
|
|
25
|
+
return session
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@pytest.fixture
|
|
29
|
+
def sample_source_data():
|
|
30
|
+
"""创建样本源数据"""
|
|
31
|
+
return pd.DataFrame(
|
|
32
|
+
{
|
|
33
|
+
"ts_code": ["000001.SZ", "000002.SZ", "600000.SH"],
|
|
34
|
+
"trade_date": ["20241201", "20241201", "20241201"],
|
|
35
|
+
"adj_factor": [1.234567, 2.345678, 3.456789],
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# Initialization Tests
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class TestAdjFactorInitialization:
|
|
44
|
+
def test_init_basic(self, mock_session):
|
|
45
|
+
"""测试基础初始化"""
|
|
46
|
+
job = AdjFactor(session=mock_session)
|
|
47
|
+
assert job.name == NAME
|
|
48
|
+
assert job.key == KEY
|
|
49
|
+
assert job.source == SOURCE
|
|
50
|
+
assert job.target == TARGET
|
|
51
|
+
|
|
52
|
+
def test_init_with_params(self, mock_session):
|
|
53
|
+
"""测试带参数的初始化"""
|
|
54
|
+
params = {"ts_code": "000001.SZ"}
|
|
55
|
+
job = AdjFactor(session=mock_session, params=params)
|
|
56
|
+
assert job.params.get("ts_code") == "000001.SZ"
|
|
57
|
+
|
|
58
|
+
def test_init_with_all_components(self, mock_session):
|
|
59
|
+
"""测试带所有组件的初始化"""
|
|
60
|
+
params = {"ts_code": "000001.SZ"}
|
|
61
|
+
coolant = {"interval": 0.1}
|
|
62
|
+
retry = {"max_retries": 3}
|
|
63
|
+
|
|
64
|
+
job = AdjFactor(
|
|
65
|
+
session=mock_session,
|
|
66
|
+
params=params,
|
|
67
|
+
coolant=coolant,
|
|
68
|
+
retry=retry,
|
|
69
|
+
cache=False,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
assert job.name == NAME
|
|
73
|
+
assert job.key == KEY
|
|
74
|
+
assert job.params.get("ts_code") == "000001.SZ"
|
|
75
|
+
|
|
76
|
+
def test_name_constant(self):
|
|
77
|
+
"""测试NAME常量"""
|
|
78
|
+
assert NAME == "adjfactor"
|
|
79
|
+
|
|
80
|
+
def test_key_constant(self):
|
|
81
|
+
"""测试KEY常量"""
|
|
82
|
+
assert KEY == "/tushare/adjfactor"
|
|
83
|
+
|
|
84
|
+
def test_paginate_constant(self):
|
|
85
|
+
"""测试PAGINATE常量"""
|
|
86
|
+
assert PAGINATE.pagesize
|
|
87
|
+
assert PAGINATE.pagelimit
|
|
88
|
+
|
|
89
|
+
def test_source_schema(self):
|
|
90
|
+
"""测试SOURCE表结构"""
|
|
91
|
+
columns_list = SOURCE.list_columns()
|
|
92
|
+
assert columns_list is not None
|
|
93
|
+
assert len(columns_list) == 3
|
|
94
|
+
column_names = [col.name for col in columns_list]
|
|
95
|
+
assert "ts_code" in column_names
|
|
96
|
+
assert "trade_date" in column_names
|
|
97
|
+
assert "adj_factor" in column_names
|
|
98
|
+
|
|
99
|
+
def test_target_schema(self):
|
|
100
|
+
"""测试TARGET表结构"""
|
|
101
|
+
columns_list = TARGET.list_columns()
|
|
102
|
+
assert columns_list is not None
|
|
103
|
+
assert len(columns_list) == 4
|
|
104
|
+
column_names = [col.name for col in columns_list]
|
|
105
|
+
assert "code" in column_names
|
|
106
|
+
assert "date" in column_names
|
|
107
|
+
assert "datecode" in column_names
|
|
108
|
+
assert "adj_factor" in column_names
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# Transform Tests
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class TestAdjFactorTransform:
|
|
115
|
+
def test_transform_basic(self, mock_session, sample_source_data):
|
|
116
|
+
"""测试基本转换"""
|
|
117
|
+
job = AdjFactor(session=mock_session)
|
|
118
|
+
result = job.transform(sample_source_data)
|
|
119
|
+
|
|
120
|
+
assert "code" in result.columns
|
|
121
|
+
assert "date" in result.columns
|
|
122
|
+
assert "datecode" in result.columns
|
|
123
|
+
assert "adj_factor" in result.columns
|
|
124
|
+
assert len(result) == 3
|
|
125
|
+
|
|
126
|
+
def test_transform_date_conversion(self, mock_session, sample_source_data):
|
|
127
|
+
"""测试日期转换"""
|
|
128
|
+
job = AdjFactor(session=mock_session)
|
|
129
|
+
result = job.transform(sample_source_data)
|
|
130
|
+
|
|
131
|
+
# Check date format YYYY-MM-DD
|
|
132
|
+
assert result["date"].iloc[0] == "2024-12-01"
|
|
133
|
+
# Check datecode format YYYYMMDD
|
|
134
|
+
assert result["datecode"].iloc[0] == "20241201"
|
|
135
|
+
|
|
136
|
+
def test_transform_adj_factor_values(self, mock_session, sample_source_data):
|
|
137
|
+
"""测试复权因子值保持不变"""
|
|
138
|
+
job = AdjFactor(session=mock_session)
|
|
139
|
+
result = job.transform(sample_source_data)
|
|
140
|
+
|
|
141
|
+
assert result["adj_factor"].iloc[0] == 1.234567
|
|
142
|
+
assert result["adj_factor"].iloc[1] == 2.345678
|
|
143
|
+
assert result["adj_factor"].iloc[2] == 3.456789
|
|
144
|
+
|
|
145
|
+
def test_transform_empty_data(self, mock_session):
|
|
146
|
+
"""测试空数据转换"""
|
|
147
|
+
job = AdjFactor(session=mock_session)
|
|
148
|
+
empty_df = pd.DataFrame()
|
|
149
|
+
result = job.transform(empty_df)
|
|
150
|
+
|
|
151
|
+
assert result.empty
|
|
152
|
+
assert "code" in result.columns
|
|
153
|
+
|
|
154
|
+
def test_transform_none_data(self, mock_session):
|
|
155
|
+
"""测试None数据转换"""
|
|
156
|
+
job = AdjFactor(session=mock_session)
|
|
157
|
+
result = job.transform(None)
|
|
158
|
+
|
|
159
|
+
assert result.empty
|
|
160
|
+
assert "code" in result.columns
|
|
161
|
+
|
|
162
|
+
def test_transform_invalid_dates(self, mock_session):
|
|
163
|
+
"""测试无效日期处理"""
|
|
164
|
+
job = AdjFactor(session=mock_session)
|
|
165
|
+
data = pd.DataFrame(
|
|
166
|
+
{
|
|
167
|
+
"ts_code": ["000001.SZ"],
|
|
168
|
+
"trade_date": ["invalid"],
|
|
169
|
+
"adj_factor": [1.0],
|
|
170
|
+
}
|
|
171
|
+
)
|
|
172
|
+
result = job.transform(data)
|
|
173
|
+
|
|
174
|
+
# Should handle invalid dates gracefully
|
|
175
|
+
assert len(result) == 1
|
|
176
|
+
assert pd.isna(result["date"].iloc[0]) or result["date"].iloc[0] == "NaT"
|
|
177
|
+
|
|
178
|
+
def test_transform_duplicates_removed(self, mock_session):
|
|
179
|
+
"""测试重复数据删除"""
|
|
180
|
+
job = AdjFactor(session=mock_session)
|
|
181
|
+
data = pd.DataFrame(
|
|
182
|
+
{
|
|
183
|
+
"ts_code": ["000001.SZ", "000001.SZ", "000002.SZ"],
|
|
184
|
+
"trade_date": ["20241201", "20241201", "20241201"],
|
|
185
|
+
"adj_factor": [1.0, 1.0, 2.0],
|
|
186
|
+
}
|
|
187
|
+
)
|
|
188
|
+
result = job.transform(data)
|
|
189
|
+
|
|
190
|
+
# Duplicates should be removed
|
|
191
|
+
assert len(result) == 2
|
|
192
|
+
|
|
193
|
+
def test_transform_sorting(self, mock_session):
|
|
194
|
+
"""测试数据排序"""
|
|
195
|
+
job = AdjFactor(session=mock_session)
|
|
196
|
+
data = pd.DataFrame(
|
|
197
|
+
{
|
|
198
|
+
"ts_code": ["600000.SH", "000001.SZ", "000002.SZ"],
|
|
199
|
+
"trade_date": ["20241203", "20241201", "20241202"],
|
|
200
|
+
"adj_factor": [3.0, 1.0, 2.0],
|
|
201
|
+
}
|
|
202
|
+
)
|
|
203
|
+
result = job.transform(data)
|
|
204
|
+
|
|
205
|
+
# Should be sorted by code and date
|
|
206
|
+
assert result["code"].iloc[0] == "000001.SZ"
|
|
207
|
+
assert result["code"].iloc[1] == "000002.SZ"
|
|
208
|
+
assert result["code"].iloc[2] == "600000.SH"
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
# Run Tests
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class TestAdjFactorRun:
|
|
215
|
+
def test_run_basic(self, mock_session, sample_source_data):
|
|
216
|
+
"""测试基本运行"""
|
|
217
|
+
job = AdjFactor(session=mock_session, cache=False)
|
|
218
|
+
|
|
219
|
+
with patch.object(job, "_fetchall", return_value=sample_source_data):
|
|
220
|
+
result = job.run()
|
|
221
|
+
assert len(result) == 3
|
|
222
|
+
assert "code" in result.columns
|
|
223
|
+
|
|
224
|
+
def test_run_with_ts_code(self, mock_session, sample_source_data):
|
|
225
|
+
"""测试指定股票代码运行"""
|
|
226
|
+
params = {"ts_code": "000001.SZ"}
|
|
227
|
+
job = AdjFactor(session=mock_session, params=params, cache=False)
|
|
228
|
+
|
|
229
|
+
with patch.object(job, "_fetchall", return_value=sample_source_data):
|
|
230
|
+
result = job.run()
|
|
231
|
+
assert len(result) > 0
|
|
232
|
+
|
|
233
|
+
def test_run_with_trade_date_string(self, mock_session, sample_source_data):
|
|
234
|
+
"""测试交易日期(字符串)运行"""
|
|
235
|
+
params = {"trade_date": "20241201"}
|
|
236
|
+
job = AdjFactor(session=mock_session, params=params, cache=False)
|
|
237
|
+
|
|
238
|
+
with patch.object(job, "_fetchall", return_value=sample_source_data):
|
|
239
|
+
result = job.run()
|
|
240
|
+
assert len(result) > 0
|
|
241
|
+
|
|
242
|
+
def test_run_with_trade_date_datetime(self, mock_session, sample_source_data):
|
|
243
|
+
"""测试交易日期(datetime)运行"""
|
|
244
|
+
params = {"trade_date": datetime(2024, 12, 1)}
|
|
245
|
+
job = AdjFactor(session=mock_session, params=params, cache=False)
|
|
246
|
+
|
|
247
|
+
with patch.object(job, "_fetchall", return_value=sample_source_data):
|
|
248
|
+
result = job.run()
|
|
249
|
+
assert len(result) > 0
|
|
250
|
+
|
|
251
|
+
def test_run_with_trade_date_date(self, mock_session, sample_source_data):
|
|
252
|
+
"""测试交易日期(date)运行"""
|
|
253
|
+
params = {"trade_date": date(2024, 12, 1)}
|
|
254
|
+
job = AdjFactor(session=mock_session, params=params, cache=False)
|
|
255
|
+
|
|
256
|
+
with patch.object(job, "_fetchall", return_value=sample_source_data):
|
|
257
|
+
result = job.run()
|
|
258
|
+
assert len(result) > 0
|
|
259
|
+
|
|
260
|
+
def test_run_with_date_range_string(self, mock_session, sample_source_data):
|
|
261
|
+
"""测试日期区间(字符串)运行"""
|
|
262
|
+
params = {"start_date": "20241101", "end_date": "20241231"}
|
|
263
|
+
job = AdjFactor(session=mock_session, params=params, cache=False)
|
|
264
|
+
|
|
265
|
+
with patch.object(job, "_fetchall", return_value=sample_source_data):
|
|
266
|
+
result = job.run()
|
|
267
|
+
assert len(result) > 0
|
|
268
|
+
|
|
269
|
+
def test_run_with_date_range_datetime(self, mock_session, sample_source_data):
|
|
270
|
+
"""测试日期区间(datetime)运行"""
|
|
271
|
+
params = {
|
|
272
|
+
"start_date": datetime(2024, 11, 1),
|
|
273
|
+
"end_date": datetime(2024, 12, 31),
|
|
274
|
+
}
|
|
275
|
+
job = AdjFactor(session=mock_session, params=params, cache=False)
|
|
276
|
+
|
|
277
|
+
with patch.object(job, "_fetchall", return_value=sample_source_data):
|
|
278
|
+
result = job.run()
|
|
279
|
+
assert len(result) > 0
|
|
280
|
+
|
|
281
|
+
def test_run_with_date_range_date(self, mock_session, sample_source_data):
|
|
282
|
+
"""测试日期区间(date)运行"""
|
|
283
|
+
params = {"start_date": date(2024, 11, 1), "end_date": date(2024, 12, 31)}
|
|
284
|
+
job = AdjFactor(session=mock_session, params=params, cache=False)
|
|
285
|
+
|
|
286
|
+
with patch.object(job, "_fetchall", return_value=sample_source_data):
|
|
287
|
+
result = job.run()
|
|
288
|
+
assert len(result) > 0
|
|
289
|
+
|
|
290
|
+
def test_run_calls_transform(self, mock_session, sample_source_data):
|
|
291
|
+
"""测试运行时调用transform"""
|
|
292
|
+
job = AdjFactor(session=mock_session, cache=False)
|
|
293
|
+
|
|
294
|
+
with (
|
|
295
|
+
patch.object(job, "_fetchall", return_value=sample_source_data),
|
|
296
|
+
patch.object(job, "transform", wraps=job.transform) as mock_transform,
|
|
297
|
+
):
|
|
298
|
+
job.run()
|
|
299
|
+
mock_transform.assert_called_once()
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
# Cache Tests
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
class TestAdjFactorCache:
|
|
306
|
+
def test_cache_persistence(self, mock_session, sample_source_data):
|
|
307
|
+
"""测试缓存持久性"""
|
|
308
|
+
job = AdjFactor(session=mock_session, cache=True)
|
|
309
|
+
|
|
310
|
+
with (
|
|
311
|
+
patch.object(job, "_fetchall", return_value=sample_source_data),
|
|
312
|
+
patch.object(job, "_load_cache", return_value=None),
|
|
313
|
+
patch.object(job, "_save_cache") as mock_save,
|
|
314
|
+
):
|
|
315
|
+
job.run()
|
|
316
|
+
mock_save.assert_called_once()
|
|
317
|
+
|
|
318
|
+
def test_run_without_cache(self, mock_session, sample_source_data):
|
|
319
|
+
"""测试不使用缓存运行"""
|
|
320
|
+
job = AdjFactor(session=mock_session, cache=False)
|
|
321
|
+
|
|
322
|
+
with patch.object(job, "_fetchall", return_value=sample_source_data):
|
|
323
|
+
result = job.run()
|
|
324
|
+
assert len(result) == 3
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
# Integration Tests
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
class TestAdjFactorIntegration:
|
|
331
|
+
def test_full_workflow(self, mock_session, sample_source_data):
|
|
332
|
+
"""测试完整工作流程"""
|
|
333
|
+
job = AdjFactor(
|
|
334
|
+
session=mock_session,
|
|
335
|
+
params={"ts_code": "000001.SZ"},
|
|
336
|
+
cache=False,
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
with patch.object(job, "_fetchall", return_value=sample_source_data):
|
|
340
|
+
# Run job
|
|
341
|
+
result = job.run()
|
|
342
|
+
assert not result.empty
|
|
343
|
+
|
|
344
|
+
def test_large_dataset_handling(self, mock_session):
|
|
345
|
+
"""测试大数据集处理"""
|
|
346
|
+
# Create large dataset
|
|
347
|
+
large_data = pd.DataFrame(
|
|
348
|
+
{
|
|
349
|
+
"ts_code": [f"{i:06d}.SZ" for i in range(1000)],
|
|
350
|
+
"trade_date": ["20241201"] * 1000,
|
|
351
|
+
"adj_factor": [1.0 + i * 0.001 for i in range(1000)],
|
|
352
|
+
}
|
|
353
|
+
)
|
|
354
|
+
job = AdjFactor(session=mock_session, cache=False)
|
|
355
|
+
with patch.object(job, "_fetchall", return_value=large_data):
|
|
356
|
+
result = job.run()
|
|
357
|
+
assert len(result) == 1000
|
|
358
|
+
|
|
359
|
+
def test_missing_fields_handling(self, mock_session):
|
|
360
|
+
"""测试缺失字段处理"""
|
|
361
|
+
data = pd.DataFrame(
|
|
362
|
+
{
|
|
363
|
+
"ts_code": ["000001.SZ", "000002.SZ"],
|
|
364
|
+
"trade_date": ["20241201", "20241201"],
|
|
365
|
+
"adj_factor": [1.0, None],
|
|
366
|
+
}
|
|
367
|
+
)
|
|
368
|
+
job = AdjFactor(session=mock_session, cache=False)
|
|
369
|
+
with patch.object(job, "_fetchall", return_value=data):
|
|
370
|
+
result = job.run()
|
|
371
|
+
# Should handle None/NaN gracefully
|
|
372
|
+
assert len(result) == 2
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from xfintech.data.source.tushare.stock.capflow.capflow import Capflow
|
|
4
|
+
from xfintech.data.source.tushare.stock.capflow.constant import (
|
|
5
|
+
KEY,
|
|
6
|
+
NAME,
|
|
7
|
+
PAGINATE,
|
|
8
|
+
SOURCE,
|
|
9
|
+
TARGET,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"Capflow",
|
|
14
|
+
"KEY",
|
|
15
|
+
"NAME",
|
|
16
|
+
"PAGINATE",
|
|
17
|
+
"SOURCE",
|
|
18
|
+
"TARGET",
|
|
19
|
+
]
|