lixinger-python 0.3.1__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/.claude/settings.local.json +2 -1
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/PKG-INFO +1 -1
- lixinger_python-0.3.2/examples/index_constituent_weightings_example.py +45 -0
- lixinger_python-0.3.2/examples/index_constituents_example.py +46 -0
- lixinger_python-0.3.2/examples/index_info_example.py +42 -0
- lixinger_python-0.3.2/lixinger/api/cn/index/constituent_weightings.py +109 -0
- lixinger_python-0.3.2/lixinger/api/cn/index/constituents.py +112 -0
- lixinger_python-0.3.2/lixinger/api/cn/index/index.py +130 -0
- lixinger_python-0.3.2/lixinger/api/cn/index/namespace.py +85 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/client.py +35 -8
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/pyproject.toml +1 -1
- lixinger_python-0.3.2/tests/api/cn/index/test_constituents.py +126 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/uv.lock +1 -1
- lixinger_python-0.3.1/lixinger/api/cn/index/constituent_weightings.py +0 -71
- lixinger_python-0.3.1/lixinger/api/cn/index/constituents.py +0 -71
- lixinger_python-0.3.1/lixinger/api/cn/index/index.py +0 -69
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/.env.example +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/.github/copilot-instructions.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/.github/workflows/README.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/.github/workflows/pr-checks.yml +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/.gitignore +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/.pre-commit-config.yaml +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/.python-version +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/.ruff.toml +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/ADD_NEW_API_QUICK.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/AGENTS.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/CHANGELOG.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/CLAUDE.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/DOCS.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/LICENSE +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/MANIFEST.in +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/PUBLISHING.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/README.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/SETUP.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/codecov.yml +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/client.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/company/announcement.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/company/candlestick.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/company/company.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/company/dividend.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/company/equity_change.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/company/fs/non_financial.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/company/fundamental/bank.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/company/fundamental/insurance.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/company/fundamental/non_financial.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/company/fundamental/other_financial.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/company/fundamental/security.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/company/indices.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/company/profile.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/fund/announcement.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/fund/asset_combination.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/fund/asset_industry_combination.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/fund/candlestick.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/fund/fund.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/fund/profile.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/fund/shareholdings.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/index/candlestick.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/index/constituent_weightings.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/index/constituents.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/index/drawdown.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/index/fundamental.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/index/index.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/index/tracking_fund.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/api/overview.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/development/code-style.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/development/contributing.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/development/testing.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/examples/company.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/examples/fund.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/examples/index.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/getting-started/configuration.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/getting-started/installation.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/getting-started/quickstart.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/docs/index.md +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/examples/company_example.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/examples/company_profile_example.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/fund_response.json +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/base.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/announcement.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/candlestick.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/company.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/dividend.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/equity_change.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/fs/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/fs/non_financial.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/fundamental/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/fundamental/bank.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/fundamental/insurance.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/fundamental/non_financial.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/fundamental/other_financial.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/fundamental/security.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/indices.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/namespace.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/company/profile.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/fund/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/fund/announcement.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/fund/asset_combination.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/fund/asset_industry_combination.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/fund/candlestick.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/fund/fund.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/fund/profile.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/fund/shareholdings.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/index/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/index/candlestick.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/index/drawdown.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/index/fundamental.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/api/cn/index/tracking_fund.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/config.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/exceptions.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/announcement.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/candlestick.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/company.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/dividend.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/equity_change.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/fs/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/fs/non_financial.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/fundamental/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/fundamental/bank.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/fundamental/insurance.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/fundamental/non_financial.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/fundamental/other_financial.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/fundamental/security.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/company/indices.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/fund/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/fund/announcement.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/fund/asset_combination.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/fund/asset_industry_combination.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/fund/candlestick.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/fund/fund.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/fund/profile.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/fund/shareholdings.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/index/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/index/candlestick.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/index/constituent_weightings.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/index/constituents.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/index/drawdown.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/index/fundamental.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/index/index.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/models/cn/index/tracking_fund.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/py.typed +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/utils/__init__.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/utils/api.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/utils/dataframe.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/utils/dict.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/utils/rate_limiter.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/lixinger/utils/retry.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/mkdocs.yml +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/mypy.ini +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/scripts/explore_api.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/scripts/generate_docs.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/scripts/publish.sh +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/api/cn/company/test_announcement.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/api/cn/company/test_dividend.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/conftest.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_candlestick.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_client.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_cn_index_candlestick.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_cn_index_constituent_weightings.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_company.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_company_profile.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_equity_change.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_fund.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_fund_announcement.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_fund_asset_combination.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_fund_asset_industry_combination.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_fund_candlestick.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_fund_profile.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_fund_shareholdings.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_fundamental.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_fundamental_bank.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_fundamental_security.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_index.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_index_constituents.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_index_drawdown.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_index_fundamental.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_indices.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_integration.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_non_financial_statements.py +0 -0
- {lixinger_python-0.3.1 → lixinger_python-0.3.2}/tests/test_tracking_fund.py +0 -0
|
@@ -105,7 +105,8 @@
|
|
|
105
105
|
"Bash(cat > /tmp/final_summary.md << 'EOF'\n# 🎉 文档和代码回归测试完整总结\n\n## 📋 工作概览\n\n本次工作完成了对整个项目文档和代码的全面审查、修复和验证,确保没有代码回归。\n\n## ✅ 完成的工作\n\n### 1️⃣ MkDocs 文档修复(第一阶段)\n\n**修复的文档数量**: 32 个文件\n\n**修复内容**:\n- ✅ 所有示例代码从 `LixingerClient` 更正为 `AsyncLixingerClient`\n- ✅ 所有示例都使用正确的 `async`/`await` 语法\n- ✅ 命名空间路径已更正\n- ✅ 每个 API 文档展示两种使用方式(客户端类和函数式 API)\n- ✅ API 统计更新为 27 个接口\n\n**涉及文件**:\n- `docs/api/**/*.md` \\(27 个 API 文档\\)\n- `docs/getting-started/quickstart.md`\n- `docs/index.md`\n- `docs/examples/company.md`\n- `docs/api/overview.md`\n- `scripts/generate_docs.py`\n\n### 2️⃣ Python Docstring 审计和修复(第二阶段)\n\n**审计范围**: 38 个 API Python 文件\n\n**发现并修复的问题**:\n\n1. **4 个文件使用了错误的类名**:\n - `company/profile.py` ✅\n - `company/company.py` ✅\n - `company/equity_change.py` ✅\n - `index/tracking_fund.py` ✅\n\n2. **2 个文件缺少示例**:\n - `fundamental/bank.py` ✅ 添加了完整示例\n - `fundamental/security.py` ✅ 添加了完整示例\n\n### 3️⃣ 命名空间统一(第三阶段)\n\n**发现的问题**: 3 个 fundamental API 文件使用了 `client.cn_company` 而不是推荐的 `client.company`\n\n**修复的文件**:\n- `fundamental/insurance.py` ✅\n- `fundamental/non_financial.py` ✅\n- `fundamental/other_financial.py` ✅\n\n**现在的规范**:\n- Company APIs: 使用 `client.company.*` \\(简洁别名\\)\n- Index APIs: 使用 `client.cn_index_*` \\(扁平结构\\)\n- Fund APIs: 使用 `client.cn_fund_*` \\(扁平结构\\)\n\n### 4️⃣ 代码质量修复(第四阶段)\n\n**修复的问题**:\n1. ✅ 删除了 `lixinger/__init__.py` 中的重复导入\n2. ✅ 格式化了 `lixinger/client.py`\n\n## 🧪 测试和验证结果\n\n### ✅ 所有测试通过\n\n```\n65 passed, 26 deselected, 1 warning in 2.86s\n```\n\n**测试覆盖**:\n- ✅ Company APIs \\(11 tests\\)\n- ✅ Index APIs \\(11 tests\\)\n- ✅ Fund APIs \\(14 tests\\)\n- ✅ Fundamental APIs \\(6 tests\\)\n- ✅ Client initialization \\(4 tests\\)\n- ✅ 其他 APIs \\(19 tests\\)\n\n### ✅ 代码质量检查全部通过\n\n1. **Ruff 代码检查**: ✅ All checks passed!\n2. **Ruff 格式检查**: ✅ 111 files already formatted\n3. **Mypy 类型检查**: ✅ Success: no issues found in 79 source files\n4. **MkDocs 构建**: ✅ Documentation built in 5.31 seconds\n\n## 📊 统计数据\n\n| 项目 | 数量 |\n|------|------|\n| 审计的 Python 文件 | 38 |\n| 修复的 Python 文件 | 10 |\n| 修复的文档文件 | 32 |\n| 通过的测试用例 | 65 |\n| API 文档总数 | 27 |\n| 代码覆盖率 | 100% |\n\n## 🎯 确保的一致性\n\n### 文档一致性\n- ✅ 所有示例使用 `AsyncLixingerClient`\n- ✅ 所有示例使用 `async`/`await`\n- ✅ 所有命名空间路径正确\n- ✅ 格式统一、清晰\n\n### 代码一致性\n- ✅ 所有 docstring 格式统一\n- ✅ 所有命名空间使用推荐别名\n- ✅ 无重复导入\n- ✅ 代码格式化正确\n\n### API 一致性\n- ✅ 类方法 API 与函数式 API 一致\n- ✅ 参数类型和返回值类型一致\n- ✅ 错误处理方式一致\n\n## 🚀 验证命令\n\n### 运行测试\n```bash\n# 运行所有单元测试\nuv run pytest tests/ -m \"not integration\" -v\n\n# 运行特定测试\nuv run pytest tests/test_fundamental.py -v\n```\n\n### 代码质量检查\n```bash\n# Ruff 检查\nuv run ruff check .\n\n# 格式检查\nuv run ruff format --check .\n\n# 类型检查\nuv run mypy lixinger/\n```\n\n### 文档构建\n```bash\n# 构建文档\nuv run mkdocs build\n\n# 启动文档服务器\nuv run mkdocs serve\n```\n\n## ✨ 最终状态\n\n所有代码和文档现在都:\n- ✅ 语法正确\n- ✅ 类型安全\n- ✅ 格式统一\n- ✅ 测试通过\n- ✅ 文档一致\n- ✅ 无回归问题\n\n## 📝 Docstring 格式标准\n\n### 类方法示例\n```python\n\"\"\"获取数据的中文描述.\n\nAPI Endpoint: /cn/...\nAPI Method: POST\nAPI Doc: https://www.lixinger.com/open/api/doc?api-key=...\n\nArgs:\n param1: 参数说明\n param2: 参数说明\n\nReturns:\n 返回值说明\n\nExample:\n 获取具体数据示例::\n\n from lixinger import AsyncLixingerClient\n\n async with AsyncLixingerClient\\(\\) as client:\n df = await client.namespace.api_name.method\\(\n param1=\"value1\"\n \\)\n print\\(df\\)\n\n\"\"\"\n```\n\n### 函数式 API 示例\n```python\n\"\"\"获取数据的中文描述.\n\nArgs:\n param1: 参数说明\n param2: 参数说明\n\nReturns:\n 返回值说明\n\nExample:\n 获取具体数据示例::\n\n from lixinger import api_function_name\n\n df = await api_function_name\\(\n param1=\"value1\"\n \\)\n print\\(df\\)\n\n\"\"\"\n```\n\n## 🎊 总结\n\n本次工作完成了:\n1. ✅ 全面的文档审查和修复\n2. ✅ 所有 Python docstring 的统一和增强\n3. ✅ 命名空间的一致性优化\n4. ✅ 代码质量问题的修复\n5. ✅ 完整的回归测试验证\n\n**没有发现任何代码回归问题!** 所有测试通过,所有代码质量检查通过,项目处于健康状态。🎉\nEOF\ncat /tmp/final_summary.md)",
|
|
106
106
|
"Bash(grep -r \"API Endpoint:\" lixinger/api/cn/company/*.py | head -10)",
|
|
107
107
|
"Bash(uv run mypy lixinger/api/cn/company/dividend.py)",
|
|
108
|
-
"Bash(uv run mypy lixinger/models/cn/company/dividend.py lixinger/api/cn/company/dividend.py)"
|
|
108
|
+
"Bash(uv run mypy lixinger/models/cn/company/dividend.py lixinger/api/cn/company/dividend.py)",
|
|
109
|
+
"Bash(uv run:*)"
|
|
109
110
|
]
|
|
110
111
|
}
|
|
111
112
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Index constituent weightings API example.
|
|
2
|
+
|
|
3
|
+
This example demonstrates how to use the index constituent weightings API
|
|
4
|
+
to retrieve the weighting (proportion) of constituent stocks in an index over time.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
|
|
9
|
+
from lixinger import AsyncLixingerClient, get_constituent_weightings
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def main():
|
|
13
|
+
"""Demonstrate usage of index constituent weightings API."""
|
|
14
|
+
# Method 1: Using the async client with context manager (recommended)
|
|
15
|
+
print("Method 1: Using async client...")
|
|
16
|
+
async with AsyncLixingerClient() as client:
|
|
17
|
+
# Get constituent weightings of CSI 300 Index
|
|
18
|
+
print("\nFetching constituent weightings of CSI 300 Index...")
|
|
19
|
+
df = await client.index.get_constituent_weightings(
|
|
20
|
+
stock_code="000300", # CSI 300
|
|
21
|
+
start_date="2024-01-01",
|
|
22
|
+
end_date="2024-12-31",
|
|
23
|
+
)
|
|
24
|
+
print(f"Total records: {len(df)}")
|
|
25
|
+
print("\nTop 10 stocks by weight:")
|
|
26
|
+
top_stocks = df.sort_values("weighting", ascending=False).head(10)
|
|
27
|
+
print(top_stocks[["date", "stock_code", "weighting"]])
|
|
28
|
+
|
|
29
|
+
# Analyze weighting distribution
|
|
30
|
+
print("\nWeighting statistics:")
|
|
31
|
+
print(df["weighting"].describe())
|
|
32
|
+
|
|
33
|
+
# Method 2: Using functional API
|
|
34
|
+
print("\nMethod 2: Using functional API...")
|
|
35
|
+
df = await get_constituent_weightings(
|
|
36
|
+
stock_code="000300",
|
|
37
|
+
start_date="2024-06-01",
|
|
38
|
+
end_date="2024-06-30",
|
|
39
|
+
)
|
|
40
|
+
print(f"Total records: {len(df)}")
|
|
41
|
+
print(df.head(10))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
if __name__ == "__main__":
|
|
45
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Index constituents API example.
|
|
2
|
+
|
|
3
|
+
This example demonstrates how to use the index constituents API
|
|
4
|
+
to retrieve constituent stocks of A-share indices.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
|
|
9
|
+
from lixinger import AsyncLixingerClient, get_constituents
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def main():
|
|
13
|
+
"""Demonstrate usage of index constituents API."""
|
|
14
|
+
# Method 1: Using the async client with context manager (recommended)
|
|
15
|
+
print("Method 1: Using async client...")
|
|
16
|
+
async with AsyncLixingerClient() as client:
|
|
17
|
+
# Get constituents of Shanghai Composite Index (000001.SH)
|
|
18
|
+
print("\nFetching constituents of Shanghai Composite Index...")
|
|
19
|
+
df = await client.index.get_constituents(
|
|
20
|
+
stock_codes=["000001"],
|
|
21
|
+
date="2024-12-31",
|
|
22
|
+
)
|
|
23
|
+
print(f"Total constituents: {len(df)}")
|
|
24
|
+
print(df.head(10))
|
|
25
|
+
|
|
26
|
+
# Get constituents of multiple indices
|
|
27
|
+
print("\nFetching constituents of multiple indices...")
|
|
28
|
+
df = await client.index.get_constituents(
|
|
29
|
+
stock_codes=["000001", "399001"], # Shanghai & Shenzhen Composite
|
|
30
|
+
date="2024-12-31",
|
|
31
|
+
)
|
|
32
|
+
print(f"Total constituents: {len(df)}")
|
|
33
|
+
print(df.head(10))
|
|
34
|
+
|
|
35
|
+
# Method 2: Using functional API
|
|
36
|
+
print("\nMethod 2: Using functional API...")
|
|
37
|
+
df = await get_constituents(
|
|
38
|
+
stock_codes=["000300"], # CSI 300
|
|
39
|
+
date="2024-12-31",
|
|
40
|
+
)
|
|
41
|
+
print(f"Total constituents: {len(df)}")
|
|
42
|
+
print(df.head(10))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
if __name__ == "__main__":
|
|
46
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Index information API example.
|
|
2
|
+
|
|
3
|
+
This example demonstrates how to use the index API
|
|
4
|
+
to retrieve basic information about stock indices.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
|
|
9
|
+
from lixinger import AsyncLixingerClient, get_index
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def main():
|
|
13
|
+
"""Demonstrate usage of index information API."""
|
|
14
|
+
# Method 1: Using the async client with context manager (recommended)
|
|
15
|
+
print("Method 1: Using async client...")
|
|
16
|
+
async with AsyncLixingerClient() as client:
|
|
17
|
+
# Get information for specific indices
|
|
18
|
+
print("\nFetching info for CSI 300 and CSI 500...")
|
|
19
|
+
df = await client.index.get_index(stock_codes=["000300", "000905"])
|
|
20
|
+
print(df[["name", "stock_code", "source", "launch_date"]])
|
|
21
|
+
|
|
22
|
+
# Get all CSI indices
|
|
23
|
+
print("\nFetching all CSI indices...")
|
|
24
|
+
df = await client.index.get_index(source="csi")
|
|
25
|
+
print(f"Total CSI indices: {len(df)}")
|
|
26
|
+
print(df[["name", "stock_code", "rebalancing_frequency"]].head(10))
|
|
27
|
+
|
|
28
|
+
# Get all indices (may be large)
|
|
29
|
+
print("\nFetching all available indices...")
|
|
30
|
+
df = await client.index.get_index()
|
|
31
|
+
print(f"Total indices: {len(df)}")
|
|
32
|
+
print("\nIndices by source:")
|
|
33
|
+
print(df["source"].value_counts())
|
|
34
|
+
|
|
35
|
+
# Method 2: Using functional API
|
|
36
|
+
print("\nMethod 2: Using functional API...")
|
|
37
|
+
df = await get_index(stock_codes=["000001"]) # Shanghai Composite
|
|
38
|
+
print(df[["name", "stock_code", "source", "launch_date"]])
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
if __name__ == "__main__":
|
|
42
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""Index constituent weightings APIs."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
from lixinger.api.base import BaseAPI
|
|
8
|
+
from lixinger.models.cn.index.constituent_weightings import ConstituentWeighting
|
|
9
|
+
from lixinger.utils.api import api
|
|
10
|
+
from lixinger.utils.dataframe import get_response_df
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ConstituentWeightingsAPI(BaseAPI):
|
|
14
|
+
"""Index constituent weightings APIs."""
|
|
15
|
+
|
|
16
|
+
async def get_constituent_weightings(
|
|
17
|
+
self,
|
|
18
|
+
stock_code: str,
|
|
19
|
+
start_date: str,
|
|
20
|
+
end_date: str,
|
|
21
|
+
) -> pd.DataFrame:
|
|
22
|
+
"""获取指数成分股权重数据.
|
|
23
|
+
|
|
24
|
+
API Endpoint: /cn/index/constituent-weightings
|
|
25
|
+
API Method: POST
|
|
26
|
+
Documentation: https://www.lixinger.com/open/api/doc?api-key=cn/index/constituent-weightings
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
stock_code: 指数代码,如 "000300" (沪深300)
|
|
30
|
+
start_date: 开始日期 (YYYY-MM-DD)
|
|
31
|
+
end_date: 结束日期 (YYYY-MM-DD)
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
包含指数成分股权重信息的 DataFrame,包含以下字段:
|
|
35
|
+
- date: 日期
|
|
36
|
+
- stock_code: 成分股代码
|
|
37
|
+
- weighting: 权重(0-1之间的浮点数)
|
|
38
|
+
|
|
39
|
+
Example:
|
|
40
|
+
获取沪深300指数成分股权重::
|
|
41
|
+
|
|
42
|
+
from lixinger import AsyncLixingerClient
|
|
43
|
+
|
|
44
|
+
async with AsyncLixingerClient() as client:
|
|
45
|
+
# 查询指定时间段的成分股权重
|
|
46
|
+
df = await client.index.get_constituent_weightings(
|
|
47
|
+
stock_code="000300",
|
|
48
|
+
start_date="2024-01-01",
|
|
49
|
+
end_date="2024-12-31"
|
|
50
|
+
)
|
|
51
|
+
print(df)
|
|
52
|
+
|
|
53
|
+
# 查看权重最大的成分股
|
|
54
|
+
top_stocks = df.sort_values("weighting", ascending=False).head(10)
|
|
55
|
+
print(top_stocks)
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
payload: dict[str, Any] = {
|
|
59
|
+
"stockCode": stock_code,
|
|
60
|
+
"startDate": start_date,
|
|
61
|
+
"endDate": end_date,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
data = await self._request("POST", "/cn/index/constituent-weightings", json=payload)
|
|
65
|
+
return get_response_df(data, ConstituentWeighting)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# Functional API instance
|
|
69
|
+
_api_instance = ConstituentWeightingsAPI()
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@api
|
|
73
|
+
async def get_constituent_weightings(
|
|
74
|
+
stock_code: str,
|
|
75
|
+
start_date: str,
|
|
76
|
+
end_date: str,
|
|
77
|
+
) -> pd.DataFrame:
|
|
78
|
+
"""获取指数成分股权重数据.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
stock_code: 指数代码,如 "000300" (沪深300)
|
|
82
|
+
start_date: 开始日期 (YYYY-MM-DD)
|
|
83
|
+
end_date: 结束日期 (YYYY-MM-DD)
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
包含指数成分股权重信息的 DataFrame,包含以下字段:
|
|
87
|
+
- date: 日期
|
|
88
|
+
- stock_code: 成分股代码
|
|
89
|
+
- weighting: 权重(0-1之间的浮点数)
|
|
90
|
+
|
|
91
|
+
Example:
|
|
92
|
+
获取沪深300指数成分股权重::
|
|
93
|
+
|
|
94
|
+
from lixinger import get_constituent_weightings
|
|
95
|
+
|
|
96
|
+
# 查询指定时间段的成分股权重
|
|
97
|
+
df = await get_constituent_weightings(
|
|
98
|
+
stock_code="000300",
|
|
99
|
+
start_date="2024-01-01",
|
|
100
|
+
end_date="2024-12-31"
|
|
101
|
+
)
|
|
102
|
+
print(df)
|
|
103
|
+
|
|
104
|
+
"""
|
|
105
|
+
return await _api_instance.get_constituent_weightings(
|
|
106
|
+
stock_code=stock_code,
|
|
107
|
+
start_date=start_date,
|
|
108
|
+
end_date=end_date,
|
|
109
|
+
)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""Index constituents APIs."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
from lixinger.api.base import BaseAPI
|
|
8
|
+
from lixinger.models.cn.index.constituents import Constituent
|
|
9
|
+
from lixinger.utils.api import api
|
|
10
|
+
from lixinger.utils.dataframe import get_response_df
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ConstituentsAPI(BaseAPI):
|
|
14
|
+
"""Index constituents APIs."""
|
|
15
|
+
|
|
16
|
+
async def get_constituents(
|
|
17
|
+
self,
|
|
18
|
+
stock_codes: list[str],
|
|
19
|
+
date: str,
|
|
20
|
+
) -> pd.DataFrame:
|
|
21
|
+
"""获取指数成分股列表.
|
|
22
|
+
|
|
23
|
+
API Endpoint: /cn/index/constituents
|
|
24
|
+
API Method: POST
|
|
25
|
+
Documentation: https://www.lixinger.com/open/api/doc?api-key=cn/index/constituents
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
stock_codes: 指数代码列表,如 ["000001.SH", "399001.SZ"]
|
|
29
|
+
date: 查询日期 (YYYY-MM-DD),返回该日期的成分股列表
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
包含指数成分股信息的 DataFrame,包含以下字段:
|
|
33
|
+
- index_stock_code: 指数代码
|
|
34
|
+
- stock_code: 成分股代码
|
|
35
|
+
- area_code: 地区代码
|
|
36
|
+
- market: 市场
|
|
37
|
+
|
|
38
|
+
Example:
|
|
39
|
+
获取沪深300指数的成分股::
|
|
40
|
+
|
|
41
|
+
from lixinger import AsyncLixingerClient
|
|
42
|
+
|
|
43
|
+
async with AsyncLixingerClient() as client:
|
|
44
|
+
# 查询单个指数的成分股
|
|
45
|
+
df = await client.index.get_constituents(
|
|
46
|
+
stock_codes=["000300.SH"],
|
|
47
|
+
date="2024-12-31"
|
|
48
|
+
)
|
|
49
|
+
print(df)
|
|
50
|
+
|
|
51
|
+
# 查询多个指数的成分股
|
|
52
|
+
df = await client.index.get_constituents(
|
|
53
|
+
stock_codes=["000001.SH", "399001.SZ"],
|
|
54
|
+
date="2024-12-31"
|
|
55
|
+
)
|
|
56
|
+
print(df)
|
|
57
|
+
|
|
58
|
+
"""
|
|
59
|
+
payload: dict[str, Any] = {
|
|
60
|
+
"stockCodes": stock_codes,
|
|
61
|
+
"date": date,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
data = await self._request("POST", "/cn/index/constituents", json=payload)
|
|
65
|
+
flattened_data = []
|
|
66
|
+
for item in data:
|
|
67
|
+
index_stock_code = item["stockCode"]
|
|
68
|
+
for constituent in item["constituents"]:
|
|
69
|
+
constituent["index_stock_code"] = index_stock_code
|
|
70
|
+
flattened_data.append(constituent)
|
|
71
|
+
return get_response_df(flattened_data, Constituent)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# Functional API instance
|
|
75
|
+
_api_instance = ConstituentsAPI()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@api
|
|
79
|
+
async def get_constituents(
|
|
80
|
+
stock_codes: list[str],
|
|
81
|
+
date: str,
|
|
82
|
+
) -> pd.DataFrame:
|
|
83
|
+
"""获取指数成分股列表.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
stock_codes: 指数代码列表,如 ["000001.SH", "399001.SZ"]
|
|
87
|
+
date: 查询日期 (YYYY-MM-DD),返回该日期的成分股列表
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
包含指数成分股信息的 DataFrame,包含以下字段:
|
|
91
|
+
- index_stock_code: 指数代码
|
|
92
|
+
- stock_code: 成分股代码
|
|
93
|
+
- area_code: 地区代码
|
|
94
|
+
- market: 市场
|
|
95
|
+
|
|
96
|
+
Example:
|
|
97
|
+
获取沪深300指数的成分股::
|
|
98
|
+
|
|
99
|
+
from lixinger import get_constituents
|
|
100
|
+
|
|
101
|
+
# 查询单个指数的成分股
|
|
102
|
+
df = await get_constituents(
|
|
103
|
+
stock_codes=["000300.SH"],
|
|
104
|
+
date="2024-12-31"
|
|
105
|
+
)
|
|
106
|
+
print(df)
|
|
107
|
+
|
|
108
|
+
"""
|
|
109
|
+
return await _api_instance.get_constituents(
|
|
110
|
+
stock_codes=stock_codes,
|
|
111
|
+
date=date,
|
|
112
|
+
)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"""Index-related APIs.
|
|
2
|
+
|
|
3
|
+
This module provides APIs for querying index information.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
import pandas as pd
|
|
9
|
+
|
|
10
|
+
from lixinger.api.base import BaseAPI
|
|
11
|
+
from lixinger.models.cn.index import Index
|
|
12
|
+
from lixinger.utils.api import api
|
|
13
|
+
from lixinger.utils.dataframe import get_response_df
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class IndexAPI(BaseAPI):
|
|
17
|
+
"""Index related APIs."""
|
|
18
|
+
|
|
19
|
+
async def get_index(
|
|
20
|
+
self,
|
|
21
|
+
stock_codes: list[str] | None = None,
|
|
22
|
+
source: str | None = None,
|
|
23
|
+
) -> pd.DataFrame:
|
|
24
|
+
"""获取指数基本信息.
|
|
25
|
+
|
|
26
|
+
API Endpoint: /cn/index
|
|
27
|
+
API Method: POST
|
|
28
|
+
Documentation: https://www.lixinger.com/open/api/doc?api-key=cn/index
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
stock_codes: 指数代码列表,如 ["000300", "000001"]。不传则返回所有指数
|
|
32
|
+
source: 指数来源筛选,可选值:
|
|
33
|
+
- "csi": 中证指数
|
|
34
|
+
- "cni": 国证指数
|
|
35
|
+
- "sse": 上证指数
|
|
36
|
+
- "szse": 深证指数
|
|
37
|
+
不传则返回所有来源的指数
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
包含指数基本信息的 DataFrame,包含以下字段:
|
|
41
|
+
- name: 指数名称
|
|
42
|
+
- stock_code: 指数代码
|
|
43
|
+
- area_code: 地区代码
|
|
44
|
+
- market: 市场
|
|
45
|
+
- source: 指数来源 (csi/cni/sse/szse等)
|
|
46
|
+
- fs_table_type: 财报类型 (hybrid/non_financial等)
|
|
47
|
+
- currency: 货币单位
|
|
48
|
+
- launch_date: 发布日期
|
|
49
|
+
- rebalancing_frequency: 调仓频率 (semi-annually/quarterly等)
|
|
50
|
+
- caculation_method: 计算方法 (grading_weighted等)
|
|
51
|
+
- series: 指数系列分类
|
|
52
|
+
|
|
53
|
+
Example:
|
|
54
|
+
获取指数基本信息::
|
|
55
|
+
|
|
56
|
+
from lixinger import AsyncLixingerClient
|
|
57
|
+
|
|
58
|
+
async with AsyncLixingerClient() as client:
|
|
59
|
+
# 获取指定指数的信息
|
|
60
|
+
df = await client.index.get_index(
|
|
61
|
+
stock_codes=["000300", "000905"]
|
|
62
|
+
)
|
|
63
|
+
print(df[["name", "stock_code", "source", "launch_date"]])
|
|
64
|
+
|
|
65
|
+
# 获取中证指数系列
|
|
66
|
+
df = await client.index.get_index(source="csi")
|
|
67
|
+
print(df[["name", "stock_code"]])
|
|
68
|
+
|
|
69
|
+
# 获取所有指数
|
|
70
|
+
df = await client.index.get_index()
|
|
71
|
+
print(f"Total indices: {len(df)}")
|
|
72
|
+
|
|
73
|
+
"""
|
|
74
|
+
payload: dict[str, Any] = {}
|
|
75
|
+
if stock_codes is not None:
|
|
76
|
+
payload["stockCodes"] = stock_codes
|
|
77
|
+
if source is not None:
|
|
78
|
+
payload["source"] = source
|
|
79
|
+
|
|
80
|
+
data = await self._request("POST", "/cn/index", json=payload)
|
|
81
|
+
return get_response_df(data, Index)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# Functional API instance
|
|
85
|
+
_api_instance = IndexAPI()
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@api
|
|
89
|
+
async def get_index(
|
|
90
|
+
stock_codes: list[str] | None = None,
|
|
91
|
+
source: str | None = None,
|
|
92
|
+
) -> pd.DataFrame:
|
|
93
|
+
"""获取指数基本信息.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
stock_codes: 指数代码列表,如 ["000300", "000001"]。不传则返回所有指数
|
|
97
|
+
source: 指数来源筛选 (csi/cni/sse/szse)。不传则返回所有来源
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
包含指数基本信息的 DataFrame,包含以下字段:
|
|
101
|
+
- name: 指数名称
|
|
102
|
+
- stock_code: 指数代码
|
|
103
|
+
- area_code: 地区代码
|
|
104
|
+
- market: 市场
|
|
105
|
+
- source: 指数来源
|
|
106
|
+
- fs_table_type: 财报类型
|
|
107
|
+
- currency: 货币单位
|
|
108
|
+
- launch_date: 发布日期
|
|
109
|
+
- rebalancing_frequency: 调仓频率
|
|
110
|
+
- caculation_method: 计算方法
|
|
111
|
+
- series: 指数系列分类
|
|
112
|
+
|
|
113
|
+
Example:
|
|
114
|
+
获取指数基本信息::
|
|
115
|
+
|
|
116
|
+
from lixinger import get_index
|
|
117
|
+
|
|
118
|
+
# 获取指定指数
|
|
119
|
+
df = await get_index(stock_codes=["000300", "000905"])
|
|
120
|
+
print(df[["name", "stock_code", "source"]])
|
|
121
|
+
|
|
122
|
+
# 获取中证指数系列
|
|
123
|
+
df = await get_index(source="csi")
|
|
124
|
+
print(df)
|
|
125
|
+
|
|
126
|
+
"""
|
|
127
|
+
return await _api_instance.get_index(
|
|
128
|
+
stock_codes=stock_codes,
|
|
129
|
+
source=source,
|
|
130
|
+
)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""Index namespace for grouping related APIs."""
|
|
2
|
+
|
|
3
|
+
from lixinger.api.cn.index.candlestick import IndexCandlestickAPI
|
|
4
|
+
from lixinger.api.cn.index.constituent_weightings import ConstituentWeightingsAPI
|
|
5
|
+
from lixinger.api.cn.index.constituents import ConstituentsAPI
|
|
6
|
+
from lixinger.api.cn.index.drawdown import DrawdownAPI
|
|
7
|
+
from lixinger.api.cn.index.fundamental import IndexFundamentalAPI
|
|
8
|
+
from lixinger.api.cn.index.index import IndexAPI
|
|
9
|
+
from lixinger.api.cn.index.tracking_fund import TrackingFundAPI
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class IndexNamespace:
|
|
13
|
+
"""Namespace for index-related APIs.
|
|
14
|
+
|
|
15
|
+
This class groups all index-related APIs under a single namespace.
|
|
16
|
+
Access APIs via their specific attributes:
|
|
17
|
+
|
|
18
|
+
- index: Index information API (get_index)
|
|
19
|
+
- constituents: Index constituents API (get_constituents)
|
|
20
|
+
- constituent_weightings: Index constituent weightings API (get_constituent_weightings)
|
|
21
|
+
- fundamental: Index fundamental data API (get_index_fundamental)
|
|
22
|
+
- candlestick: Index candlestick data API (get_candlestick)
|
|
23
|
+
- drawdown: Index drawdown data API (get_drawdown)
|
|
24
|
+
- tracking_fund: Index tracking fund API (get_tracking_fund)
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__( # noqa: PLR0913
|
|
29
|
+
self,
|
|
30
|
+
index: IndexAPI,
|
|
31
|
+
constituents: ConstituentsAPI,
|
|
32
|
+
constituent_weightings: ConstituentWeightingsAPI,
|
|
33
|
+
fundamental: IndexFundamentalAPI,
|
|
34
|
+
candlestick: IndexCandlestickAPI,
|
|
35
|
+
drawdown: DrawdownAPI,
|
|
36
|
+
tracking_fund: TrackingFundAPI,
|
|
37
|
+
):
|
|
38
|
+
"""Initialize the index namespace.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
index: Index information API
|
|
42
|
+
constituents: Index constituents API
|
|
43
|
+
constituent_weightings: Index constituent weightings API
|
|
44
|
+
fundamental: Index fundamental data API
|
|
45
|
+
candlestick: Index candlestick data API
|
|
46
|
+
drawdown: Index drawdown data API
|
|
47
|
+
tracking_fund: Index tracking fund API
|
|
48
|
+
|
|
49
|
+
"""
|
|
50
|
+
self.index = index
|
|
51
|
+
self.constituents = constituents
|
|
52
|
+
self.constituent_weightings = constituent_weightings
|
|
53
|
+
self.fundamental = fundamental
|
|
54
|
+
self.candlestick = candlestick
|
|
55
|
+
self.drawdown = drawdown
|
|
56
|
+
self.tracking_fund = tracking_fund
|
|
57
|
+
|
|
58
|
+
# Convenience aliases for shorter access
|
|
59
|
+
def get_index(self, *args, **kwargs):
|
|
60
|
+
"""Alias for index.get_index."""
|
|
61
|
+
return self.index.get_index(*args, **kwargs)
|
|
62
|
+
|
|
63
|
+
def get_constituents(self, *args, **kwargs):
|
|
64
|
+
"""Alias for constituents.get_constituents."""
|
|
65
|
+
return self.constituents.get_constituents(*args, **kwargs)
|
|
66
|
+
|
|
67
|
+
def get_constituent_weightings(self, *args, **kwargs):
|
|
68
|
+
"""Alias for constituent_weightings.get_constituent_weightings."""
|
|
69
|
+
return self.constituent_weightings.get_constituent_weightings(*args, **kwargs)
|
|
70
|
+
|
|
71
|
+
def get_fundamental(self, *args, **kwargs):
|
|
72
|
+
"""Alias for fundamental.get_fundamental."""
|
|
73
|
+
return self.fundamental.get_fundamental(*args, **kwargs)
|
|
74
|
+
|
|
75
|
+
def get_candlestick(self, *args, **kwargs):
|
|
76
|
+
"""Alias for candlestick.get_candlestick."""
|
|
77
|
+
return self.candlestick.get_candlestick(*args, **kwargs)
|
|
78
|
+
|
|
79
|
+
def get_drawdown(self, *args, **kwargs):
|
|
80
|
+
"""Alias for drawdown.get_drawdown."""
|
|
81
|
+
return self.drawdown.get_drawdown(*args, **kwargs)
|
|
82
|
+
|
|
83
|
+
def get_tracking_fund(self, *args, **kwargs):
|
|
84
|
+
"""Alias for tracking_fund.get_tracking_fund."""
|
|
85
|
+
return self.tracking_fund.get_tracking_fund(*args, **kwargs)
|
|
@@ -32,6 +32,7 @@ from lixinger.api.cn.index import (
|
|
|
32
32
|
IndexFundamentalAPI,
|
|
33
33
|
TrackingFundAPI,
|
|
34
34
|
)
|
|
35
|
+
from lixinger.api.cn.index.namespace import IndexNamespace
|
|
35
36
|
from lixinger.config import get_config_from_env
|
|
36
37
|
from lixinger.utils.rate_limiter import AsyncRateLimiter
|
|
37
38
|
|
|
@@ -156,15 +157,36 @@ class AsyncLixingerClient:
|
|
|
156
157
|
self.cn_company_indices = cn_company_indices
|
|
157
158
|
self.cn_company_dividend = cn_company_dividend
|
|
158
159
|
self.cn_company_announcement = cn_company_announcement
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
self.
|
|
162
|
-
|
|
160
|
+
|
|
161
|
+
# Index APIs
|
|
162
|
+
cn_index = IndexAPI(self._http_client, self.config, self._rate_limiter)
|
|
163
|
+
cn_index_constituents = ConstituentsAPI(self._http_client, self.config, self._rate_limiter)
|
|
164
|
+
cn_index_constituent_weightings = ConstituentWeightingsAPI(self._http_client, self.config, self._rate_limiter)
|
|
165
|
+
cn_index_candlestick = IndexCandlestickAPI(self._http_client, self.config, self._rate_limiter)
|
|
166
|
+
cn_index_drawdown = DrawdownAPI(self._http_client, self.config, self._rate_limiter)
|
|
167
|
+
cn_index_fundamental = IndexFundamentalAPI(self._http_client, self.config, self._rate_limiter)
|
|
168
|
+
cn_index_tracking_fund = TrackingFundAPI(self._http_client, self.config, self._rate_limiter)
|
|
169
|
+
|
|
170
|
+
# Index namespace (groups all index APIs)
|
|
171
|
+
self.cn_index = IndexNamespace(
|
|
172
|
+
index=cn_index,
|
|
173
|
+
constituents=cn_index_constituents,
|
|
174
|
+
constituent_weightings=cn_index_constituent_weightings,
|
|
175
|
+
fundamental=cn_index_fundamental,
|
|
176
|
+
candlestick=cn_index_candlestick,
|
|
177
|
+
drawdown=cn_index_drawdown,
|
|
178
|
+
tracking_fund=cn_index_tracking_fund,
|
|
163
179
|
)
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
self.
|
|
167
|
-
self.
|
|
180
|
+
|
|
181
|
+
# Legacy flat access for index APIs (deprecated, for backward compatibility)
|
|
182
|
+
self.cn_index_constituents = cn_index_constituents
|
|
183
|
+
self.cn_index_constituent_weightings = cn_index_constituent_weightings
|
|
184
|
+
self.cn_index_candlestick = cn_index_candlestick
|
|
185
|
+
self.cn_index_drawdown = cn_index_drawdown
|
|
186
|
+
self.cn_index_fundamental = cn_index_fundamental
|
|
187
|
+
self.cn_index_tracking_fund = cn_index_tracking_fund
|
|
188
|
+
|
|
189
|
+
# Fund APIs
|
|
168
190
|
self.cn_fund = FundAPI(self._http_client, self.config, self._rate_limiter)
|
|
169
191
|
self.cn_fund_profile = FundProfileAPI(self._http_client, self.config, self._rate_limiter)
|
|
170
192
|
self.cn_fund_candlestick = FundCandlestickAPI(self._http_client, self.config, self._rate_limiter)
|
|
@@ -190,6 +212,11 @@ class AsyncLixingerClient:
|
|
|
190
212
|
"""Alias for cn_company."""
|
|
191
213
|
return self.cn_company
|
|
192
214
|
|
|
215
|
+
@property
|
|
216
|
+
def index(self) -> IndexNamespace:
|
|
217
|
+
"""Alias for cn_index."""
|
|
218
|
+
return self.cn_index
|
|
219
|
+
|
|
193
220
|
@property
|
|
194
221
|
def candlestick(self) -> CandlestickAPI:
|
|
195
222
|
"""Alias for cn_company_candlestick."""
|