├── akshare ├── cal │ └── __init__.py ├── pro │ ├── __init__.py │ ├── cons.py │ ├── data_pro.py │ └── client.py ├── forex │ └── __init__.py ├── qdii │ └── __init__.py ├── stock_a │ └── __init__.py ├── qhkc │ └── __init__.py ├── qhkc_web │ └── __init__.py ├── data │ ├── crypto_info.zip │ └── __init__.py ├── air │ └── __init__.py ├── fx │ ├── __init__.py │ ├── cons.py │ ├── fx_c_swap_cm.py │ └── fx_quote_baidu.py ├── hf │ ├── __init__.py │ └── hf_sp500.py ├── nlp │ ├── __init__.py │ └── nlp_interface.py ├── article │ ├── __init__.py │ ├── cons.py │ ├── epu_index.py │ └── fred_md.py ├── bank │ ├── __init__.py │ └── cons.py ├── bond │ ├── __init__.py │ ├── bond_cb_sina.py │ ├── cons.py │ └── bond_nafmii.py ├── cost │ ├── __init__.py │ └── cost_living.py ├── crypto │ ├── __init__.py │ ├── crypto_hold.py │ └── crypto_bitcoin_cme.py ├── currency │ ├── __init__.py │ └── currency_safe.py ├── energy │ └── __init__.py ├── event │ └── __init__.py ├── fortune │ ├── __init__.py │ ├── fortune_forbes_500.py │ └── fortune_xincaifu_500.py ├── fund │ ├── __init__.py │ ├── fund_overview_em.py │ └── fund_init_em.py ├── futures │ ├── __init__.py │ ├── futures_rule_em.py │ ├── futures_comm_ctp.py │ ├── futures_rule.py │ ├── futures_stock_js.py │ ├── futures_index_ccidx.py │ ├── futures_foreign.py │ └── futures_inventory_em.py ├── index │ ├── __init__.py │ ├── index_zh_a_scope.py │ ├── index_hog.py │ ├── index_stock_us_sina.py │ ├── index_spot.py │ ├── index_csindex.py │ ├── index_eri.py │ └── index_global_sina.py ├── movie │ └── __init__.py ├── news │ └── __init__.py ├── option │ ├── __init__.py │ ├── option_contract_info_ctp.py │ ├── option_current_sse.py │ ├── option_margin.py │ ├── option_premium_analysis_em.py │ ├── option_czce.py │ ├── option_value_analysis_em.py │ ├── option_risk_indicator_sse.py │ └── option_risk_analysis_em.py ├── other │ └── __init__.py ├── rate │ └── __init__.py ├── reits │ └── __init__.py ├── spot │ └── __init__.py ├── stock │ ├── __init__.py │ ├── stock_news_cx.py │ ├── stock_stop.py │ ├── stock_industry_sw.py │ ├── stock_gsrl_em.py │ ├── stock_hot_search_baidu.py │ ├── stock_hk_fhpx_ths.py │ ├── stock_zh_a_tick_tx.py │ ├── stock_intraday_em.py │ ├── stock_intraday_sina.py │ ├── stock_hot_up_em.py │ ├── stock_us_js.py │ └── stock_info_em.py ├── tool │ ├── __init__.py │ └── trade_date_hist.py ├── utils │ ├── __init__.py │ ├── cons.py │ ├── tqdm.py │ ├── token_process.py │ ├── context.py │ ├── multi_decrypt.py │ └── func.py ├── economic │ ├── __init__.py │ └── marco_cnbs.py ├── file_fold │ └── __init__.py ├── interest_rate │ └── __init__.py ├── stock_feature │ ├── __init__.py │ ├── cons.py │ ├── stock_all_pb.py │ ├── stock_congestion_lg.py │ ├── stock_ttm_lyr.py │ ├── stock_ebs_lg.py │ ├── stock_zh_vote_baidu.py │ ├── stock_zh_valuation_baidu.py │ ├── stock_market_legu.py │ ├── stock_hk_valuation_baidu.py │ ├── stock_buffett_index_lg.py │ ├── stock_a_high_low.py │ ├── stock_fhps_ths.py │ ├── stock_tfp_em.py │ ├── stock_value_em.py │ └── stock_hsgt_min_em.py ├── stock_fundamental │ ├── __init__.py │ ├── stock_kcb_detail_sse.py │ ├── stock_zyjs_ths.py │ ├── stock_kcb_sse.py │ ├── stock_ipo_declare.py │ └── stock_zygc.py ├── futures_derivative │ ├── __init__.py │ ├── futures_contract_info_dce.py │ ├── futures_contract_info_gfex.py │ ├── futures_contract_info_ine.py │ └── futures_contract_info_shfe.py ├── exceptions.py └── datasets.py ├── assets └── images │ └── akshare_logo.jpg ├── tests ├── __init__.py └── test_func.py ├── docs ├── requirements.txt ├── data │ ├── qhkc │ │ └── index.rst │ ├── index.rst │ ├── tool │ │ └── tool.md │ ├── hf │ │ └── hf.md │ └── bank │ │ └── bank.md ├── deploy_http.md ├── platform.md ├── index.rst ├── dependency.md ├── data_tips.md ├── README.rst ├── trade.md ├── indicator.md ├── introduction.md └── akdocker │ └── akdocker.md ├── requirements.txt ├── .gitignore ├── Dockerfile-Jupyter ├── Dockerfile ├── requirements-dev.txt ├── .pre-commit-config.yaml ├── .github ├── ISSUE_TEMPLATE │ └── akshare_report.md └── workflows │ ├── release_and_deploy.yml │ └── main_dev_check.yml ├── LICENSE ├── .readthedocs.yaml └── pyproject.toml /akshare/cal/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /akshare/pro/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /akshare/forex/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /akshare/qdii/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /akshare/stock_a/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /akshare/qhkc/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /akshare/qhkc_web/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /akshare/data/crypto_info.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akfamily/akshare/HEAD/akshare/data/crypto_info.zip -------------------------------------------------------------------------------- /assets/images/akshare_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akfamily/akshare/HEAD/assets/images/akshare_logo.jpg -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/12/12 18:16 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/air/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/9/30 13:58 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/fx/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/10/20 10:57 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/hf/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/4/21 15:33 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/nlp/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/3/1 0:02 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/article/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/11/12 14:51 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/bank/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/11/7 14:06 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/bond/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/9/30 13:58 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/cost/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/12/18 12:32 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/crypto/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/10/23 13:51 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/currency/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/3/6 16:40 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/data/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2022/5/9 18:08 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/energy/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/12/17 16:54 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/event/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/1/23 9:07 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/fortune/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/12/10 21:55 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/fund/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/9/30 13:58 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/futures/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/9/30 13:58 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/index/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/9/30 13:58 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/movie/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/12/16 20:44 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/news/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/10/18 12:54 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/option/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/9/30 13:58 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/other/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2021/5/14 17:52 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/rate/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/10/29 13:03 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/reits/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2021/8/27 15:49 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/spot/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2021/12/6 21:58 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/stock/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/10/25 15:55 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/tool/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/9/30 13:58 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/utils/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/2/13 21:21 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/economic/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/10/21 12:08 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/file_fold/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/9/30 13:58 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/interest_rate/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/1/10 17:09 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/stock_feature/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/12/27 18:02 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/stock_fundamental/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/5/14 15:34 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /akshare/futures_derivative/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/10/27 19:45 5 | Desc: 6 | """ 7 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx>=7.4.3 2 | sphinx_rtd_theme>=2.0.0 3 | readthedocs-sphinx-search>=0.3.2 4 | sphinx-markdown-tables>=0.0.17 5 | setuptools>=69.2.0 6 | recommonmark>=0.7.1 7 | markdown>=3.6 -------------------------------------------------------------------------------- /akshare/pro/cons.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/12/24 16:28 5 | Desc: API常量文件 6 | """ 7 | 8 | TOKEN_F_P = "tk.csv" 9 | TOKEN_ERR_MSG = "请设置 AKShare pro 的 token 凭证码,如果没有权限,请访问 https://qhkch.com/ 注册申请" 10 | -------------------------------------------------------------------------------- /docs/data/qhkc/index.rst: -------------------------------------------------------------------------------- 1 | AKShare 奇货可查 2 | ================= 3 | 4 | AKShare 奇货可查模块主要介绍奇货可查提供的数据接口的详细说明 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | commodity.md 10 | broker.md 11 | index_data.md 12 | fundamental.md 13 | tools.md 14 | fund.md 15 | -------------------------------------------------------------------------------- /akshare/utils/cons.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python 2 | """ 3 | Date: 2024/4/7 15:30 4 | Desc: 通用变量 5 | """ 6 | 7 | headers = { 8 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " 9 | "Chrome/114.0.0.0 Safari/537.36" 10 | } 11 | -------------------------------------------------------------------------------- /akshare/article/cons.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/11/14 20:32 5 | Desc: 学术板块配置文件 6 | """ 7 | 8 | # EPU 9 | epu_home_url = "http://www.policyuncertainty.com/index.html" 10 | 11 | # FF-Factor 12 | ff_home_url = "http://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html" 13 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp>=3.11.13 2 | beautifulsoup4>=4.9.1 3 | curl_cffi>=0.13.0 4 | lxml>=4.2.1 5 | pandas>=0.25 6 | requests>=2.22.0 7 | urllib3>=1.25.8 8 | html5lib>=1.0.1 9 | tqdm>=4.43.0 10 | xlrd>=1.2.0 11 | openpyxl>=3.0.3 12 | jsonpath>=0.82 13 | tabulate>=0.8.6 14 | decorator>=4.4.2 15 | mini-racer>=0.12.4 16 | nest_asyncio>=1.6.0 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.bak 2 | *.pyc 3 | *.xml 4 | *.tar.gz 5 | *.iml 6 | *.icls 7 | /_windows/ 8 | /codestyles/ 9 | # Temp 10 | build/ 11 | docs/build/ 12 | docs/_build/ 13 | dist/ 14 | *.egg-info/ 15 | colors 16 | # IDE 17 | .idea/ 18 | # jupyter 19 | .ipynb_checkpoints 20 | 21 | #docs/source/_static/ 22 | #docs/source/_templates/ 23 | .DS_Store 24 | /data 25 | /tests/data 26 | -------------------------------------------------------------------------------- /Dockerfile-Jupyter: -------------------------------------------------------------------------------- 1 | # 升级到 Python 3.13.x 提高 20% 以上性能 2 | FROM python:3.13-bullseye 3 | 4 | # 设定时区 5 | ENV TZ=Asia/Shanghai 6 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 7 | 8 | # RUN pip install akshare jupyterlab -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host=mirrors.aliyun.com --upgrade 9 | RUN pip install --no-cache-dir jupyterlab scikit-learn scipy pandas aktools akshare 10 | -------------------------------------------------------------------------------- /akshare/stock_feature/cons.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/12/30 21:02 5 | Desc: 6 | """ 7 | 8 | stock_em_sy_js = """ 9 | function getCode(num) { 10 | var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 11 | var codes = str.split(''); 12 | num = num || 6; 13 | var code = ""; 14 | for (var i = 0; i < num; i++) { 15 | code += codes[Math.floor(Math.random() * 52)] 16 | } 17 | return code 18 | } 19 | """ 20 | -------------------------------------------------------------------------------- /docs/data/index.rst: -------------------------------------------------------------------------------- 1 | AKShare 数据字典 2 | ================= 3 | 4 | 数据字典主要介绍 AKShare 提供的数据接口的详细说明 5 | 6 | .. toctree:: 7 | :maxdepth: 6 8 | 9 | stock/stock 10 | futures/futures 11 | bond/bond 12 | option/option 13 | fx/fx 14 | currency/currency 15 | spot/spot 16 | interest_rate/interest_rate 17 | fund/fund_private 18 | fund/fund_public 19 | index/index 20 | macro/macro 21 | dc/dc 22 | bank/bank 23 | article/article 24 | energy/energy 25 | event/event 26 | hf/hf 27 | nlp/nlp 28 | qdii/qdii 29 | others/others 30 | qhkc/index 31 | tool/tool 32 | -------------------------------------------------------------------------------- /docs/deploy_http.md: -------------------------------------------------------------------------------- 1 | # [AKShare](https://github.com/akfamily/akshare) HTTP 部署 2 | 3 | ## 说明 4 | 5 | AKShare HTTP 版本的部署主要依赖 AKTools、AKShare、FastAPI、Uvicorn、Typer 等开源 Python 库,部署的核心程序在 AKTools 中。 6 | 非常感谢给 [AKTools 项目](https://github.com/akfamily/aktools) 点 Star,您的支持是我们持续开发最大的动力! 7 | 8 | ## 快速启动 9 | 10 | ### 安装库 11 | 12 | ```shell 13 | pip install aktools 14 | ``` 15 | 16 | ### 运行库 17 | 18 | ```shell 19 | python -m aktools 20 | ``` 21 | 22 | ## 版本说明 23 | 24 | 1. 仅体验 HTTP API 功能则只需要安装:`pip install aktools==0.0.68` 版本; 25 | 2. 体验完整功能请安装最新版,支持用于认证、权限、可视化页面等更多功能。 26 | 27 | ## 更多详情 28 | 29 | [参见 AKTools 项目文档](https://aktools.akfamily.xyz/) 30 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # 使用精简镜像,镜像体积从 1.2G 下降为约 400M,提高启动效率,同时升级到 Python 3.13.x 提高 20% 以上性能 2 | FROM python:3.13-slim-bullseye 3 | 4 | # 升级 pip 到最新版 5 | RUN pip install --upgrade pip 6 | 7 | # 新增 gunicorn 安装,提升并发和并行能力 8 | RUN pip install --no-cache-dir akshare fastapi uvicorn gunicorn -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host=mirrors.aliyun.com --upgrade 9 | RUN pip install --no-cache-dir aktools -i https://pypi.org/simple --upgrade 10 | 11 | # 设置工作目录方便启动 12 | ENV APP_HOME=/usr/local/lib/python3.13/site-packages/aktools 13 | WORKDIR $APP_HOME 14 | 15 | # 默认启动 gunicorn 服务 16 | CMD ["gunicorn", "--bind", "0.0.0.0:8080", "main:app", "-k", "uvicorn.workers.UvicornWorker"] 17 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | akqmt>=0.1.0 2 | aiohttp>=3.11.13 3 | beautifulsoup4>=4.9.1 4 | curl_cffi>=0.13.0 5 | lxml>=4.2.1 6 | pandas>=0.25 7 | requests>=2.22.0 8 | urllib3>=1.25.8 9 | html5lib>=1.0.1 10 | tqdm>=4.43.0 11 | xlrd>=1.2.0 12 | openpyxl>=3.0.3 13 | jsonpath>=0.82 14 | tabulate>=0.8.6 15 | decorator>=4.4.2 16 | mini-racer>=0.12.4 17 | commitizen>=2.35.0 18 | pre-commit>=2.20.0 19 | sphinx>=7.4.3 20 | recommonmark>=0.7.1 21 | nest_asyncio>=1.6.0 22 | sphinx_markdown_tables>=0.0.17 23 | sphinx_rtd_theme>=1.0.0 24 | mplfinance>=0.12.10b0 25 | ruff>=0.3.3 26 | ruff-lsp>=0.0.53 27 | pre-commit>=3.6.2 28 | # backtrader>=1.9.78.123 # just for test 29 | # lib-pybroker # just for demo.md 30 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # commit setup 2 | repos: 3 | - repo: https://github.com/pre-commit/pre-commit-hooks 4 | rev: v4.5.0 5 | hooks: 6 | - id: check-yaml 7 | - id: end-of-file-fixer 8 | - id: trailing-whitespace 9 | - repo: https://github.com/astral-sh/ruff-pre-commit 10 | # Ruff version. 11 | rev: v0.3.2 12 | hooks: 13 | # Run the linter. 14 | - id: ruff 15 | args: [--fix] 16 | # Run the formatter. 17 | - id: ruff-format 18 | - repo: https://github.com/compilerla/conventional-pre-commit 19 | rev: v3.1.0 20 | hooks: 21 | - id: conventional-pre-commit 22 | stages: [commit-msg] 23 | args: [] 24 | -------------------------------------------------------------------------------- /akshare/fx/cons.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/10/20 10:58 5 | Desc: 外汇配置文件 6 | """ 7 | 8 | # headers 9 | SHORT_HEADERS = { 10 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" 11 | } 12 | # url 13 | FX_SPOT_URL = ( 14 | "http://www.chinamoney.com.cn/r/cms/www/chinamoney/data/fx/rfx-sp-quot.json" 15 | ) 16 | FX_SWAP_URL = ( 17 | "http://www.chinamoney.com.cn/r/cms/www/chinamoney/data/fx/rfx-sw-quot.json" 18 | ) 19 | FX_PAIR_URL = ( 20 | "http://www.chinamoney.com.cn/r/cms/www/chinamoney/data/fx/cpair-quot.json" 21 | ) 22 | # payload 23 | SPOT_PAYLOAD = {"t": {}} 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/akshare_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: AKShare-问题报告 3 | about: 反馈 AKShare 接口相关的问题 4 | title: AKShare 接口问题报告 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | > 由于开源项目维护工作量较大,本 issue 只接受接口报错问题。如有更多问题,推荐加入【财经数据与量化投研】知识社区:https://t.zsxq.com/ZCxUG 。 11 | 12 | ## 重要前提 13 | 14 | 遇到任何 AKShare 使用问题,请先将您本地的 AKShare 升级到**最新版**,可以通过如下命令升级: 15 | 16 | ```bash 17 | pip install akshare --upgrade # Python 版本需要大于等于 3.9 18 | ``` 19 | 20 | ## 如何提交问题 21 | 22 | 请提交以下相关信息,以更精准的解决问题。**不符合提交规范的 issue 会被关闭!** 23 | 24 | 1. 请先详细阅读 AKShare 文档中对应接口的使用方式:https://akshare.akfamily.xyz 25 | 2. 请务必将 AKShare 升级到最新版本 26 | 3. 请检查操作系统版本,目前只支持 64 位主流操作系统 27 | 4. 请检查 Python 版本,目前只支持 3.9 以上的版本 28 | 5. 请提交相关接口的名称和相应的调用代码 29 | 6. 接口报错的截图或描述 30 | 7. 期望获得的正确结果 31 | -------------------------------------------------------------------------------- /docs/platform.md: -------------------------------------------------------------------------------- 1 | # [AKShare](https://github.com/akfamily/akshare) 量化专题 2 | 3 | ## 开源平台 4 | 5 | - [PyBroker](https://www.pybroker.com/) 6 | - [Backtrader](https://www.backtrader.com/) 7 | - [VN.PY](https://www.vnpy.com/) 8 | - [功夫量化](https://www.kungfu-trader.com/) 9 | 10 | ## 网页端 11 | 12 | - [BigQuant](https://bigquant.com/) 13 | - [JoinQuant](https://www.joinquant.com/) 14 | - [MyQuant](https://www.myquant.cn/) 15 | - [Uqer](https://uqer.datayes.com/) 16 | - [RiceQuant](https://www.ricequant.com/welcome/) 17 | - [WindQuant](https://www.windquant.com/) 18 | 19 | ## 量化策略 20 | 21 | - 双均线策略(期货) 22 | - alpha对冲(股票+期货) 23 | - 集合竞价选股(股票) 24 | - 多因子选股(股票) 25 | - 网格交易(期货) 26 | - 指数增强(股票) 27 | - 跨品种套利(期货) 28 | - 跨期套利(期货) 29 | - 日内回转交易(股票) 30 | - 做市商交易(期货) 31 | - 海龟交易法(期货) 32 | - 行业轮动(股票) 33 | - 机器学习(股票) 34 | -------------------------------------------------------------------------------- /akshare/utils/tqdm.py: -------------------------------------------------------------------------------- 1 | def get_tqdm(enable: bool = True): 2 | """ 3 | 返回适用于当前环境的 tqdm 对象。 4 | 5 | Args: 6 | enable (bool): 是否启用进度条。默认为 True。 7 | 8 | Returns: 9 | tqdm 对象。 10 | """ 11 | if not enable: 12 | # 如果进度条被禁用,返回一个不显示进度条的 tqdm 对象 13 | return lambda iterable, *args, **kwargs: iterable 14 | 15 | try: 16 | # 尝试检查是否在 jupyter notebook 环境中,有利于退出进度条 17 | # noinspection PyUnresolvedReferences 18 | shell = get_ipython().__class__.__name__ 19 | if shell == "ZMQInteractiveShell": 20 | from tqdm.notebook import tqdm 21 | else: 22 | from tqdm import tqdm 23 | except (NameError, ImportError): 24 | # 如果不在 Jupyter 环境中,就使用标准 tqdm 25 | from tqdm import tqdm 26 | 27 | return tqdm 28 | -------------------------------------------------------------------------------- /akshare/utils/token_process.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/2/13 21:22 5 | Desc: 存储和读取 Token 文件 6 | """ 7 | 8 | import os 9 | 10 | import pandas as pd 11 | 12 | from akshare.pro import cons 13 | 14 | 15 | def set_token(token): 16 | df = pd.DataFrame([token], columns=["token"]) 17 | user_home = os.path.expanduser("~") 18 | fp = os.path.join(user_home, cons.TOKEN_F_P) 19 | df.to_csv(fp, index=False) 20 | 21 | 22 | def get_token(): 23 | user_home = os.path.expanduser("~") 24 | fp = os.path.join(user_home, cons.TOKEN_F_P) 25 | if os.path.exists(fp): 26 | df = pd.read_csv(fp) 27 | return str(df.iloc[0]["token"]) 28 | else: 29 | print(cons.TOKEN_ERR_MSG) 30 | return 31 | 32 | 33 | if __name__ == "__main__": 34 | pass 35 | -------------------------------------------------------------------------------- /akshare/pro/data_pro.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/11/10 22:52 5 | Desc: 数据接口初始化 6 | """ 7 | 8 | from akshare.pro import client 9 | from akshare.utils import token_process 10 | 11 | 12 | def pro_api(token=""): 13 | """ 14 | 初始化 pro API,第一次可以通过ak.set_token('your token')来记录自己的token凭证,临时token可以通过本参数传入 15 | """ 16 | if token == "" or token is None: 17 | token = token_process.get_token() 18 | if token is not None and token != "": 19 | pro = client.DataApi(token) 20 | return pro 21 | else: 22 | raise Exception("api init error.") 23 | 24 | 25 | if __name__ == "__main__": 26 | pro_test = pro_api() 27 | variety_all_df = pro_test.variety_all() 28 | print(variety_all_df) 29 | variety_no_futures_df = pro_test.variety_no_futures(symbol="RB", date="2018-08-08") 30 | print(variety_no_futures_df) 31 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. AKShare documentation master file, created by 2 | sphinx-quickstart on Fri Oct 11 00:10:59 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | 欢迎访问 AKShare 在线文档! 7 | =========================================== 8 | 9 | .. note:: 10 | 11 | 推荐关注微信公众号【数据科学实战】获取更多财经数据与量化投研知识 12 | 13 | .. image:: https://jfds-1252952517.cos.ap-chengdu.myqcloud.com/akshare/readme/qrcode/ds.png 14 | :width: 400px 15 | :align: center 16 | :alt: WeChat QR code 17 | 18 | .. toctree:: 19 | :maxdepth: 2 20 | :glob: 21 | :caption: Table of contents: 22 | 23 | introduction 24 | installation 25 | data/index 26 | indicator 27 | data_tips 28 | trade 29 | answer 30 | tutorial 31 | articles 32 | anaconda 33 | platform 34 | demo 35 | changelog 36 | contributing 37 | dependency 38 | deploy_http 39 | akdocker/akdocker 40 | special 41 | -------------------------------------------------------------------------------- /tests/test_func.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/8/28 15:00 5 | Desc: To test intention, just write test code here! 6 | """ 7 | 8 | import pathlib 9 | 10 | from akshare.datasets import get_ths_js, get_crypto_info_csv 11 | 12 | 13 | def test_cost_living(): 14 | """ 15 | just for test aim 16 | :return: assert result 17 | :rtype: assert 18 | """ 19 | pass 20 | 21 | 22 | def test_path_func(): 23 | """ 24 | test path func 25 | :return: path of file 26 | :rtype: pathlib.Path 27 | """ 28 | temp_path = get_ths_js("ths.js") 29 | assert isinstance(temp_path, pathlib.Path) 30 | 31 | 32 | def test_zipfile_func(): 33 | """ 34 | test path func 35 | :return: path of file 36 | :rtype: pathlib.Path 37 | """ 38 | temp_path = get_crypto_info_csv("crypto_info.zip") 39 | assert isinstance(temp_path, pathlib.Path) 40 | 41 | 42 | if __name__ == "__main__": 43 | # test_cost_living() 44 | test_path_func() 45 | test_zipfile_func() 46 | -------------------------------------------------------------------------------- /akshare/futures/futures_rule_em.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/1/17 19:30 5 | Desc: 东方财富网-期货行情-品种及交易规则 6 | https://portal.eastmoneyfutures.com/pages/service/jyts.html#jyrl 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | from akshare.utils.cons import headers 12 | 13 | 14 | def futures_rule_em() -> pd.DataFrame: 15 | """ 16 | 东方财富网-期货行情-品种及交易规则 17 | https://portal.eastmoneyfutures.com/pages/service/jyts.html#jyrl 18 | :return: 品种及交易规则 19 | :rtype: pandas.DataFrame 20 | """ 21 | url = "https://eastmoneyfutures.com/api/ComManage/GetPZJYInfo" 22 | r = requests.get(url, headers=headers) 23 | data_json = r.json() 24 | temp_df = pd.DataFrame(data_json["Data"]) 25 | return temp_df 26 | 27 | 28 | def futures_trading_hours_em(): 29 | """ 30 | 东方财富网-期货交易时间 31 | https://qhweb.eastmoney.com/tradinghours 32 | """ 33 | pass 34 | 35 | 36 | if __name__ == "__main__": 37 | futures_rule_em_df = futures_rule_em() 38 | print(futures_rule_em_df) 39 | -------------------------------------------------------------------------------- /.github/workflows/release_and_deploy.yml: -------------------------------------------------------------------------------- 1 | # release_and_deploy 2 | name: Release and Deploy 3 | 4 | on: 5 | push: 6 | tags: 7 | - 'release-v*.*.*' 8 | 9 | jobs: 10 | deploy: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout repository 14 | uses: actions/checkout@v4 15 | 16 | - name: Set up Python 17 | uses: actions/setup-python@v5 18 | with: 19 | python-version: '3.x' 20 | 21 | - name: Install dependencies 22 | run: | 23 | python -m pip install --upgrade pip 24 | pip install setuptools wheel twine 25 | 26 | - name: Build and publish package 27 | env: 28 | TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} 29 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 30 | run: | 31 | python setup.py sdist bdist_wheel 32 | twine upload dist/* 33 | 34 | - name: Create GitHub release 35 | uses: softprops/action-gh-release@v2 36 | with: 37 | token: ${{ secrets.GITHUB_TOKEN }} 38 | -------------------------------------------------------------------------------- /akshare/exceptions.py: -------------------------------------------------------------------------------- 1 | """ 2 | AKShare 异常处理模块 3 | """ 4 | 5 | 6 | class AkshareException(Exception): 7 | """Base exception for akshare library""" 8 | 9 | def __init__(self, message): 10 | self.message = message 11 | super().__init__(self.message) 12 | 13 | 14 | class APIError(AkshareException): 15 | """Raised when API request fails""" 16 | 17 | def __init__(self, message, status_code=None): 18 | self.status_code = status_code 19 | super().__init__(f"API Error: {message} (Status code: {status_code})") 20 | 21 | 22 | class DataParsingError(AkshareException): 23 | """Raised when data parsing fails""" 24 | 25 | pass 26 | 27 | 28 | class InvalidParameterError(AkshareException): 29 | """Raised when an invalid parameter is provided""" 30 | 31 | pass 32 | 33 | 34 | class NetworkError(AkshareException): 35 | """Raised when network-related issues occur""" 36 | 37 | pass 38 | 39 | 40 | class RateLimitError(AkshareException): 41 | """Raised when API rate limit is exceeded""" 42 | 43 | pass 44 | -------------------------------------------------------------------------------- /akshare/stock_fundamental/stock_kcb_detail_sse.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2022/4/7 17:36 5 | Desc: http://kcb.sse.com.cn/renewal/xmxq/index.shtml?auditId=926&anchor_type=0 6 | """ 7 | 8 | import requests 9 | import pandas as pd 10 | 11 | # TODO 12 | 13 | 14 | def stock_kcb_detail_renewal(): 15 | url = "http://query.sse.com.cn/commonSoaQuery.do" 16 | params = { 17 | "isPagination": "true", 18 | "sqlId": "SH_XM_LB", 19 | "stockAuditNum": "926", # 每次更新该字段就可以 20 | "_": "1649324745607", 21 | } 22 | headers = { 23 | "Host": "query.sse.com.cn", 24 | "Pragma": "no-cache", 25 | "Referer": "http://kcb.sse.com.cn/", 26 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36", 27 | } 28 | r = requests.get(url, params=params, headers=headers) 29 | data_json = r.json() 30 | temp_df = pd.DataFrame(data_json["result"]) 31 | # 处理下 temp_df 里面的字段就可以了 32 | print(temp_df) 33 | -------------------------------------------------------------------------------- /akshare/datasets.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2024/12/30 15:30 5 | Desc: 导入文件工具,可以正确处理路径问题 6 | """ 7 | 8 | import pathlib 9 | from importlib import resources 10 | 11 | 12 | def get_ths_js(file: str = "ths.js") -> pathlib.Path: 13 | """ 14 | get path to data "ths.js" text file. 15 | :return: 文件路径 16 | :rtype: pathlib.Path 17 | """ 18 | with resources.path("akshare.data", file) as f: 19 | data_file_path = f 20 | return data_file_path 21 | 22 | 23 | def get_crypto_info_csv(file: str = "crypto_info.zip") -> pathlib.Path: 24 | """ 25 | get path to data "ths.js" text file. 26 | :return: 文件路径 27 | :rtype: pathlib.Path 28 | """ 29 | with resources.path("akshare.data", file) as f: 30 | data_file_path = f 31 | return data_file_path 32 | 33 | 34 | if __name__ == "__main__": 35 | get_ths_js_path = get_ths_js(file="ths.js") 36 | print(get_ths_js_path) 37 | 38 | get_crypto_info_csv_path = get_crypto_info_csv(file="crypto_info.zip") 39 | print(get_crypto_info_csv_path) 40 | -------------------------------------------------------------------------------- /akshare/utils/context.py: -------------------------------------------------------------------------------- 1 | class AkshareConfig: 2 | _instance = None 3 | 4 | def __new__(cls): 5 | if cls._instance is None: 6 | cls._instance = super().__new__(cls) 7 | cls._instance.proxies = None 8 | return cls._instance 9 | 10 | @classmethod 11 | def set_proxies(cls, proxies): 12 | cls().proxies = proxies 13 | 14 | @classmethod 15 | def get_proxies(cls): 16 | return cls().proxies 17 | 18 | 19 | config = AkshareConfig() 20 | 21 | 22 | # 导出 set_proxies 函数 23 | def set_proxies(proxies): 24 | config.set_proxies(proxies) 25 | 26 | 27 | def get_proxies(): 28 | return config.get_proxies() 29 | 30 | 31 | class ProxyContext: 32 | def __init__(self, proxies): 33 | self.proxies = proxies 34 | self.old_proxies = None 35 | 36 | def __enter__(self): 37 | self.old_proxies = config.get_proxies() 38 | config.set_proxies(self.proxies) 39 | return self 40 | 41 | def __exit__(self, exc_type, exc_val, exc_tb): 42 | config.set_proxies(self.old_proxies) 43 | return False # 不处理异常 44 | -------------------------------------------------------------------------------- /akshare/futures/futures_comm_ctp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/7/6 18:00 5 | Desc: openctp 期货交易费用参照表 6 | http://openctp.cn/fees.html 7 | """ 8 | 9 | from datetime import datetime 10 | from io import StringIO 11 | 12 | import pandas as pd 13 | import requests 14 | from bs4 import BeautifulSoup 15 | 16 | 17 | def futures_fees_info() -> pd.DataFrame: 18 | """ 19 | openctp 期货交易费用参照表 20 | http://openctp.cn/fees.html 21 | :return: 期货交易费用参照表 22 | :rtype: pandas.DataFrame 23 | """ 24 | url = "http://openctp.cn/fees.html" 25 | r = requests.get(url) 26 | r.encoding = "utf-8" 27 | soup = BeautifulSoup(r.text, features="lxml") 28 | datetime_str = soup.find("p").string.strip("Generated at ").strip(".") 29 | datetime_raw = datetime.strptime(datetime_str, "%Y-%m-%d %H:%M:%S") 30 | temp_df = pd.read_html(StringIO(r.text))[0] 31 | temp_df["更新时间"] = datetime_raw.strftime("%Y-%m-%d %H:%M:%S") 32 | return temp_df 33 | 34 | 35 | if __name__ == "__main__": 36 | futures_fees_info_df = futures_fees_info() 37 | print(futures_fees_info_df) 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2025 Albert King 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/data/tool/tool.md: -------------------------------------------------------------------------------- 1 | ## [AKShare](https://github.com/akfamily/akshare) 工具箱 2 | 3 | ### 交易日历 4 | 5 | 接口: tool_trade_date_hist_sina 6 | 7 | 目标地址: https://finance.sina.com.cn 8 | 9 | 描述: 新浪财经-股票交易日历数据 10 | 11 | 限量: 单次返回从 1990-12-19 到 2024-12-31 之间的股票交易日历数据, 这里补充 1992-05-04 进入交易日 12 | 13 | 输入参数 14 | 15 | | 名称 | 类型 | 描述 | 16 | |-----|-----|-----| 17 | | - | - | - | 18 | 19 | 输出参数 20 | 21 | | 名称 | 类型 | 描述 | 22 | |------------|--------|-----------------------------------------------------------| 23 | | trade_date | object | 从 1990-12-19 至 2024-12-31 的股票交易日数据; 这里补充 1992-05-04 进入交易日 | 24 | 25 | 接口示例 26 | 27 | ```python 28 | import akshare as ak 29 | 30 | tool_trade_date_hist_sina_df = ak.tool_trade_date_hist_sina() 31 | print(tool_trade_date_hist_sina_df) 32 | ``` 33 | 34 | 数据示例 35 | 36 | ``` 37 | trade_date 38 | 0 1990-12-19 39 | 1 1990-12-20 40 | 2 1990-12-21 41 | 3 1990-12-24 42 | 4 1990-12-25 43 | ... ... 44 | 8550 2025-12-25 45 | 8551 2025-12-26 46 | 8552 2025-12-29 47 | 8553 2025-12-30 48 | 8554 2025-12-31 49 | [8555 rows x 1 columns] 50 | ``` 51 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # Read the Docs configuration file for Sphinx projects 2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 3 | 4 | # Required 5 | version: 2 6 | 7 | # Set the OS, Python version and other tools you might need 8 | build: 9 | os: ubuntu-24.04 10 | tools: 11 | python: "3.13" 12 | # You can also specify other tool versions: 13 | # nodejs: "16" 14 | # rust: "1.55" 15 | # golang: "1.17" 16 | 17 | # Build documentation in the "docs/" directory with Sphinx 18 | sphinx: 19 | configuration: docs/conf.py 20 | # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs 21 | # builder: "dirhtml" 22 | # Fail on all warnings to avoid broken references 23 | # fail_on_warning: true 24 | 25 | # Optionally build your docs in additional formats such as PDF and ePub 26 | # formats: 27 | # - pdf 28 | # - epub 29 | 30 | # Optional but recommended, declare the Python requirements required 31 | # to build your documentation 32 | # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html 33 | python: 34 | install: 35 | - requirements: docs/requirements.txt 36 | -------------------------------------------------------------------------------- /akshare/fund/fund_overview_em.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/9/16 21:00 5 | Desc: 天天基金-基金档案 6 | https://fundf10.eastmoney.com/jbgk_015641.html 7 | """ 8 | from io import StringIO 9 | 10 | import pandas as pd 11 | import requests 12 | 13 | 14 | def fund_overview_em(symbol: str = "015641") -> pd.DataFrame: 15 | """ 16 | 天天基金-基金档案-基本概况 17 | https://fundf10.eastmoney.com/jbgk_015641.html 18 | :param symbol: 基金代码 19 | :type symbol: str 20 | :return: 基本概况 21 | :rtype: pandas.DataFrame 22 | """ 23 | url = f"https://fundf10.eastmoney.com/jbgk_{symbol}.html" 24 | r = requests.get(url) 25 | html_content = pd.read_html(StringIO(r.text)) 26 | 27 | if len(html_content) == 0: 28 | temp_df = pd.DataFrame([]) 29 | else: 30 | df_dict = {} 31 | # 最后一个表格的数据是我们想要的,按照Key-Value的形式存储 32 | for _, row in html_content[-1].iterrows(): 33 | df_dict[row[0]] = row[1] 34 | df_dict[row[2]] = row[3] 35 | temp_df = pd.DataFrame([df_dict]) 36 | 37 | return temp_df 38 | 39 | 40 | if __name__ == "__main__": 41 | fund_overview_em_df = fund_overview_em(symbol="015641") 42 | print(fund_overview_em_df) 43 | -------------------------------------------------------------------------------- /akshare/stock/stock_news_cx.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/11/18 16:00 5 | Desc: 财新网-财新数据通 6 | https://cxdata.caixin.com/pc/ 7 | """ 8 | 9 | import pandas as pd 10 | 11 | from akshare.request import make_request_with_retry_json 12 | 13 | 14 | def stock_news_main_cx() -> pd.DataFrame: 15 | """ 16 | 财新网-财新数据通 17 | https://cxdata.caixin.com/pc/ 18 | :return: 特定时间表示的字典 19 | :rtype: pandas.DataFrame 20 | """ 21 | url = "https://cxdata.caixin.com/api/dataplus/sjtPc/jxNews" 22 | params = { 23 | "pageNum": "1", 24 | "pageSize": "20000", 25 | "showLabels": "true", 26 | } 27 | data_json = make_request_with_retry_json(url, params=params) 28 | temp_df = pd.DataFrame(data_json["data"]["data"]) 29 | temp_df = temp_df[["tag", "summary", "intervalTime", "pubTime", "url"]] 30 | temp_df.columns = ["tag", "summary", "interval_time", "pub_time", "url"] 31 | temp_df["pub_time"] = pd.to_datetime( 32 | temp_df["pub_time"], errors="coerce", unit="ms" 33 | ).astype(str) 34 | return temp_df 35 | 36 | 37 | if __name__ == "__main__": 38 | stock_news_main_cx_df = stock_news_main_cx() 39 | print(stock_news_main_cx_df) 40 | -------------------------------------------------------------------------------- /.github/workflows/main_dev_check.yml: -------------------------------------------------------------------------------- 1 | # main_dev_check 2 | name: Main and Dev Checks 3 | 4 | on: 5 | push: 6 | branches: 7 | - main 8 | - dev 9 | pull_request: 10 | branches: 11 | - main 12 | - dev 13 | 14 | jobs: 15 | build: 16 | runs-on: ${{ matrix.os }} 17 | strategy: 18 | matrix: 19 | os: [ubuntu-latest, macos-latest, windows-latest] 20 | python-version: ["3.11", "3.12", "3.13"] 21 | 22 | steps: 23 | - name: Checkout code 24 | uses: actions/checkout@v4 25 | 26 | - name: Set up Python ${{ matrix.python-version }} 27 | uses: actions/setup-python@v5 28 | with: 29 | python-version: ${{ matrix.python-version }} 30 | 31 | - name: Install dependencies 32 | run: | 33 | python -m pip install --upgrade pip 34 | pip install -r requirements.txt 35 | 36 | - name: Lint with flake8 37 | run: | 38 | pip install flake8 39 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 40 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 41 | 42 | - name: Test with pytest 43 | run: | 44 | pip install pytest 45 | pytest 46 | -------------------------------------------------------------------------------- /akshare/stock/stock_stop.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/2/24 18:33 5 | Desc: 两网及退市 6 | https://quote.eastmoney.com/center/gridlist.html#staq_net_board 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def stock_staq_net_stop() -> pd.DataFrame: 14 | """ 15 | 东方财富网-行情中心-沪深个股-两网及退市 16 | https://quote.eastmoney.com/center/gridlist.html#staq_net_board 17 | :return: 两网及退市 18 | :rtype: pandas.DataFrame 19 | """ 20 | url = "https://5.push2.eastmoney.com/api/qt/clist/get" 21 | params = { 22 | "pn": "1", 23 | "pz": "50000", 24 | "po": "1", 25 | "np": "2", 26 | "ut": "bd1d9ddb04089700cf9c27f6f7426281", 27 | "fltt": "2", 28 | "invt": "2", 29 | "fid": "f3", 30 | "fs": "m:0 s:3", 31 | "fields": "f12,f14", 32 | } 33 | r = requests.get(url, params=params) 34 | data_json = r.json() 35 | temp_df = pd.DataFrame(data_json["data"]["diff"]).T 36 | temp_df.reset_index(inplace=True) 37 | temp_df["index"] = temp_df.index + 1 38 | temp_df.columns = ["序号", "代码", "名称"] 39 | return temp_df 40 | 41 | 42 | if __name__ == "__main__": 43 | stock_staq_net_stop_df = stock_staq_net_stop() 44 | print(stock_staq_net_stop_df) 45 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_all_pb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2023/4/11 20:40 5 | Desc: 全部A股-等权重市净率、中位数市净率 6 | https://www.legulegu.com/stockdata/all-pb 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | from akshare.stock_feature.stock_a_indicator import get_token_lg, get_cookie_csrf 13 | 14 | 15 | def stock_a_all_pb() -> pd.DataFrame: 16 | """ 17 | 全部A股-等权重市净率、中位数市净率 18 | https://legulegu.com/stockdata/all-pb 19 | :return: 全部A股-等权重市盈率、中位数市盈率 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = "https://legulegu.com/api/stock-data/market-index-pb" 23 | params = { 24 | "marketId": "ALL", 25 | "token": get_token_lg(), 26 | } 27 | r = requests.get( 28 | url, 29 | params=params, 30 | **get_cookie_csrf(url="https://legulegu.com/stockdata/all-pb"), 31 | ) 32 | data_json = r.json() 33 | temp_df = pd.DataFrame(data_json["data"]) 34 | temp_df["date"] = ( 35 | pd.to_datetime(temp_df["date"], unit="ms", utc=True) 36 | .dt.tz_convert("Asia/Shanghai") 37 | .dt.date 38 | ) 39 | del temp_df["weightingAveragePB"] 40 | return temp_df 41 | 42 | 43 | if __name__ == "__main__": 44 | stock_a_all_pb_df = stock_a_all_pb() 45 | print(stock_a_all_pb_df) 46 | -------------------------------------------------------------------------------- /akshare/hf/hf_sp500.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/4/21 15:34 5 | Desc: 高频数据-标普 500 指数 6 | https://github.com/FutureSharks/financial-data 7 | long history data for S&P 500 index daily 8 | http://www.econ.yale.edu/~shiller/data.htm 9 | """ 10 | 11 | import pandas as pd 12 | 13 | 14 | def hf_sp_500(year: str = "2017") -> pd.DataFrame: 15 | """ 16 | S&P 500 minute data from 2012-2018 17 | :param year: from 2012-2018 18 | :type year: str 19 | :return: specific year dataframe 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = f"https://github.com/FutureSharks/financial-data/raw/master/pyfinancialdata/data/stocks/histdata/SPXUSD/DAT_ASCII_SPXUSD_M1_{year}.csv" 23 | temp_df = pd.read_table(url, header=None, sep=";") 24 | temp_df.columns = ["date", "open", "high", "low", "close", "price"] 25 | temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date 26 | temp_df["open"] = pd.to_numeric(temp_df["open"]) 27 | temp_df["high"] = pd.to_numeric(temp_df["high"]) 28 | temp_df["low"] = pd.to_numeric(temp_df["low"]) 29 | temp_df["close"] = pd.to_numeric(temp_df["close"]) 30 | temp_df["price"] = pd.to_numeric(temp_df["price"]) 31 | return temp_df 32 | 33 | 34 | if __name__ == "__main__": 35 | hf_sp_500_df = hf_sp_500(year="2017") 36 | print(hf_sp_500_df) 37 | -------------------------------------------------------------------------------- /docs/dependency.md: -------------------------------------------------------------------------------- 1 | ## [AKShare](https://github.com/akfamily/akshare) 依赖说明 2 | 3 | ### Python 依赖 4 | 5 | 1. [AKShare](https://github.com/akfamily/akshare) 文档的依赖说明部分主要是为了对 [AKShare](https://github.com/akfamily/akshare) 库的所有依赖库做一个描述, 6 | 方便小伙伴在对 [AKShare](https://github.com/akfamily/akshare) 进行二次封装进行参考; 7 | 2. 提供选择该库函数的部分原因说明; 8 | 3. 所有的依赖名称都跟 PyPI 提供的库名称统一; 9 | 4. 打包的时候注意 mini-racer 库如报错,请重新编译。 10 | 11 | #### mini-racer 12 | 13 | 1. 版本 >=0.12.4 14 | 2. 推荐使用最新版 15 | 3. [PyPI 地址](https://pypi.org/project/mini-racer/) 16 | 4. [GitHub 地址](https://github.com/bpcreech/PyMiniRacer) 17 | 5. [文档地址](https://blog.sqreen.com/embedding-javascript-into-python/) 18 | 6. 选用原因如下 19 | 1. 由于 [PyExecJS](https://pypi.org/project/PyExecJS/) 在 20180118 推出最后一个版本后, 20 | 主要的开发者不再对该库进行升级维护,导致部分问题无法通过升级该库来修复, 21 | 该库的 [GitHub 地址](https://github.com/doloopwhile/PyExecJS) 可以访问如下地址,所以没有使用该库; 22 | 2. [Js2Py](https://pypi.org/project/Js2Py/) 是目前比较使用量较大和维护较好的库,其 [GitHub 地址](https://github.com/PiotrDabkowski/Js2Py) 但是考虑到在测试中, 23 | 对部分 Javascript 代码的运行不稳定,所以没有使用该库。 24 | 25 | #### pandas 26 | 27 | 1. 版本 >=0.25.0 28 | 2. 推荐使用最新版 29 | 3. [PYPI 地址](https://pypi.org/project/pandas/) 30 | 4. [GitHub 地址](https://github.com/pandas-dev/pandas/) 31 | 5. [文档地址](https://pandas.pydata.org/) 32 | 6. 选用原因如下 33 | 1. 该库主要用于采集后的数据清洗,此处建议升级到最新版,[AKShare](https://github.com/akfamily/akshare/) 会优先支持最新的版本; 34 | 2. 默认会安装 [NumPy](https://numpy.org/) 依赖。 35 | -------------------------------------------------------------------------------- /akshare/index/index_zh_a_scope.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/4/17 19:00 5 | Desc: 数库-A股新闻情绪指数 6 | https://www.chinascope.com/reasearch.html 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def index_news_sentiment_scope() -> pd.DataFrame: 14 | """ 15 | 数库-A股新闻情绪指数 16 | https://www.chinascope.com/reasearch.html 17 | :return: A股新闻情绪指数 18 | :rtype: pandas.DataFrame 19 | """ 20 | url = "https://www.chinascope.com/inews/senti/index" 21 | params = {"period": "YEAR"} 22 | r = requests.get(url=url, params=params) 23 | data_json = r.json() 24 | temp_df = pd.DataFrame(data_json) 25 | temp_df.rename( 26 | columns={ 27 | "tradeDate": "日期", 28 | "maIndex1": "市场情绪指数", 29 | "marketClose": "沪深300指数", 30 | }, 31 | inplace=True, 32 | ) 33 | temp_df = temp_df[ 34 | [ 35 | "日期", 36 | "市场情绪指数", 37 | "沪深300指数", 38 | ] 39 | ] 40 | temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date 41 | temp_df["市场情绪指数"] = pd.to_numeric(temp_df["市场情绪指数"], errors="coerce") 42 | temp_df["沪深300指数"] = pd.to_numeric(temp_df["沪深300指数"], errors="coerce") 43 | return temp_df 44 | 45 | 46 | if __name__ == "__main__": 47 | index_news_sentiment_scope_df = index_news_sentiment_scope() 48 | print(index_news_sentiment_scope_df) 49 | -------------------------------------------------------------------------------- /akshare/fortune/fortune_forbes_500.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2022/1/26 15:10 5 | Desc: 福布斯中国-榜单 6 | https://www.forbeschina.com/lists 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | from bs4 import BeautifulSoup 12 | 13 | 14 | def forbes_rank(symbol: str = "2021福布斯中国创投人100") -> pd.DataFrame: 15 | """ 16 | 福布斯中国-榜单 17 | https://www.forbeschina.com/lists 18 | https://www.forbeschina.com/lists/1750 19 | :param symbol: choice of {"2020福布斯美国富豪榜", "2020福布斯新加坡富豪榜", "2020福布斯中国名人榜", *} 20 | :type symbol: str 21 | :return: 具体指标的榜单 22 | :rtype: pandas.DataFrame 23 | """ 24 | url = "https://www.forbeschina.com/lists" 25 | r = requests.get(url, verify=False) 26 | soup = BeautifulSoup(r.text, "lxml") 27 | need_list = [ 28 | item.find_all("a") for item in soup.find_all("div", attrs={"class": "col-sm-4"}) 29 | ] 30 | all_list = [] 31 | for item in need_list: 32 | all_list.extend(item) 33 | name_url_dict = dict( 34 | zip( 35 | [item.text.strip() for item in all_list], 36 | ["https://www.forbeschina.com" + item["href"] for item in all_list], 37 | ) 38 | ) 39 | r = requests.get(name_url_dict[symbol], verify=False) 40 | temp_df = pd.read_html(r.text)[0] 41 | return temp_df 42 | 43 | 44 | if __name__ == "__main__": 45 | forbes_rank_df = forbes_rank(symbol="2021福布斯中国香港富豪榜") 46 | print(forbes_rank_df) 47 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_congestion_lg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2023/4/7 15:05 5 | Desc: 乐咕乐股-大盘拥挤度 6 | https://legulegu.com/stockdata/ashares-congestion 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | from akshare.stock_feature.stock_a_indicator import get_token_lg, get_cookie_csrf 13 | 14 | 15 | def stock_a_congestion_lg() -> pd.DataFrame: 16 | """ 17 | 乐咕乐股-大盘拥挤度 18 | https://legulegu.com/stockdata/ashares-congestion 19 | :return: 大盘拥挤度 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = "https://legulegu.com/api/stockdata/ashares-congestion" 23 | token = get_token_lg() 24 | params = {"token": token} 25 | r = requests.get( 26 | url, 27 | params=params, 28 | **get_cookie_csrf(url="https://legulegu.com/stockdata/ashares-congestion"), 29 | ) 30 | data_json = r.json() 31 | temp_df = pd.DataFrame(data_json["items"]) 32 | temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date 33 | temp_df = temp_df[ 34 | [ 35 | "date", 36 | "close", 37 | "congestion", 38 | ] 39 | ] 40 | temp_df["close"] = pd.to_numeric(temp_df["close"], errors="coerce") 41 | temp_df["congestion"] = pd.to_numeric(temp_df["congestion"], errors="coerce") 42 | return temp_df 43 | 44 | 45 | if __name__ == "__main__": 46 | stock_a_congestion_lg_df = stock_a_congestion_lg() 47 | print(stock_a_congestion_lg_df) 48 | -------------------------------------------------------------------------------- /akshare/tool/trade_date_hist.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/3/25 16:30 5 | Desc: 新浪财经-交易日历 6 | https://finance.sina.com.cn/realstock/company/klc_td_sh.txt 7 | 此处可以用来更新 calendar.json 文件,注意末尾没有 "," 号 8 | """ 9 | 10 | import datetime 11 | 12 | import pandas as pd 13 | import requests 14 | import py_mini_racer 15 | 16 | from akshare.stock.cons import hk_js_decode 17 | 18 | 19 | def tool_trade_date_hist_sina() -> pd.DataFrame: 20 | """ 21 | 新浪财经-交易日历-历史数据 22 | https://finance.sina.com.cn/realstock/company/klc_td_sh.txt 23 | :return: 交易日历 24 | :rtype: pandas.DataFrame 25 | """ 26 | url = "https://finance.sina.com.cn/realstock/company/klc_td_sh.txt" 27 | r = requests.get(url) 28 | js_code = py_mini_racer.MiniRacer() 29 | js_code.eval(hk_js_decode) 30 | dict_list = js_code.call("d", r.text.split("=")[1].split(";")[0].replace('"', "")) 31 | temp_df = pd.DataFrame(dict_list) 32 | temp_df.columns = ["trade_date"] 33 | temp_df["trade_date"] = pd.to_datetime(temp_df["trade_date"]).dt.date 34 | temp_list = temp_df["trade_date"].to_list() 35 | # 该日期是交易日,但是在新浪返回的交易日历缺失该日期,这里补充上 36 | temp_list.append(datetime.date(year=1992, month=5, day=4)) 37 | temp_list.sort() 38 | temp_df = pd.DataFrame(temp_list, columns=["trade_date"]) 39 | return temp_df 40 | 41 | 42 | if __name__ == "__main__": 43 | tool_trade_date_hist_df = tool_trade_date_hist_sina() 44 | print(tool_trade_date_hist_df) 45 | -------------------------------------------------------------------------------- /akshare/futures/futures_rule.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/3/31 18:00 5 | Desc: 国泰君安期货-交易日历数据表 6 | https://www.gtjaqh.com/pc/calendar.html 7 | """ 8 | 9 | from io import StringIO 10 | 11 | import pandas as pd 12 | import requests 13 | 14 | 15 | def futures_rule(date: str = "20231205") -> pd.DataFrame: 16 | """ 17 | 国泰君安期货-交易日历数据表 18 | https://www.gtjaqh.com/pc/calendar.html 19 | :param date: 需要指定为交易日, 且是近期的日期 20 | :type date: str 21 | :return: 交易日历数据 22 | :rtype: pandas.DataFrame 23 | """ 24 | import urllib3 25 | 26 | urllib3.disable_warnings() 27 | url = " https://www.gtjaqh.com/pc/calendar" 28 | params = {"date": f"{date}"} 29 | r = requests.get(url, params=params, verify=False) 30 | big_df = pd.read_html(StringIO(r.text), header=1)[0] 31 | big_df["交易保证金比例"] = big_df["交易保证金比例"].str.strip("%") 32 | big_df["交易保证金比例"] = pd.to_numeric(big_df["交易保证金比例"], errors="coerce") 33 | big_df["涨跌停板幅度"] = big_df["涨跌停板幅度"].str.strip("%") 34 | big_df["涨跌停板幅度"] = pd.to_numeric(big_df["涨跌停板幅度"], errors="coerce") 35 | big_df["合约乘数"] = pd.to_numeric(big_df["合约乘数"], errors="coerce") 36 | big_df["最小变动价位"] = pd.to_numeric(big_df["最小变动价位"], errors="coerce") 37 | big_df["限价单每笔最大下单手数"] = pd.to_numeric( 38 | big_df["限价单每笔最大下单手数"], errors="coerce" 39 | ) 40 | return big_df 41 | 42 | 43 | if __name__ == "__main__": 44 | futures_rule_df = futures_rule(date="20250328") 45 | print(futures_rule_df) 46 | -------------------------------------------------------------------------------- /akshare/stock/stock_industry_sw.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/7/22 17:30 5 | Desc: 申万宏源研究-行业分类 6 | http://www.swhyresearch.com/institute_sw/allIndex/downloadCenter/industryType 7 | """ 8 | 9 | import io 10 | 11 | import pandas as pd 12 | import requests 13 | 14 | from akshare.utils.cons import headers 15 | 16 | 17 | def stock_industry_clf_hist_sw() -> pd.DataFrame: 18 | """ 19 | 申万宏源研究-行业分类-全部行业分类 20 | https://www.swsresearch.com/swindex/pdf/SwClass2021/StockClassifyUse_stock.xls 21 | :return: 个股行业分类变动历史 22 | :rtype: pandas.DataFrame 23 | """ 24 | url = "https://www.swsresearch.com/swindex/pdf/SwClass2021/StockClassifyUse_stock.xls" # 此处为 https 25 | r = requests.get(url, headers=headers) 26 | temp_df = pd.read_excel( 27 | io.BytesIO(r.content), dtype={"股票代码": "str", "行业代码": "str"} 28 | ) 29 | temp_df.rename( 30 | columns={ 31 | "股票代码": "symbol", 32 | "计入日期": "start_date", 33 | "行业代码": "industry_code", 34 | "更新日期": "update_time", 35 | }, 36 | inplace=True, 37 | ) 38 | temp_df["start_date"] = pd.to_datetime( 39 | temp_df["start_date"], errors="coerce" 40 | ).dt.date 41 | temp_df["update_time"] = pd.to_datetime( 42 | temp_df["update_time"], errors="coerce" 43 | ).dt.date 44 | return temp_df 45 | 46 | 47 | if __name__ == "__main__": 48 | stock_industry_clf_hist_sw_df = stock_industry_clf_hist_sw() 49 | print(stock_industry_clf_hist_sw_df) 50 | -------------------------------------------------------------------------------- /docs/data_tips.md: -------------------------------------------------------------------------------- 1 | # [AKShare](https://github.com/akfamily/akshare) 数据说明 2 | 3 | ## 专栏介绍 4 | 5 | 本专栏主要目的是提示数据使用的风险,包括但不限于股票、期货、期权、债券、基金、外汇等数据。 6 | 7 | ## 股票数据 8 | 9 | ### stock_zh_a_hist 10 | 11 | 接口:stock_zh_a_hist 12 | 13 | 问题描述:股票 `600734` 后复权数据的开高低收字段出现负值 14 | 15 | 代码复现: 16 | 17 | ```python 18 | import akshare as ak 19 | 20 | stock_zh_a_hist_df = ak.stock_zh_a_hist( 21 | symbol="600734", 22 | period="daily", 23 | start_date="20050501", 24 | end_date="20050520", 25 | adjust="hfq" 26 | ) 27 | print(stock_zh_a_hist_df) 28 | ``` 29 | 30 | 结果复现: 31 | 32 | ```shell 33 | 日期 开盘 收盘 最高 最低 ... 成交额 振幅 涨跌幅 涨跌额 换手率 34 | 0 2005-05-09 -0.13 -0.53 0.00 -0.53 ... 1571616.0 407.69 -507.69 -0.66 0.60 35 | 1 2005-05-10 -0.53 -0.50 -0.36 -0.79 ... 1150869.0 -81.13 5.66 0.03 0.45 36 | 2 2005-05-11 -0.50 -0.30 -0.20 -0.69 ... 1651719.0 -98.00 40.00 0.20 0.63 37 | 3 2005-05-12 -0.33 -0.20 0.00 -0.43 ... 2175707.0 -143.33 33.33 0.10 0.81 38 | 4 2005-05-13 -0.33 -0.13 0.07 -0.40 ... 1569427.0 -235.00 35.00 0.07 0.58 39 | 5 2005-05-16 -0.30 -0.10 0.10 -0.40 ... 2324469.0 -384.62 23.08 0.03 0.85 40 | 6 2005-05-17 -0.10 0.04 0.13 -0.23 ... 2682900.0 -360.00 140.00 0.14 0.96 41 | 7 2005-05-18 0.00 0.20 0.27 -0.13 ... 2261494.0 1000.00 400.00 0.16 0.81 42 | 8 2005-05-19 0.10 0.07 0.17 -0.06 ... 1589463.0 115.00 -65.00 -0.13 0.57 43 | 9 2005-05-20 0.07 0.00 0.13 -0.03 ... 1355000.0 228.57 -100.00 -0.07 0.48 44 | [10 rows x 11 columns] 45 | ``` 46 | -------------------------------------------------------------------------------- /akshare/utils/multi_decrypt.py: -------------------------------------------------------------------------------- 1 | """ 2 | 利用多进行执行 js 代码方案 3 | 4 | 1. 未能解决 gevent 调用问题 5 | 2. 导致 js 代码执行缓慢 6 | 3. 该方案废弃,这里仅作参考 7 | 8 | 同时发现 gevent 里面无法调用异步的接口 9 | """ 10 | 11 | import concurrent.futures 12 | 13 | 14 | # 定义在模块级别的函数 15 | def js_executor_function(js_code_str, method, args): 16 | """在新进程中执行 JavaScript 代码的函数""" 17 | from py_mini_racer import MiniRacer 18 | 19 | js_code = MiniRacer() 20 | js_code.eval(js_code_str) 21 | 22 | if method == "call": 23 | fn_name = args[0] 24 | fn_args = args[1:] 25 | return js_code.call(fn_name, *fn_args) 26 | elif method == "eval": 27 | return js_code.eval(args[0]) 28 | else: 29 | raise ValueError(f"不支持的方法: {method}") 30 | 31 | 32 | def execute_js_in_executor(js_code_str, method, *args, timeout=30): 33 | """ 34 | 使用 ProcessPoolExecutor 在独立进程中执行 JavaScript 35 | 36 | 参数: 37 | js_code_str: JavaScript 代码字符串 38 | method: 'call' 或 'eval' 39 | args: 如果 method 是 'call',第一个参数是函数名,后续是函数参数 40 | 如果 method 是 'eval',只需提供一个参数:要评估的代码 41 | timeout: 超时时间(秒) 42 | 43 | 返回: 44 | 执行结果 45 | """ 46 | with concurrent.futures.ProcessPoolExecutor(max_workers=1) as executor: 47 | future = executor.submit(js_executor_function, js_code_str, method, args) 48 | try: 49 | return future.result(timeout=timeout) 50 | except concurrent.futures.TimeoutError: 51 | # 清理资源并抛出超时异常 52 | executor.shutdown(wait=False) 53 | raise TimeoutError("JavaScript 执行超时") 54 | -------------------------------------------------------------------------------- /akshare/bank/cons.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2023/4/3 21:06 5 | Desc: 银保监会配置文件 6 | """ 7 | 8 | cbirc_headers_without_cookie_2020 = { 9 | "Accept": "*/*", 10 | "Accept-Encoding": "gzip, deflate", 11 | "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", 12 | "Cache-Control": "no-cache", 13 | "Connection": "keep-alive", 14 | "Host": "www.nfra.gov.cn", 15 | "Pragma": "no-cache", 16 | "Referer": "http://www.nfra.gov.cn/cn/view/pages/ItemList.html?itemPId=923&itemId=4115&itemUrl=ItemListRightList.html&itemName=%E9%93%B6%E4%BF%9D%E7%9B%91%E5%88%86%E5%B1%80%E6%9C%AC%E7%BA%A7&itemsubPId=931&itemsubPName=%E8%A1%8C%E6%94%BF%E5%A4%84%E7%BD%9A", 17 | "X-Requested-With": "XMLHttpRequest", 18 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36", 19 | } 20 | 21 | cbirc_headers_without_cookie_2019 = { 22 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", 23 | "Accept-Encoding": "gzip, deflate", 24 | "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", 25 | "Cache-Control": "no-cache", 26 | "Connection": "keep-alive", 27 | "Host": "www.nfra.gov.cn", 28 | "Pragma": "no-cache", 29 | "Referer": "http://www.nfra.gov.cn/cn/list/9103/910305/ybjjcf/1.html", 30 | "Upgrade-Insecure-Requests": "1", 31 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36", 32 | } 33 | -------------------------------------------------------------------------------- /docs/README.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | ========================================= 4 | AKShare documentation quick start guide 5 | ========================================= 6 | 7 | This file provides a quick guide on how to compile the AKShare documentation. 8 | 9 | 10 | Setup the environment 11 | --------------------- 12 | 13 | To compile the documentation you need Sphinx Python library. To install it 14 | and all its dependencies run the following command from this dir 15 | 16 | :: 17 | 18 | pip install -r requirements.txt 19 | 20 | 21 | Compile the documentation 22 | ------------------------- 23 | 24 | To compile the documentation (to classic HTML output) run the following command 25 | from this dir:: 26 | 27 | make html 28 | 29 | Documentation will be generated (in HTML format) inside the ``build/html`` dir. 30 | 31 | 32 | View the documentation 33 | ---------------------- 34 | 35 | To view the documentation run the following command:: 36 | 37 | make htmlview 38 | 39 | This command will fire up your default browser and open the main page of your 40 | (previously generated) HTML documentation. 41 | 42 | 43 | Start over 44 | ---------- 45 | 46 | To cleanup all generated documentation files and start from scratch run:: 47 | 48 | make clean 49 | 50 | Keep in mind that this command won't touch any documentation source files. 51 | 52 | 53 | Recreating documentation on the fly 54 | ----------------------------------- 55 | 56 | There is a way to recreate the doc automatically when you make changes, you 57 | need to install watchdog (``pip install watchdog``) and then use:: 58 | 59 | make watch 60 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_ttm_lyr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/10/30 15:00 5 | Desc: 全部A股-等权重市盈率、中位数市盈率 6 | https://www.legulegu.com/stockdata/a-ttm-lyr 7 | """ 8 | import pandas as pd 9 | import requests 10 | 11 | from akshare.stock_feature.stock_a_indicator import get_token_lg, get_cookie_csrf 12 | 13 | 14 | def stock_a_ttm_lyr() -> pd.DataFrame: 15 | """ 16 | 全部 A 股-等权重市盈率、中位数市盈率 17 | :return: 全部A股-等权重市盈率、中位数市盈率 18 | :rtype: pandas.DataFrame 19 | """ 20 | 21 | url = "https://legulegu.com/api/stock-data/market-ttm-lyr" 22 | params = { 23 | "marketId": "5", 24 | "token": get_token_lg(), 25 | } 26 | # 获取 cookie 和 headers 27 | csrf_data = get_cookie_csrf(url="https://www.legulegu.com/stockdata/a-ttm-lyr") 28 | # 使用返回的 headers(已经是副本) 29 | request_headers = csrf_data['headers'].copy() 30 | request_headers.update({ 31 | "host": "www.legulegu.com", 32 | "referer": "https://www.legulegu.com/stockdata/a-ttm-lyr", 33 | }) 34 | # 使用独立的 session 35 | session = requests.Session() 36 | r = session.get( 37 | url, 38 | params=params, 39 | cookies=csrf_data['cookies'], 40 | headers=request_headers, 41 | ) 42 | data_json = r.json() 43 | temp_df = pd.DataFrame(data_json["data"]) 44 | temp_df["date"] = pd.to_datetime(temp_df["date"], errors="coerce").dt.date 45 | # 关闭 session 46 | session.close() 47 | return temp_df 48 | 49 | 50 | if __name__ == "__main__": 51 | stock_a_ttm_lyr_df = stock_a_ttm_lyr() 52 | print(stock_a_ttm_lyr_df) 53 | -------------------------------------------------------------------------------- /docs/data/hf/hf.md: -------------------------------------------------------------------------------- 1 | ## [AKShare](https://github.com/akfamily/akshare) 高频数据 2 | 3 | ### 标普 500 指数 4 | 5 | 接口: hf_sp_500 6 | 7 | 目标地址: https://github.com/FutureSharks/financial-data 8 | 9 | 描述: 获取标普 500 指数的分钟数据, 由于数据量比较大, 需要等待, 由于服务器在国外, 建议使用代理访问 10 | 11 | 输入参数 12 | 13 | | 名称 | 类型 | 描述 | 14 | |------|-----|--------------------------------------| 15 | | year | str | year="2017"; 只能获取 **2012-2018** 年的数据 | 16 | 17 | 输出参数 18 | 19 | | 名称 | 类型 | 描述 | 20 | |-------|---------|------| 21 | | date | object | 日期时间 | 22 | | open | float64 | 开盘价 | 23 | | high | float64 | 最高价 | 24 | | low | float64 | 最低价 | 25 | | close | float64 | 收盘价 | 26 | 27 | 接口示例 28 | 29 | ```python 30 | import akshare as ak 31 | 32 | hf_sp_500_df = ak.hf_sp_500(year="2017") 33 | print(hf_sp_500_df) 34 | ``` 35 | 36 | 数据示例 37 | 38 | ``` 39 | date open high low close price 40 | 0 2017-01-02 2241.00 2244.50 2241.00 2243.50 0 41 | 1 2017-01-02 2243.75 2243.75 2243.00 2243.00 0 42 | 2 2017-01-02 2243.25 2243.25 2243.00 2243.25 0 43 | 3 2017-01-02 2243.00 2243.00 2243.00 2243.00 0 44 | 4 2017-01-02 2243.25 2243.75 2243.25 2243.75 0 45 | ... ... ... ... ... ... ... 46 | 222021 2017-12-29 2669.50 2669.75 2669.25 2669.25 0 47 | 222022 2017-12-29 2669.00 2669.25 2669.00 2669.00 0 48 | 222023 2017-12-29 2668.75 2668.75 2668.00 2668.25 0 49 | 222024 2017-12-29 2667.75 2668.50 2667.75 2668.00 0 50 | 222025 2017-12-29 2668.25 2668.50 2667.75 2668.50 0 51 | ``` 52 | -------------------------------------------------------------------------------- /akshare/index/index_hog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/3/21 11:16 5 | Desc: 行情宝 6 | https://hqb.nxin.com/pigindex/index.shtml 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def index_hog_spot_price() -> pd.DataFrame: 14 | """ 15 | 行情宝-生猪市场价格指数 16 | https://hqb.nxin.com/pigindex/index.shtml 17 | :return: 生猪市场价格指数 18 | :rtype: pandas.DataFrame 19 | """ 20 | url = "https://hqb.nxin.com/pigindex/getPigIndexChart.shtml" 21 | params = {"regionId": "0"} 22 | r = requests.get(url, params=params) 23 | data_json = r.json() 24 | temp_df = pd.DataFrame(data_json["data"]) 25 | temp_df.columns = [ 26 | "日期", 27 | "指数", 28 | "4个月均线", 29 | "6个月均线", 30 | "12个月均线", 31 | "预售均价", 32 | "成交均价", 33 | "成交均重", 34 | ] 35 | temp_df["日期"] = ( 36 | pd.to_datetime(temp_df["日期"], unit="ms") + pd.Timedelta(hours=8) 37 | ).dt.date 38 | temp_df["指数"] = pd.to_numeric(temp_df["指数"], errors="coerce") 39 | temp_df["4个月均线"] = pd.to_numeric(temp_df["4个月均线"], errors="coerce") 40 | temp_df["6个月均线"] = pd.to_numeric(temp_df["6个月均线"], errors="coerce") 41 | temp_df["12个月均线"] = pd.to_numeric(temp_df["12个月均线"], errors="coerce") 42 | temp_df["预售均价"] = pd.to_numeric(temp_df["预售均价"], errors="coerce") 43 | temp_df["成交均价"] = pd.to_numeric(temp_df["成交均价"], errors="coerce") 44 | temp_df["成交均重"] = pd.to_numeric(temp_df["成交均重"], errors="coerce") 45 | return temp_df 46 | 47 | 48 | if __name__ == "__main__": 49 | index_hog_spot_price_df = index_hog_spot_price() 50 | print(index_hog_spot_price_df) 51 | -------------------------------------------------------------------------------- /akshare/index/index_stock_us_sina.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/3/17 18:20 5 | Desc: 新浪财经-美股指数行情 6 | https://stock.finance.sina.com.cn/usstock/quotes/.IXIC.html 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | import py_mini_racer 12 | 13 | from akshare.stock.cons import ( 14 | zh_js_decode, 15 | ) 16 | 17 | 18 | def index_us_stock_sina(symbol: str = ".INX") -> pd.DataFrame: 19 | """ 20 | 新浪财经-美股指数行情 21 | https://stock.finance.sina.com.cn/usstock/quotes/.IXIC.html 22 | :param symbol: choice of {".IXIC", ".DJI", ".INX", ".NDX"} 23 | :type symbol: str 24 | :return: 美股指数行情 25 | :rtype: pandas.DataFrame 26 | """ 27 | url = f"https://finance.sina.com.cn/staticdata/us/{symbol}" 28 | r = requests.get(url) 29 | js_code = py_mini_racer.MiniRacer() 30 | js_code.eval(zh_js_decode) 31 | dict_list = js_code.call("d", r.text.split("=")[1].split(";")[0].replace('"', "")) 32 | temp_df = pd.DataFrame(dict_list) 33 | temp_df["date"] = pd.to_datetime(temp_df["date"], errors="coerce").dt.date 34 | temp_df["open"] = pd.to_numeric(temp_df["open"], errors="coerce") 35 | temp_df["high"] = pd.to_numeric(temp_df["high"], errors="coerce") 36 | temp_df["low"] = pd.to_numeric(temp_df["low"], errors="coerce") 37 | temp_df["close"] = pd.to_numeric(temp_df["close"], errors="coerce") 38 | temp_df["volume"] = pd.to_numeric(temp_df["volume"], errors="coerce") 39 | temp_df["amount"] = pd.to_numeric(temp_df["amount"], errors="coerce") 40 | return temp_df 41 | 42 | 43 | if __name__ == "__main__": 44 | index_us_stock_sina_df = index_us_stock_sina(symbol=".INX") 45 | print(index_us_stock_sina_df) 46 | -------------------------------------------------------------------------------- /akshare/futures/futures_stock_js.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/4/24 18:10 5 | Desc: 上海期货交易所指定交割仓库库存周报 6 | https://datacenter.jin10.com/reportType/dc_shfe_weekly_stock 7 | https://tsite.shfe.com.cn/statements/dataview.html?paramid=kx 8 | """ 9 | 10 | import pandas as pd 11 | import requests 12 | 13 | 14 | def futures_stock_shfe_js(date: str = "20240419") -> pd.DataFrame: 15 | """ 16 | 金十财经-上海期货交易所指定交割仓库库存周报 17 | https://datacenter.jin10.com/reportType/dc_shfe_weekly_stock 18 | :param date: 交易日; 库存周报只在每周的最后一个交易日公布数据 19 | :type date: str 20 | :return: 库存周报 21 | :rtype: pandas.Series 22 | """ 23 | headers = { 24 | "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " 25 | "Chrome/107.0.0.0 Safari/537.36", 26 | "x-app-id": "rU6QIu7JHe2gOUeR", 27 | "x-csrf-token": "x-csrf-token", 28 | "x-version": "1.0.0", 29 | } 30 | url = "https://datacenter-api.jin10.com/reports/list" 31 | params = { 32 | "category": "stock", 33 | "date": "-".join([date[:4], date[4:6], date[6:]]), 34 | "attr_id": "1", 35 | } 36 | r = requests.get(url, params=params, headers=headers) 37 | data_json = r.json() 38 | columns_list = [item["name"] for item in data_json["data"]["keys"]] 39 | temp_df = pd.DataFrame(data_json["data"]["values"], columns=columns_list) 40 | for item in columns_list[1:]: 41 | temp_df[item] = pd.to_numeric(temp_df[item], errors="coerce") 42 | return temp_df 43 | 44 | 45 | if __name__ == "__main__": 46 | futures_stock_shfe_js_df = futures_stock_shfe_js(date="20240419") 47 | print(futures_stock_shfe_js_df) 48 | -------------------------------------------------------------------------------- /akshare/index/index_spot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/12/26 18:30 5 | Desc: 商品现货价格指数 6 | https://finance.sina.com.cn/futuremarket/spotprice.shtml#titlePos_0 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def spot_goods(symbol: str = "波罗的海干散货指数") -> pd.DataFrame: 14 | """ 15 | 新浪财经-商品现货价格指数 16 | https://finance.sina.com.cn/futuremarket/spotprice.shtml#titlePos_0 17 | :param symbol: choice of {"波罗的海干散货指数", "钢坯价格指数", "澳大利亚粉矿价格"} 18 | :type symbol: str 19 | :return: 商品现货价格指数 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = "https://stock.finance.sina.com.cn/futures/api/openapi.php/GoodsIndexService.get_goods_index" 23 | symbol_url_dict = { 24 | "波罗的海干散货指数": "BDI", 25 | "钢坯价格指数": "GP", 26 | "澳大利亚粉矿价格": "PB", 27 | } 28 | params = {"symbol": symbol_url_dict[symbol], "table": "0"} 29 | r = requests.get(url, params=params) 30 | r.encoding = "gbk" 31 | data_json = r.json() 32 | temp_df = pd.DataFrame(data_json["result"]["data"]["data"]) 33 | temp_df = temp_df[["opendate", "price", "zde", "zdf"]] 34 | temp_df.columns = ["日期", "指数", "涨跌额", "涨跌幅"] 35 | temp_df["日期"] = pd.to_datetime( 36 | temp_df["日期"], format="%Y-%m-%d", errors="coerce" 37 | ).dt.date 38 | temp_df["指数"] = pd.to_numeric(temp_df["指数"], errors="coerce") 39 | temp_df["涨跌额"] = pd.to_numeric(temp_df["涨跌额"], errors="coerce") 40 | temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce") 41 | temp_df.dropna(inplace=True, ignore_index=True) 42 | return temp_df 43 | 44 | 45 | if __name__ == "__main__": 46 | spot_goods_df = spot_goods(symbol="波罗的海干散货指数") 47 | print(spot_goods_df) 48 | -------------------------------------------------------------------------------- /akshare/stock_fundamental/stock_zyjs_ths.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2024/3/29 10:30 5 | Desc: 同花顺-主营介绍 6 | https://basic.10jqka.com.cn/new/000066/operate.html 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | from bs4 import BeautifulSoup 12 | 13 | 14 | def stock_zyjs_ths(symbol: str = "000066") -> pd.DataFrame: 15 | """ 16 | 同花顺-主营介绍 17 | https://basic.10jqka.com.cn/new/000066/operate.html 18 | :param symbol: 股票代码 19 | :type symbol: str 20 | :return: 主营介绍 21 | :rtype: pandas.DataFrame 22 | """ 23 | url = f"https://basic.10jqka.com.cn/new/{symbol}/operate.html" 24 | headers = { 25 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " 26 | "Chrome/109.0.0.0 Safari/537.36" 27 | } 28 | r = requests.get(url, headers=headers) 29 | r.encoding = "gb2312" 30 | soup = BeautifulSoup(r.text, "lxml") 31 | content_list = [ 32 | item.text.strip() 33 | for item in soup.find("ul", attrs={"class": "main_intro_list"}).find_all("li") 34 | ] 35 | columns_list = [] 36 | value_list = [] 37 | for item in content_list: 38 | columns_list.append(item.split(":")[0]) 39 | value_list.append( 40 | item.split(":", maxsplit=1)[1] 41 | .replace("\t", "") 42 | .replace("\n", "") 43 | .replace(" ", "") 44 | .strip() 45 | ) 46 | 47 | temp_df = pd.DataFrame(value_list, index=columns_list).T 48 | temp_df.insert(0, "股票代码", symbol) 49 | return temp_df 50 | 51 | 52 | if __name__ == "__main__": 53 | stock_zyjs_ths_df = stock_zyjs_ths(symbol="000066") 54 | print(stock_zyjs_ths_df) 55 | -------------------------------------------------------------------------------- /akshare/stock_fundamental/stock_kcb_sse.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2022/4/7 17:36 5 | Desc: http://kcb.sse.com.cn/renewal/# 6 | """ 7 | 8 | import requests 9 | import pandas as pd 10 | 11 | # TODO 12 | 13 | 14 | def stock_kcb_renewal(): 15 | url = "http://query.sse.com.cn/statusAction.do" 16 | params = { 17 | "isPagination": "true", 18 | "sqlId": "SH_XM_LB", 19 | "pageHelp.pageSize": "20", 20 | "offerType": "", 21 | "commitiResult": "", 22 | "registeResult": "", 23 | "province": "", 24 | "csrcCode": "", 25 | "currStatus": "", 26 | "order": "updateDate|desc,stockAuditNum|desc", 27 | "keyword": "", 28 | "auditApplyDateBegin": "", 29 | "auditApplyDateEnd": "", 30 | "pageHelp.pageNo": "1", 31 | "pageHelp.beginPage": "1", 32 | "pageHelp.endPage": "1", 33 | "_": "1649322742207", 34 | } 35 | headers = { 36 | "Host": "query.sse.com.cn", 37 | "Pragma": "no-cache", 38 | "Referer": "http://kcb.sse.com.cn/", 39 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36", 40 | } 41 | 42 | for page in range(1, 37): 43 | print(page) 44 | params.update( 45 | { 46 | "pageHelp.pageNo": page, 47 | "pageHelp.beginPage": page, 48 | "pageHelp.endPage": page, 49 | } 50 | ) 51 | r = requests.get(url, params=params, headers=headers) 52 | data_json = r.json() 53 | temp_df = pd.DataFrame(data_json["result"]) 54 | # 处理下 temp_df 里面的字段就可以了 55 | print(temp_df) 56 | break 57 | -------------------------------------------------------------------------------- /docs/trade.md: -------------------------------------------------------------------------------- 1 | # [AKShare](https://github.com/akfamily/akshare) 实盘交易 2 | 3 | ## 证券实盘 4 | 5 | ### 股票量化交易服务 6 | 7 | 提供股票、期权、两融等账户的实盘 API 接口对接,让量化模型不仅仅停留在一次次的回测中,真正做到让策略跑起来。 8 | 9 | 专注于为股票、可转债、ETF 期权以及两融策略提供全面的量化服务;针对各种个性化的量化策略,提供高效的解决方案。 10 | 11 | 为了满足不同的客户需求,我们还提供策略编写、个性化工具开发等定制服务,确保不同阶段的量化投资者都能得到有效的支持。 12 | 13 | 当下由**上市证券**专业量化服务团队提供支持,微信:cmdtzz168 14 | 15 | ![gj_wechat](https://jfds-1252952517.cos.ap-chengdu.myqcloud.com/akshare/ad/gj_wechat.png) 16 | 17 | 一、多维度的专业量化服务 18 | 19 | 1. 费用优惠:股票/ETF/可转债/港股通/北交所/两融等费率超优惠。 20 | 2. 专业服务:团队专注量化领域十载,提供多种定制化服务和量化工具,积累了大量的成功案例。 21 | 3. 高效服务:多对一,响应快,提供 7*12 小时服务。 22 | 23 | 二、辅助量化工具的使用 24 | 25 | 1. 数据库:AKShare 26 | 2. 股票软件:通达信/大智慧/同花顺等 27 | 3. 量化软件:QMT/PTRADE/聚宽/bigquant等 28 | 29 | 三、更多个性化定制服务 30 | 31 | 1. 【极速策略】如追涨停、盘前/盘中打板、尾盘强筹,根据具体需求,优化每个环节,给出极速解决方案,提高策略效率,快人一步。 32 | 2. 【指标定制】将通达信/大智慧/同花顺等指标转化为可执行的量化策略,做到条件预警、展示买卖点等。 33 | 3. 【量化工具定制】各种量化小插件随心定制,如自动止盈止损/自动仓位管理等。 34 | 35 | 与**某AA级期货公司**量化服务团队携手开发对冲策略,股期联动,祝您一臂之力。 36 | 37 | 在量化领域:专业、专心、专注。 38 | 39 | ## 期货实盘 40 | 41 | ### 期货量化交易服务 42 | 43 | 什么是量化交易服务? 44 | 45 | 以服务客户为核心的增值服务,服务包括量化咨询、量化软件指导、策略编写、软件定制、外接托管等服务,为客户量化交易之路保驾护航。 46 | 目前我们发现**某AA级期货公司**在此服务上比较专业。![futures](https://jfds-1252952517.cos.ap-chengdu.myqcloud.com/akshare/ad/futures.jpg) 47 | 48 | 有什么样的量化交易服务综合方案? 49 | 50 | 一、量化咨询,维度提升 51 | 52 | 1. 超优惠的政策:期货交易手续费的杀伤力非常大,手续费成本可能决定交易策略期望值是否为正; 53 | 2. 超高效的服务:为客户实行一对一、二对一私享服务,及时解决客户问题; 54 | 3. 超专业的咨询:宏源量化服务团队成员在期货领域经验丰富,可提供量化咨询服务,助力客户高效开发策略,少走弯路; 55 | 56 | 二、软件指导,轻松上手 57 | 58 | AKShare 的金融数据能够给大家带来许多帮助,也可以结合其他量化交易软件进行实战应用,每个交易软件都有自己的特色功能, 59 | 有了专业的指导,可以更高效的运用起来。 60 | 61 | 三、编写策略,解放双手 62 | 63 | 服务团队成员有交易经历丰富的私募基金交易员,能够高效的转化客户的主观交易策略,让客户实现程序化交易,解放双手。 64 | 65 | 四、速度优化,快人一步 66 | 67 | ![futures_process](https://jfds-1252952517.cos.ap-chengdu.myqcloud.com/akshare/ad/futures_process.png) 68 | 69 | 提供托管定制服务:通过专用网络、专用系统、专用席位、服务器托管等手段来保障高效、稳定的交易。 70 | 71 | 专业的事找专业的人! 72 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_ebs_lg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/3/19 15:30 5 | Desc: 乐咕乐股-股债利差 6 | https://legulegu.com/stockdata/equity-bond-spread 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | from akshare.stock_feature.stock_a_indicator import get_token_lg, get_cookie_csrf 13 | 14 | 15 | def stock_ebs_lg() -> pd.DataFrame: 16 | """ 17 | 乐咕乐股-股债利差 18 | https://legulegu.com/stockdata/equity-bond-spread 19 | :return: 股债利差 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = "https://legulegu.com/api/stockdata/equity-bond-spread" 23 | token = get_token_lg() 24 | params = {"token": token, "code": "000300.SH"} 25 | r = requests.get( 26 | url, 27 | params=params, 28 | **get_cookie_csrf(url="https://legulegu.com/stockdata/equity-bond-spread"), 29 | ) 30 | data_json = r.json() 31 | temp_df = pd.DataFrame(data_json["data"]) 32 | temp_df["date"] = pd.to_datetime(temp_df["date"], errors="coerce").dt.date 33 | temp_df.rename( 34 | columns={ 35 | "date": "日期", 36 | "close": "沪深300指数", 37 | "peSpread": "股债利差", 38 | "peSpreadAverage": "股债利差均线", 39 | }, 40 | inplace=True, 41 | ) 42 | temp_df = temp_df[ 43 | [ 44 | "日期", 45 | "沪深300指数", 46 | "股债利差", 47 | "股债利差均线", 48 | ] 49 | ] 50 | temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date 51 | temp_df["沪深300指数"] = pd.to_numeric(temp_df["沪深300指数"], errors="coerce") 52 | temp_df["股债利差"] = pd.to_numeric(temp_df["股债利差"], errors="coerce") 53 | temp_df["股债利差均线"] = pd.to_numeric(temp_df["股债利差均线"], errors="coerce") 54 | return temp_df 55 | 56 | 57 | if __name__ == "__main__": 58 | stock_ebs_lg_df = stock_ebs_lg() 59 | print(stock_ebs_lg_df) 60 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_zh_vote_baidu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2022/10/10 17:26 5 | Desc: 百度股市通- A 股或指数-股评-投票 6 | https://gushitong.baidu.com/index/ab-000001 7 | """ 8 | 9 | import requests 10 | import pandas as pd 11 | 12 | 13 | def stock_zh_vote_baidu( 14 | symbol: str = "000001", indicator: str = "指数" 15 | ) -> pd.DataFrame: 16 | """ 17 | 百度股市通- A 股或指数-股评-投票 18 | https://gushitong.baidu.com/index/ab-000001 19 | :param symbol: 股票代码 20 | :type symbol: str 21 | :param indicator: choice of {"指数", "股票"} 22 | :type indicator: str 23 | :return: 投票数据 24 | :rtype: pandas.DataFrame 25 | """ 26 | indicator_map = {"股票": "stock", "指数": "index"} 27 | url = "https://finance.pae.baidu.com/vapi/v1/stockvoterecords" 28 | params = { 29 | "code": symbol, 30 | "market": "ab", 31 | "finance_type": indicator_map[indicator], 32 | "select_type": "week", 33 | "from_smart_app": "0", 34 | "method": "query", 35 | "finClientType": "pc", 36 | } 37 | temp_list = [] 38 | for item_period in ["day", "week", "month", "year"]: 39 | params.update({"select_type": item_period}) 40 | r = requests.get(url, params=params) 41 | data_json = r.json() 42 | temp_list.append( 43 | [ 44 | item 45 | for item in data_json["Result"]["voteRecords"]["voteRes"] 46 | if item["type"] == item_period 47 | ][0] 48 | ) 49 | temp_df = pd.DataFrame(temp_list) 50 | temp_df.columns = ["周期", "-", "看涨", "看跌", "看涨比例", "看跌比例"] 51 | temp_df = temp_df[["周期", "看涨", "看跌", "看涨比例", "看跌比例"]] 52 | return temp_df 53 | 54 | 55 | if __name__ == "__main__": 56 | stock_zh_vote_baidu_df = stock_zh_vote_baidu(symbol="000001", indicator="指数") 57 | print(stock_zh_vote_baidu_df) 58 | -------------------------------------------------------------------------------- /akshare/bond/bond_cb_sina.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2023/9/12 16:50 5 | Desc: 新浪财经-债券-可转债 6 | https://money.finance.sina.com.cn/bond/info/sz128039.html 7 | """ 8 | 9 | from io import StringIO 10 | 11 | import pandas as pd 12 | import requests 13 | 14 | 15 | def bond_cb_profile_sina(symbol: str = "sz128039") -> pd.DataFrame: 16 | """ 17 | 新浪财经-债券-可转债-详情资料 18 | https://money.finance.sina.com.cn/bond/info/sz128039.html 19 | :param symbol: 带市场标识的转债代码 20 | :type symbol: str 21 | :return: 可转债-详情资料 22 | :rtype: pandas.DataFrame 23 | """ 24 | url = f"https://money.finance.sina.com.cn/bond/info/{symbol}.html" 25 | r = requests.get(url) 26 | temp_df = pd.read_html(StringIO(r.text))[0] 27 | temp_df.columns = ["item", "value"] 28 | return temp_df 29 | 30 | 31 | def bond_cb_summary_sina(symbol: str = "sh155255") -> pd.DataFrame: 32 | """ 33 | 新浪财经-债券-可转债-债券概况 34 | https://money.finance.sina.com.cn/bond/quotes/sh155255.html 35 | :param symbol: 带市场标识的转债代码 36 | :type symbol: str 37 | :return: 可转债-债券概况 38 | :rtype: pandas.DataFrame 39 | """ 40 | url = f"https://money.finance.sina.com.cn/bond/quotes/{symbol}.html" 41 | r = requests.get(url) 42 | temp_df = pd.read_html(StringIO(r.text))[10] 43 | part1 = temp_df.iloc[:, 0:2].copy() 44 | part1.columns = ["item", "value"] 45 | part2 = temp_df.iloc[:, 2:4].copy() 46 | part2.columns = ["item", "value"] 47 | part3 = temp_df.iloc[:, 4:6].copy() 48 | part3.columns = ["item", "value"] 49 | big_df = pd.concat(objs=[part1, part2, part3], ignore_index=True) 50 | return big_df 51 | 52 | 53 | if __name__ == "__main__": 54 | bond_cb_profile_sina_df = bond_cb_profile_sina(symbol="sz128039") 55 | print(bond_cb_profile_sina_df) 56 | 57 | bond_cb_summary_sina_df = bond_cb_summary_sina(symbol="sh155255") 58 | print(bond_cb_summary_sina_df) 59 | -------------------------------------------------------------------------------- /docs/data/bank/bank.md: -------------------------------------------------------------------------------- 1 | ## [AKShare](https://github.com/akfamily/akshare) 银行数据 2 | 3 | ### 银保监分局本级行政处罚 4 | 5 | 接口: bank_fjcf_table_detail 6 | 7 | 目标地址: https://www.cbirc.gov.cn/cn/view/pages/ItemDetail.html?docId=881574&itemId=4115&generaltype=9 8 | 9 | 描述: 首页-政务信息-行政处罚-银保监分局本级-XXXX行政处罚信息公开表, 是信息公开表不是处罚决定书书 10 | 11 | 限量: 单次返回银保监分局本级行政处罚中的指定页数的所有表格数据 12 | 13 | 输入参数 14 | 15 | | 名称 | 类型 | 描述 | 16 | |-------|-----|---------------------------------------------| 17 | | page | int | page=5; 获取前 5 页数据, 并返回处理好后的数据框 | 18 | | item | int | item="分局本级"; choice of {"机关", "本级", "分局本级"} | 19 | | begin | int | begin=1; 开始页面 | 20 | 21 | 输出参数-分局本级 22 | 23 | | 名称 | 类型 | 描述 | 24 | |--------------|----|----| 25 | | 行政处罚决定书文号 | - | - | 26 | | 姓名 | - | - | 27 | | 单位 | - | - | 28 | | 单位名称 | - | - | 29 | | 主要负责人姓名 | - | - | 30 | | 主要违法违规事实(案由) | - | - | 31 | | 行政处罚依据 | - | - | 32 | | 行政处罚决定 | - | - | 33 | | 作出处罚决定的机关名称 | - | - | 34 | | 作出处罚决定的日期 | - | - | 35 | 36 | 接口示例 37 | 38 | ```python 39 | import akshare as ak 40 | 41 | bank_fjcf_table_detail_df = ak.bank_fjcf_table_detail(page=5, item="分局本级") 42 | print(bank_fjcf_table_detail_df) 43 | ``` 44 | 45 | 数据示例 46 | 47 | ``` 48 | 行政处罚决定书文号 ... 处罚公布日期 49 | 0 楚金罚决字〔2024〕9号 ... 2024-02-08 18:38:00 50 | 1 楚金罚决字〔2024〕8号 ... 2024-02-08 18:28:00 51 | 2 楚金罚决字〔2024〕7号 ... 2024-02-08 18:18:00 52 | 3 遵金罚决字〔2024〕4号 ... 2024-02-08 17:04:00 53 | 4 遵金罚决字〔2024〕3号 ... 2024-02-08 17:03:00 54 | .. ... ... ... 55 | 85 吉金监罚决字〔2024〕9号 ... 2024-02-02 12:19:02 56 | 86 吉金监罚决字〔2024〕8号 ... 2024-02-02 12:18:30 57 | 87 吉金监罚决字〔2024〕7号 ... 2024-02-02 12:17:47 58 | 88 吉金监罚决字〔2024〕6号 ... 2024-02-02 12:17:08 59 | 89 吉金监罚决字〔2024〕5号 ... 2024-02-02 11:47:50 60 | [90 rows x 12 columns] 61 | ``` 62 | -------------------------------------------------------------------------------- /akshare/stock_fundamental/stock_ipo_declare.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2022/1/7 17:02 5 | Desc: 东方财富网-数据中心-新股申购-首发申报信息-首发申报企业信息 6 | https://data.eastmoney.com/xg/xg/sbqy.html 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | from akshare.utils import demjson 13 | 14 | 15 | def stock_ipo_declare() -> pd.DataFrame: 16 | """ 17 | 东方财富网-数据中心-新股申购-首发申报信息-首发申报企业信息 18 | https://data.eastmoney.com/xg/xg/sbqy.html 19 | :return: 首发申报企业信息 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = "https://datainterface.eastmoney.com/EM_DataCenter/JS.aspx" 23 | params = { 24 | "st": "1", 25 | "sr": "-1", 26 | "ps": "500", 27 | "p": "1", 28 | "type": "NS", 29 | "sty": "NSFR", 30 | "js": "({data:[(x)],pages:(pc)})", 31 | "mkt": "1", 32 | "fd": "2021-04-02", 33 | } 34 | r = requests.get(url, params=params) 35 | data_text = r.text 36 | data_json = demjson.decode(data_text[1:-1]) 37 | temp_df = pd.DataFrame([item.split(",") for item in data_json["data"]]) 38 | temp_df.reset_index(inplace=True) 39 | temp_df["index"] = temp_df.index + 1 40 | temp_df.columns = [ 41 | "序号", 42 | "会计师事务所", 43 | "_", 44 | "保荐机构", 45 | "_", 46 | "律师事务所", 47 | "_", 48 | "_", 49 | "拟上市地", 50 | "_", 51 | "_", 52 | "备注", 53 | "申报企业", 54 | "_", 55 | "_", 56 | "_", 57 | "_", 58 | ] 59 | temp_df = temp_df[ 60 | [ 61 | "序号", 62 | "申报企业", 63 | "拟上市地", 64 | "保荐机构", 65 | "会计师事务所", 66 | "律师事务所", 67 | "备注", 68 | ] 69 | ] 70 | return temp_df 71 | 72 | 73 | if __name__ == "__main__": 74 | stock_ipo_declare_df = stock_ipo_declare() 75 | print(stock_ipo_declare_df) 76 | -------------------------------------------------------------------------------- /akshare/futures/futures_index_ccidx.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2025/10/29 15:00 5 | Desc: 中证商品指数 6 | http://www.ccidx.com/ 7 | """ 8 | 9 | import json 10 | 11 | import pandas as pd 12 | import requests 13 | 14 | 15 | def futures_index_ccidx(symbol: str = "中证商品期货指数") -> pd.DataFrame: 16 | """ 17 | 中证商品指数-商品指数-日频率 18 | http://www.ccidx.com/index.html 19 | :param symbol: choice of {"中证商品期货指数", "中证商品期货价格指数"} 20 | :type symbol: str 21 | :return: 商品指数-日频率 22 | :rtype: pandas.DataFrame 23 | """ 24 | futures_index_map = { 25 | "中证商品期货指数": "100001.CCI", 26 | "中证商品期货价格指数": "000001.CCI", 27 | } 28 | url = "http://www.ccidx.com/CCI-ZZZS/index/getDateLine" 29 | params = {"indexId": futures_index_map[symbol]} 30 | r = requests.get(url, params=params) 31 | data_json = r.json() 32 | temp_df = pd.DataFrame( 33 | [json.loads(item) for item in data_json["data"]["dateLineJson"]] 34 | ) 35 | temp_df.rename( 36 | columns={ 37 | "tradeDate": "日期", 38 | "indexId": "指数代码", 39 | "closingPrice": "收盘点位", 40 | "settlePrice": "结算点位", 41 | "dailyIncreaseAndDecrease": "涨跌", 42 | "dailyIncreaseAndDecreasePercentage": "涨跌幅", 43 | }, 44 | inplace=True, 45 | ) 46 | 47 | temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date 48 | temp_df["收盘点位"] = pd.to_numeric(temp_df["收盘点位"], errors="coerce") 49 | temp_df["结算点位"] = pd.to_numeric(temp_df["结算点位"], errors="coerce") 50 | temp_df["涨跌"] = pd.to_numeric(temp_df["涨跌"], errors="coerce") 51 | temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce") 52 | temp_df.sort_values(by=["日期"], inplace=True) 53 | temp_df.reset_index(inplace=True, drop=True) 54 | return temp_df 55 | 56 | 57 | if __name__ == "__main__": 58 | futures_index_ccidx_df = futures_index_ccidx(symbol="中证商品期货指数") 59 | print(futures_index_ccidx_df) 60 | -------------------------------------------------------------------------------- /akshare/fx/fx_c_swap_cm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/9/9 14:57 5 | Desc: 中国外汇交易中心暨全国银行间同业拆借中心-基准-外汇市场-外汇掉期曲线-外汇掉漆 C-Swap 定盘曲线 6 | https://www.chinamoney.org.cn/chinese/bkcurvfsw 7 | """ 8 | 9 | import ssl 10 | 11 | import pandas as pd 12 | import requests 13 | from requests.adapters import HTTPAdapter 14 | 15 | 16 | class LegacySSLAdapter(HTTPAdapter): 17 | def init_poolmanager(self, *args, **kwargs): 18 | context = ssl.create_default_context() 19 | # 允许不安全的 legacy renegotiation 20 | context.options |= ssl.OP_LEGACY_SERVER_CONNECT 21 | kwargs['ssl_context'] = context 22 | return super().init_poolmanager(*args, **kwargs) 23 | 24 | 25 | def fx_c_swap_cm(): 26 | """ 27 | 中国外汇交易中心暨全国银行间同业拆借中心-基准-外汇市场-外汇掉期曲线-外汇掉期 C-Swap 定盘曲线 28 | https://www.chinamoney.org.cn/chinese/bkcurvfsw 29 | :return: 外汇掉期 C-Swap 定盘曲线 30 | :rtype: pandas.DataFrame 31 | """ 32 | session = requests.Session() 33 | session.mount(prefix='https://', adapter=LegacySSLAdapter()) 34 | url = "https://www.chinamoney.org.cn/r/cms/www/chinamoney/data/fx/fx-c-sw-curv-USD.CNY.json" 35 | payload = { 36 | "t": "1757402201554", 37 | } 38 | r = session.post(url, data=payload) 39 | data_json = r.json() 40 | temp_df = pd.DataFrame(data_json['records']) 41 | temp_df.rename(columns={ 42 | "curveTime": "日期时间", 43 | "tenor": "期限品种", 44 | "swapPnt": "掉期点(Pips)", 45 | "dataSource": "掉期点数据源", 46 | "swapAllPrc": "全价汇率", 47 | }, inplace=True) 48 | temp_df = temp_df[[ 49 | "日期时间", 50 | "期限品种", 51 | "掉期点(Pips)", 52 | "掉期点数据源", 53 | "全价汇率", 54 | ]] 55 | temp_df["掉期点(Pips)"] = pd.to_numeric(temp_df["掉期点(Pips)"], errors='coerce') 56 | temp_df["全价汇率"] = pd.to_numeric(temp_df["全价汇率"], errors='coerce') 57 | return temp_df 58 | 59 | 60 | if __name__ == '__main__': 61 | fx_c_swap_cm_df = fx_c_swap_cm() 62 | print(fx_c_swap_cm_df) 63 | -------------------------------------------------------------------------------- /akshare/bond/cons.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/10/20 10:21 5 | Desc: 债券配置文件 6 | """ 7 | 8 | # bond-cov-sina 9 | zh_sina_bond_hs_cov_url = "http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeDataSimple" 10 | zh_sina_bond_hs_cov_count_url = "http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeStockCountSimple" 11 | zh_sina_bond_hs_cov_hist_url = ( 12 | "https://finance.sina.com.cn/realstock/company/{}/hisdata/klc_kl.js?d={}" 13 | ) 14 | zh_sina_bond_hs_cov_payload = { 15 | "page": "1", 16 | "num": "80", 17 | "sort": "symbol", 18 | "asc": "1", 19 | "node": "hskzz_z", 20 | "_s_r_a": "page", 21 | } 22 | 23 | # bond-sina 24 | zh_sina_bond_hs_url = "http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeData" 25 | zh_sina_bond_hs_count_url = "http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeStockCountSimple" 26 | zh_sina_bond_hs_hist_url = ( 27 | "https://finance.sina.com.cn/realstock/company/{}/hisdata/klc_kl.js?d={}" 28 | ) 29 | zh_sina_bond_hs_payload = { 30 | "page": "1", 31 | "num": "80", 32 | "sort": "symbol", 33 | "asc": "1", 34 | "node": "hs_z", 35 | "_s_r_a": "page", 36 | } 37 | 38 | # headers 39 | SHORT_HEADERS = { 40 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" 41 | } 42 | 43 | # quote 44 | MARKET_QUOTE_URL = "http://www.chinamoney.com.cn/ags/ms/cm-u-md-bond/CbMktMakQuot?flag=1&lang=cn&abdAssetEncdShrtDesc=&emaEntyEncdShrtDesc=" 45 | MARKET_QUOTE_PAYLOAD = { 46 | "flag": "1", 47 | "lang": "cn", 48 | "abdAssetEncdShrtDesc": "", 49 | "emaEntyEncdShrtDesc": "", 50 | } 51 | 52 | # trade 53 | MARKET_TRADE_URL = ( 54 | "http://www.chinamoney.com.cn/ags/ms/cm-u-md-bond/CbtPri?lang=cn&flag=1&bondName=" 55 | ) 56 | MARKET_TRADE_PAYLOAD = {"lang": "cn", "flag": "1", "bondName": ""} 57 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_zh_valuation_baidu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/5/29 23:00 5 | Desc: 百度股市通-A股-财务报表-估值数据 6 | https://gushitong.baidu.com/stock/ab-002044 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def stock_zh_valuation_baidu( 14 | symbol: str = "002044", indicator: str = "总市值", period: str = "近一年" 15 | ) -> pd.DataFrame: 16 | """ 17 | 百度股市通-A股-财务报表-估值数据 18 | https://gushitong.baidu.com/stock/ab-002044 19 | :param symbol: 股票代码 20 | :type symbol: str 21 | :param indicator: choice of {"总市值", "市盈率(TTM)", "市盈率(静)", "市净率", "市现率"} 22 | :type indicator: str 23 | :param period: choice of {"近一年", "近三年", "近五年", "近十年", "全部"} 24 | :type period: str 25 | :return: 估值数据 26 | :rtype: pandas.DataFrame 27 | """ 28 | url = "https://gushitong.baidu.com/opendata" 29 | params = { 30 | "openapi": "1", 31 | "dspName": "iphone", 32 | "tn": "tangram", 33 | "client": "app", 34 | "query": indicator, 35 | "code": symbol, 36 | "word": "", 37 | "resource_id": "51171", 38 | "market": "ab", 39 | "tag": indicator, 40 | "chart_select": period, 41 | "industry_select": "", 42 | "skip_industry": "1", 43 | "finClientType": "pc", 44 | } 45 | r = requests.get(url, params=params) 46 | data_json = r.json() 47 | temp_df = pd.DataFrame( 48 | data_json["Result"][0]["DisplayData"]["resultData"]["tplData"]["result"][ 49 | "chartInfo" 50 | ][0]["body"] 51 | ) 52 | temp_df.columns = ["date", "value"] 53 | temp_df["date"] = pd.to_datetime(temp_df["date"], errors="coerce").dt.date 54 | temp_df["value"] = pd.to_numeric(temp_df["value"], errors="coerce") 55 | return temp_df 56 | 57 | 58 | if __name__ == "__main__": 59 | stock_zh_valuation_baidu_df = stock_zh_valuation_baidu( 60 | symbol="002044", indicator="总市值", period="近一年" 61 | ) 62 | print(stock_zh_valuation_baidu_df) 63 | -------------------------------------------------------------------------------- /akshare/option/option_contract_info_ctp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/10/30 17:40 5 | Desc: openctp-合约信息接口 6 | http://openctp.cn/instruments.html 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def option_contract_info_ctp() -> pd.DataFrame: 14 | """ 15 | openctp-合约信息接口-期权合约 16 | http://openctp.cn/instruments.html 17 | :return: 期权合约信息 18 | :rtype: pandas.DataFrame 19 | """ 20 | url = "http://dict.openctp.cn/instruments?types=option" 21 | r = requests.get(url) 22 | data_json = r.json() 23 | temp_df = pd.DataFrame(data_json['data']) 24 | 25 | # 字段映射:英文字段名 -> 中文字段名 26 | column_mapping = { 27 | 'ExchangeID': '交易所ID', 28 | 'InstrumentID': '合约ID', 29 | 'InstrumentName': '合约名称', 30 | 'ProductClass': '商品类别', 31 | 'ProductID': '品种ID', 32 | 'VolumeMultiple': '合约乘数', 33 | 'PriceTick': '最小变动价位', 34 | 'LongMarginRatioByMoney': '做多保证金率', 35 | 'ShortMarginRatioByMoney': '做空保证金率', 36 | 'LongMarginRatioByVolume': '做多保证金/手', 37 | 'ShortMarginRatioByVolume': '做空保证金/手', 38 | 'OpenRatioByMoney': '开仓手续费率', 39 | 'OpenRatioByVolume': '开仓手续费/手', 40 | 'CloseRatioByMoney': '平仓手续费率', 41 | 'CloseRatioByVolume': '平仓手续费/手', 42 | 'CloseTodayRatioByMoney': '平今手续费率', 43 | 'CloseTodayRatioByVolume': '平今手续费/手', 44 | 'DeliveryYear': '交割年份', 45 | 'DeliveryMonth': '交割月份', 46 | 'OpenDate': '上市日期', 47 | 'ExpireDate': '最后交易日', 48 | 'DeliveryDate': '交割日', 49 | 'UnderlyingInstrID': '标的合约ID', 50 | 'UnderlyingMultiple': '标的合约乘数', 51 | 'OptionsType': '期权类型', 52 | 'StrikePrice': '行权价', 53 | 'InstLifePhase': '合约状态' 54 | } 55 | # 重命名列为中文 56 | temp_df = temp_df.rename(columns=column_mapping) 57 | return temp_df 58 | 59 | 60 | # 使用示例 61 | if __name__ == "__main__": 62 | option_contract_info_ctp_df = option_contract_info_ctp() 63 | print(option_contract_info_ctp_df) 64 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_market_legu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/4/25 20:22 5 | Desc: 乐咕乐股网-赚钱效应分析 6 | https://www.legulegu.com/stockdata/market-activity 7 | """ 8 | 9 | from io import StringIO 10 | 11 | import pandas as pd 12 | import requests 13 | from bs4 import BeautifulSoup 14 | 15 | from akshare.utils.cons import headers 16 | 17 | 18 | def stock_market_activity_legu() -> pd.DataFrame: 19 | """ 20 | 乐咕乐股网-赚钱效应分析 21 | https://www.legulegu.com/stockdata/market-activity 22 | :return: 乐咕乐股网-赚钱效应分析 23 | :rtype: pandas.DataFrame 24 | """ 25 | url = "https://legulegu.com/stockdata/market-activity" 26 | r = requests.get(url, headers=headers) 27 | temp_df = pd.read_html(StringIO(r.text))[0] 28 | temp_df_one = temp_df.iloc[:, :2] 29 | temp_df_one.columns = ["item", "value"] 30 | temp_df_two = temp_df.iloc[:, 2:4] 31 | temp_df_two.columns = ["item", "value"] 32 | temp_df_three = temp_df.iloc[:, 4:6] 33 | temp_df_three.columns = ["item", "value"] 34 | temp_df = pd.concat( 35 | objs=[temp_df_one, temp_df_two, temp_df_three], ignore_index=True 36 | ) 37 | temp_df.dropna(how="all", axis=0, inplace=True) 38 | soup = BeautifulSoup(r.text, features="lxml") 39 | item_str = soup.find(name="div", attrs={"class": "current-index"}).text 40 | inner_temp_df = pd.DataFrame([item.strip() for item in item_str.split(":")]).T 41 | inner_temp_df.columns = ["item", "value"] 42 | temp_df = pd.concat(objs=[temp_df, inner_temp_df], ignore_index=True) 43 | item_str = soup.find(name="div", attrs={"class": "current-data"}).text.strip() 44 | inner_temp_df = pd.DataFrame(["统计日期", item_str]).T 45 | inner_temp_df.columns = ["item", "value"] 46 | temp_df = pd.concat(objs=[temp_df, inner_temp_df], ignore_index=True) 47 | temp_df.reset_index(inplace=True, drop=True) 48 | return temp_df 49 | 50 | 51 | if __name__ == "__main__": 52 | stock_market_activity_legu_df = stock_market_activity_legu() 53 | print(stock_market_activity_legu_df) 54 | -------------------------------------------------------------------------------- /akshare/article/epu_index.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/1/20 22:00 5 | Desc: 经济政策不确定性指数 6 | https://www.policyuncertainty.com/index.html 7 | """ 8 | 9 | import pandas as pd 10 | 11 | 12 | def article_epu_index(symbol: str = "China") -> pd.DataFrame: 13 | """ 14 | 经济政策不确定性指数 15 | https://www.policyuncertainty.com/index.html 16 | :param symbol: 指定的国家名称, e.g. “China” 17 | :type symbol: str 18 | :return: 经济政策不确定性指数数据 19 | :rtype: pandas.DataFrame 20 | """ 21 | # 切勿修改 http 否则会读取不到 csv 文件 22 | if symbol == "China New": 23 | symbol = "SCMP_China" 24 | if symbol == "China": 25 | symbol = "SCMP_China" 26 | if symbol == "USA": 27 | symbol = "US" 28 | if symbol == "Hong Kong": 29 | symbol = "HK" 30 | epu_df = pd.read_excel( 31 | io=f"http://www.policyuncertainty.com/media/{symbol}_EPU_Data_Annotated.xlsx", 32 | engine="openpyxl", 33 | ) 34 | return epu_df 35 | if symbol in ["Germany", "France", "Italy"]: # 欧洲 36 | symbol = "Europe" 37 | if symbol == "South Korea": 38 | symbol = "Korea" 39 | if symbol == "Spain New": 40 | symbol = "Spain" 41 | if symbol in ["Ireland", "Chile", "Colombia", "Netherlands", "Singapore", "Sweden"]: 42 | epu_df = pd.read_excel( 43 | io=f"http://www.policyuncertainty.com/media/{symbol}_Policy_Uncertainty_Data.xlsx", 44 | engine="openpyxl", 45 | ) 46 | return epu_df 47 | if symbol == "Greece": 48 | epu_df = pd.read_excel( 49 | io=f"http://www.policyuncertainty.com/media/FKT_{symbol}_Policy_Uncertainty_Data.xlsx", 50 | engine="openpyxl", 51 | ) 52 | return epu_df 53 | url = f"http://www.policyuncertainty.com/media/{symbol}_Policy_Uncertainty_Data.csv" 54 | epu_df = pd.read_csv(url) 55 | return epu_df 56 | 57 | 58 | if __name__ == "__main__": 59 | article_epu_index_df = article_epu_index(symbol="China") 60 | print(article_epu_index_df) 61 | -------------------------------------------------------------------------------- /akshare/fortune/fortune_xincaifu_500.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2022/10/30 21:12 5 | Desc: 新财富 500 人富豪榜 6 | http://www.xcf.cn/zhuanti/ztzz/hdzt1/500frb/index.html 7 | """ 8 | 9 | import json 10 | 11 | import pandas as pd 12 | import requests 13 | 14 | 15 | def xincaifu_rank(year: str = "2022") -> pd.DataFrame: 16 | """ 17 | 新财富 500 人富豪榜 18 | http://www.xcf.cn/zhuanti/ztzz/hdzt1/500frb/index.html 19 | :param year: 具体排名年份, 数据从 2003-至今 20 | :type year: str 21 | :return: 排行榜 22 | :rtype: pandas.DataFrame 23 | """ 24 | url = "http://service.ikuyu.cn/XinCaiFu2/pcremoting/bdListAction.do" 25 | params = { 26 | "method": "getPage", 27 | "callback": "jsonpCallback", 28 | "sortBy": "", 29 | "order": "", 30 | "type": "4", 31 | "keyword": "", 32 | "pageSize": "1000", 33 | "year": year, 34 | "pageNo": "1", 35 | "from": "jsonp", 36 | } 37 | r = requests.get(url, params=params) 38 | data_text = r.text 39 | data_json = json.loads(data_text[data_text.find("{") : -1]) 40 | temp_df = pd.DataFrame(data_json["data"]["rows"]) 41 | temp_df.columns 42 | temp_df.rename( 43 | columns={ 44 | "assets": "财富", 45 | "year": "年份", 46 | "sex": "性别", 47 | "name": "姓名", 48 | "rank": "排名", 49 | "company": "主要公司", 50 | "industry": "相关行业", 51 | "id": "-", 52 | "addr": "公司总部", 53 | "rankLst": "-", 54 | "age": "年龄", 55 | }, 56 | inplace=True, 57 | ) 58 | temp_df = temp_df[ 59 | [ 60 | "排名", 61 | "财富", 62 | "姓名", 63 | "主要公司", 64 | "相关行业", 65 | "公司总部", 66 | "性别", 67 | "年龄", 68 | "年份", 69 | ] 70 | ] 71 | return temp_df 72 | 73 | 74 | if __name__ == "__main__": 75 | xincaifu_rank_df = xincaifu_rank(year="2022") 76 | print(xincaifu_rank_df) 77 | -------------------------------------------------------------------------------- /docs/indicator.md: -------------------------------------------------------------------------------- 1 | # [AKShare](https://github.com/akfamily/akshare) 指标计算 2 | 3 | ## 已实现波动率指标 4 | 5 | ### YZ 已实现波动率 6 | 7 | 接口: volatility_yz_rv 8 | 9 | 目标地址: https://github.com/hugogobato/Yang-Zhang-s-Realized-Volatility-Automated-Estimation-in-Python 10 | 11 | 描述: 波动率-已实现波动率-Yang-Zhang已实现波动率 12 | 13 | 限量: 单次返回日频率的已实现波动率数据 14 | 15 | 输入参数 16 | 17 | | 名称 | 类型 | 描述 | 18 | |------|------------------|---------------------------------------| 19 | | data | pandas.DataFrame | 包含日期和 OHLC(开高低收) 价格的 pandas.DataFrame | 20 | 21 | 输出参数 22 | 23 | | 名称 | 类型 | 描述 | 24 | |------|---------|-----| 25 | | date | object | - | 26 | | rv | float64 | - | 27 | 28 | 接口示例 29 | 30 | ```python 31 | import akshare as ak 32 | 33 | stock_df = ak.rv_from_stock_zh_a_hist_min_em( 34 | symbol="000001", 35 | start_date="2021-10-20 09:30:00", 36 | end_date="2024-11-01 15:00:00", 37 | period="5", 38 | adjust="" 39 | ) 40 | volatility_yz_rv_df = ak.volatility_yz_rv(data=stock_df) 41 | print(volatility_yz_rv_df) 42 | ``` 43 | 44 | 数据示例 45 | 46 | ``` 47 | date rv 48 | 0 2024-09-10 0.001955 49 | 1 2024-09-11 0.002207 50 | 2 2024-09-12 0.002113 51 | 3 2024-09-13 0.002216 52 | 4 2024-09-18 0.002039 53 | 5 2024-09-19 0.002631 54 | 6 2024-09-20 0.002043 55 | 7 2024-09-23 0.002116 56 | 8 2024-09-24 0.002374 57 | 9 2024-09-25 0.003624 58 | 10 2024-09-26 0.003392 59 | 11 2024-09-27 0.005944 60 | 12 2024-09-30 0.008488 61 | 13 2024-10-08 0.011529 62 | 14 2024-10-09 0.008031 63 | 15 2024-10-10 0.006964 64 | 16 2024-10-11 0.004970 65 | 17 2024-10-14 0.004435 66 | 18 2024-10-15 0.003706 67 | 19 2024-10-16 0.004293 68 | 20 2024-10-17 0.003534 69 | 21 2024-10-18 0.004322 70 | 22 2024-10-21 0.004417 71 | 23 2024-10-22 0.002922 72 | 24 2024-10-23 0.002124 73 | 25 2024-10-24 0.001814 74 | 26 2024-10-25 0.001605 75 | 27 2024-10-28 0.002125 76 | 28 2024-10-29 0.002045 77 | 29 2024-10-30 0.002428 78 | 30 2024-10-31 0.002718 79 | 31 2024-11-01 0.002932 80 | ``` 81 | -------------------------------------------------------------------------------- /akshare/nlp/nlp_interface.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/7/6 14:02 5 | Desc: ownthink-knowledge graph 6 | https://ownthink.com/ 7 | https://www.ownthink.com/docs/kg/ 8 | """ 9 | 10 | import pandas as pd 11 | import requests 12 | 13 | 14 | def nlp_ownthink(word: str = "人工智能", indicator: str = "entity") -> pd.DataFrame: 15 | """ 16 | Knowledge Graph interface for financial research 17 | https://ownthink.com/ 18 | :param word: word in chinese 19 | :type word: str 20 | :param indicator: entity or desc or avp or tag 21 | :type indicator: str 22 | :return: indicator data 23 | :rtype: list or dict or pandas.DataFrame 24 | """ 25 | url = "https://api.ownthink.com/kg/knowledge" 26 | payload = { 27 | "entity": word, 28 | } 29 | r = requests.post(url, data=payload) 30 | if not r.json()["data"]: 31 | print("Can not find the resource, please type into the correct word") 32 | return pd.DataFrame() 33 | if indicator == "entity": 34 | return r.json()["data"]["entity"] 35 | if indicator == "desc": 36 | return r.json()["data"]["desc"] 37 | if indicator == "avp": 38 | return pd.DataFrame(r.json()["data"]["avp"], columns=["字段", "值"]) 39 | if indicator == "tag": 40 | return r.json()["data"]["tag"] 41 | 42 | 43 | def nlp_answer(question: str = "人工智能") -> str: 44 | """ 45 | 智能问答 46 | https://ownthink.com/robot.html 47 | :param question: word in chinese 48 | :type question: str 49 | :return: indicator data 50 | :rtype: list or dict or pandas.DataFrame 51 | """ 52 | url = "https://api.ownthink.com/bot" 53 | params = {"spoken": question} 54 | r = requests.get(url, params=params) 55 | json_data = r.json() 56 | answer = json_data["data"]["info"]["text"] 57 | return answer 58 | 59 | 60 | if __name__ == "__main__": 61 | nlp_ownthink_df = nlp_ownthink(word="人工智能", indicator="entity") 62 | print(nlp_ownthink_df) 63 | 64 | nlp_answer_df = nlp_answer(question="姚明的身高") 65 | print(nlp_answer_df) 66 | -------------------------------------------------------------------------------- /akshare/stock/stock_gsrl_em.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2023/8/8 21:30 5 | Desc: 东方财富网-数据中心-股市日历 6 | https://data.eastmoney.com/gsrl/gsdt.html 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def stock_gsrl_gsdt_em(date: str = "20230808") -> pd.DataFrame: 14 | """ 15 | 东方财富网-数据中心-股市日历-公司动态 16 | https://data.eastmoney.com/gsrl/gsdt.html 17 | :param date: 交易日 18 | :type date: str 19 | :return: 公司动态 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = "https://datacenter-web.eastmoney.com/api/data/v1/get" 23 | params = { 24 | "sortColumns": "SECURITY_CODE", 25 | "sortTypes": "1", 26 | "pageSize": "5000", 27 | "pageNumber": "1", 28 | "columns": "SECURITY_CODE,SECUCODE,SECURITY_NAME_ABBR,EVENT_TYPE,EVENT_CONTENT,TRADE_DATE", 29 | "source": "WEB", 30 | "client": "WEB", 31 | "reportName": "RPT_ORGOP_ALL", 32 | "filter": f"""(TRADE_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')""", 33 | } 34 | r = requests.get(url, params=params) 35 | data_json = r.json() 36 | temp_df = pd.DataFrame(data_json["result"]["data"]) 37 | temp_df.reset_index(inplace=True) 38 | temp_df["index"] = temp_df["index"] + 1 39 | temp_df.rename( 40 | columns={ 41 | "index": "序号", 42 | "SECURITY_CODE": "代码", 43 | "SECUCODE": "-", 44 | "SECURITY_NAME_ABBR": "简称", 45 | "EVENT_TYPE": "事件类型", 46 | "EVENT_CONTENT": "具体事项", 47 | "TRADE_DATE": "交易日", 48 | }, 49 | inplace=True, 50 | ) 51 | 52 | temp_df = temp_df[ 53 | [ 54 | "序号", 55 | "代码", 56 | "简称", 57 | "事件类型", 58 | "具体事项", 59 | "交易日", 60 | ] 61 | ] 62 | temp_df["交易日"] = pd.to_datetime(temp_df["交易日"], errors="coerce").dt.date 63 | return temp_df 64 | 65 | 66 | if __name__ == "__main__": 67 | stock_gsrl_gsdt_em_df = stock_gsrl_gsdt_em(date="20230808") 68 | print(stock_gsrl_gsdt_em_df) 69 | -------------------------------------------------------------------------------- /akshare/option/option_current_sse.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2025/9/8 16:20 5 | Desc: 上海证券交易所-产品-股票期权-信息披露-当日合约 6 | http://www.sse.com.cn/assortment/options/disclo/preinfo/ 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def option_current_day_sse() -> pd.DataFrame: 14 | """ 15 | 上海证券交易所-产品-股票期权-信息披露-当日合约 16 | http://www.sse.com.cn/assortment/options/disclo/preinfo/ 17 | :return: 上交所期权当日合约 18 | :rtype: pandas.DataFrame 19 | """ 20 | url = "http://query.sse.com.cn/commonQuery.do" 21 | params = { 22 | "isPagination": "false", 23 | "expireDate": "", 24 | "securityId": "", 25 | "sqlId": "SSE_ZQPZ_YSP_GGQQZSXT_XXPL_DRHY_SEARCH_L", 26 | } 27 | headers = { 28 | "Accept": "*/*", 29 | "Accept-Encoding": "gzip, deflate", 30 | "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", 31 | "Cache-Control": "no-cache", 32 | "Connection": "keep-alive", 33 | "Host": "query.sse.com.cn", 34 | "Pragma": "no-cache", 35 | "Referer": "http://www.sse.com.cn/", 36 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " 37 | "Chrome/101.0.4951.67 Safari/537.36", 38 | } 39 | r = requests.get(url, params=params, headers=headers) 40 | data_json = r.json() 41 | temp_df = pd.DataFrame(data_json["result"]) 42 | dict_df = { 43 | "SECURITY_ID": "合约编码", 44 | "CONTRACT_ID": "合约交易代码", 45 | "CONTRACT_SYMBOL": "合约简称", 46 | "SECURITYNAMEBYID": "标的券名称及代码", 47 | "CALL_OR_PUT": "类型", 48 | "EXERCISE_PRICE": "行权价", 49 | "CONTRACT_UNIT": "合约单位", 50 | "END_DATE": "期权行权日", 51 | "DELIVERY_DATE": "行权交收日", 52 | "EXPIRE_DATE": "到期日", 53 | "START_DATE": "开始日期", 54 | } 55 | temp_df = temp_df[dict_df.keys()].rename(columns=dict_df) 56 | return temp_df 57 | 58 | 59 | if __name__ == "__main__": 60 | option_current_day_sse_df = option_current_day_sse() 61 | print(option_current_day_sse_df) 62 | -------------------------------------------------------------------------------- /akshare/futures_derivative/futures_contract_info_dce.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/8/18 11:00 5 | Desc: 大连商品交易所-业务/服务-业务参数-交易参数-合约信息查询 6 | http://www.dce.com.cn/dalianshangpin/ywfw/ywcs/jycs/hyxxcx/index.html 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def futures_contract_info_dce() -> pd.DataFrame: 14 | """ 15 | 大连商品交易所-数据中心-业务数据-交易参数-合约信息 16 | http://www.dce.com.cn/dce/channel/list/180.html 17 | :return: 交易参数汇总查询 18 | :rtype: pandas.DataFrame 19 | """ 20 | url = "http://www.dce.com.cn/dcereport/publicweb/tradepara/contractInfo" 21 | payload = { 22 | "lang": "zh", 23 | "tradeType": "1", 24 | "varietyId": "all", 25 | } 26 | r = requests.post(url, json=payload) 27 | data_json = r.json() 28 | temp_df = pd.DataFrame(data_json['data']) 29 | temp_df.rename(columns={ 30 | "contractId": "合约", 31 | "variety": "品种名称", 32 | "varietyOrder": "品种代码", 33 | "unit": "交易单位", 34 | "tick": "最小变动价位", 35 | "startTradeDate": "开始交易日", 36 | "endTradeDate": "最后交易日", 37 | "endDeliveryDate": "最后交割日", 38 | "tradeType": "", 39 | }, inplace=True) 40 | temp_df = temp_df[[ 41 | "品种名称", 42 | "合约", 43 | "交易单位", 44 | "最小变动价位", 45 | "开始交易日", 46 | "最后交易日", 47 | "最后交割日", 48 | ]] 49 | temp_df["交易单位"] = pd.to_numeric(temp_df["交易单位"], errors="coerce") 50 | temp_df["最小变动价位"] = pd.to_numeric(temp_df["最小变动价位"], errors="coerce") 51 | temp_df["开始交易日"] = pd.to_datetime( 52 | temp_df["开始交易日"], format="%Y%m%d", errors="coerce" 53 | ).dt.date 54 | temp_df["最后交易日"] = pd.to_datetime( 55 | temp_df["最后交易日"], format="%Y%m%d", errors="coerce" 56 | ).dt.date 57 | temp_df["最后交割日"] = pd.to_datetime( 58 | temp_df["最后交割日"], format="%Y%m%d", errors="coerce" 59 | ).dt.date 60 | return temp_df 61 | 62 | 63 | if __name__ == "__main__": 64 | futures_contract_info_dce_df = futures_contract_info_dce() 65 | print(futures_contract_info_dce_df) 66 | -------------------------------------------------------------------------------- /akshare/index/index_csindex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/8/4 14:00 5 | Desc: 中证指数网站-指数列表 6 | 网站:https://www.csindex.com.cn/#/indices/family/list?index_series=1 7 | """ 8 | import warnings 9 | from io import BytesIO 10 | 11 | import pandas as pd 12 | import requests 13 | 14 | 15 | def index_csindex_all() -> pd.DataFrame: 16 | """ 17 | 中证指数网站-指数列表 18 | https://www.csindex.com.cn/#/indices/family/list?index_series=1 19 | Note: 但是不知道数据更新时间 20 | :return: 最新指数的列表, 21 | :rtype: pandas.DataFrame 22 | """ 23 | warnings.filterwarnings("ignore", category=UserWarning, message="Workbook contains no default style") 24 | url = ( 25 | f"https://www.csindex.com.cn/csindex-home/exportExcel/indexAll/CH" 26 | ) 27 | 28 | headers = { 29 | "Content-Type": "application/json;charset=UTF-8", 30 | } 31 | playloads = { 32 | "sorter": { 33 | "sortField": "null", 34 | "sortOrder": None 35 | }, 36 | "pager": { 37 | "pageNum": 1, 38 | "pageSize": 10 39 | }, 40 | "indexFilter": { 41 | "ifCustomized": None, 42 | "ifTracked": None, 43 | "ifWeightCapped": None, 44 | "indexCompliance": None, 45 | "hotSpot": None, 46 | "indexClassify": None, 47 | "currency": None, 48 | "region": None, 49 | "indexSeries": ["1"], 50 | "undefined": None 51 | } 52 | } 53 | r = requests.post(url, json=playloads, headers=headers) 54 | 55 | temp_df = pd.read_excel(BytesIO(r.content)) 56 | temp_df["基日"] = pd.to_datetime( 57 | temp_df["基日"], format="%Y-%m-%d", errors="coerce" 58 | ).dt.date 59 | temp_df["发布时间"] = pd.to_datetime( 60 | temp_df["发布时间"], format="%Y-%m-%d", errors="coerce" 61 | ).dt.date 62 | temp_df["指数代码"] = temp_df["指数代码"].astype(str).str.zfill(6) 63 | return temp_df 64 | 65 | 66 | if __name__ == "__main__": 67 | index_csindex_all_df = index_csindex_all() 68 | print(index_csindex_all_df) 69 | -------------------------------------------------------------------------------- /akshare/stock/stock_hot_search_baidu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/6/16 18:19 5 | Desc: 百度股市通-热搜股票 6 | https://gushitong.baidu.com/hotlist?mainTab=hotSearch&market=all 7 | """ 8 | 9 | from datetime import datetime 10 | 11 | import pandas as pd 12 | import requests 13 | 14 | 15 | def stock_hot_search_baidu( 16 | symbol: str = "A股", date: str = "20250616", time: str = "今日" 17 | ): 18 | """ 19 | 百度股市通-热搜股票 20 | https://gushitong.baidu.com/hotlist?mainTab=hotSearch&market=all 21 | :param symbol: choice of {"全部", "A股", "港股", "美股"} 22 | :type symbol: str 23 | :param date: 日期 24 | :type date: str 25 | :param time: time="今日";choice of {"今日", "1小时"} 26 | :type time: str 27 | :return: 热搜股票 28 | :rtype: pandas.DataFrame 29 | """ 30 | hour_str = datetime.now().hour 31 | symbol_map = { 32 | "全市场": "all", 33 | "A股": "ab", 34 | "港股": "hk", 35 | "美股": "us", 36 | } 37 | url = "https://finance.pae.baidu.com/selfselect/listsugrecomm" 38 | params = { 39 | "bizType": "wisexmlnew", 40 | "dsp": "iphone", 41 | "product": "search", 42 | "style": "tablelist", 43 | "market": symbol_map[symbol], 44 | "type": time, 45 | "day": date, 46 | "hour": hour_str, 47 | "pn": "0", 48 | "rn": "12", 49 | "finClientType": "pc", 50 | } 51 | r = requests.get(url, params=params) 52 | data_json = r.json() 53 | temp_df = pd.DataFrame(data_json["Result"]['list']["body"]) 54 | temp_df.rename(columns={ 55 | 'name': "名称/代码", 56 | 'pxChangeRate': "涨跌幅", 57 | 'heat': "综合热度", 58 | 59 | }, inplace=True) 60 | temp_df = temp_df[[ 61 | "名称/代码", 62 | "涨跌幅", 63 | "综合热度", 64 | ]] 65 | temp_df['综合热度'] = pd.to_numeric(temp_df['综合热度'], errors='coerce') 66 | return temp_df 67 | 68 | 69 | if __name__ == "__main__": 70 | stock_hot_search_baidu_df = stock_hot_search_baidu( 71 | symbol="A股", date="20250616", time="今日" 72 | ) 73 | print(stock_hot_search_baidu_df) 74 | -------------------------------------------------------------------------------- /akshare/currency/currency_safe.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2024/4/29 17:00 5 | Desc: 人民币汇率中间价 6 | https://www.safe.gov.cn/safe/rmbhlzjj/index.html 7 | """ 8 | 9 | import re 10 | from datetime import datetime 11 | from io import StringIO 12 | 13 | import pandas as pd 14 | import requests 15 | from bs4 import BeautifulSoup 16 | 17 | 18 | def currency_boc_safe() -> pd.DataFrame: 19 | """ 20 | 人民币汇率中间价 21 | https://www.safe.gov.cn/safe/rmbhlzjj/index.html 22 | :return: 人民币汇率中间价 23 | :rtype: pandas.DataFrame 24 | """ 25 | url = "https://www.safe.gov.cn/safe/2020/1218/17833.html" 26 | r = requests.get(url) 27 | r.encoding = "utf8" 28 | soup = BeautifulSoup(r.text, features="lxml") 29 | content = soup.find(name="a", string=re.compile("人民币汇率"))["href"] 30 | url = f"https://www.safe.gov.cn{content}" 31 | temp_df = pd.read_excel(url) 32 | temp_df.sort_values(by=["日期"], inplace=True) 33 | temp_df.reset_index(inplace=True, drop=True) 34 | start_date = ( 35 | (pd.Timestamp(temp_df["日期"].tolist()[-1]) + pd.Timedelta(days=1)) 36 | .isoformat() 37 | .split("T")[0] 38 | ) 39 | end_date = datetime.now().isoformat().split("T")[0] 40 | url = "https://www.safe.gov.cn/AppStructured/hlw/RMBQuery.do" 41 | payload = { 42 | "startDate": start_date, 43 | "endDate": end_date, 44 | "queryYN": "true", 45 | } 46 | r = requests.post(url, data=payload) 47 | current_temp_df = pd.read_html(StringIO(r.text))[-1] 48 | current_temp_df.sort_values(by=["日期"], inplace=True) 49 | current_temp_df.reset_index(inplace=True, drop=True) 50 | big_df = pd.concat(objs=[temp_df, current_temp_df], ignore_index=True) 51 | column_name_list = big_df.columns[1:] 52 | for item in column_name_list: 53 | big_df[item] = pd.to_numeric(big_df[item], errors="coerce") 54 | big_df["日期"] = pd.to_datetime(big_df["日期"], errors="coerce").dt.date 55 | return big_df 56 | 57 | 58 | if __name__ == "__main__": 59 | currency_boc_safe_df = currency_boc_safe() 60 | print(currency_boc_safe_df) 61 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_hk_valuation_baidu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/11/21 18:26 5 | Desc: 百度股市通-港股-财务报表-估值数据 6 | https://gushitong.baidu.com/stock/hk-06969 7 | """ 8 | 9 | import http.client 10 | import json 11 | import urllib 12 | 13 | import pandas as pd 14 | 15 | 16 | def stock_hk_valuation_baidu( 17 | symbol: str = "06969", indicator: str = "总市值", period: str = "近一年" 18 | ) -> pd.DataFrame: 19 | """ 20 | 百度股市通-港股-财务报表-估值数据 21 | https://gushitong.baidu.com/stock/hk-06969 22 | :param symbol: 股票代码 23 | :type symbol: str 24 | :param indicator: choice of {"总市值", "市盈率(TTM)", "市盈率(静)", "市净率", "市现率"} 25 | :type indicator: str 26 | :param period: choice of {"近一年", "近三年", "全部"} 27 | :type period: str 28 | :return: 估值数据 29 | :rtype: pandas.DataFrame 30 | """ 31 | params = { 32 | "openapi": "1", 33 | "dspName": "iphone", 34 | "tn": "tangram", 35 | "client": "app", 36 | "query": indicator, 37 | "code": symbol, 38 | "word": "", 39 | "resource_id": "51171", 40 | "market": "hk", 41 | "tag": indicator, 42 | "chart_select": period, 43 | "industry_select": "", 44 | "skip_industry": "1", 45 | "finClientType": "pc", 46 | } 47 | conn = http.client.HTTPSConnection("gushitong.baidu.com") 48 | conn.request(method="GET", url=f"/opendata?{urllib.parse.urlencode(params)}") 49 | r = conn.getresponse() 50 | data_json = json.loads(r.read()) 51 | temp_df = pd.DataFrame( 52 | data_json["Result"][0]["DisplayData"]["resultData"]["tplData"]["result"][ 53 | "chartInfo" 54 | ][0]["body"] 55 | ) 56 | temp_df.columns = ["date", "value"] 57 | temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date 58 | temp_df["value"] = pd.to_numeric(temp_df["value"]) 59 | return temp_df 60 | 61 | 62 | if __name__ == "__main__": 63 | stock_hk_valuation_baidu_df = stock_hk_valuation_baidu( 64 | symbol="06969", indicator="总市值", period="近三年" 65 | ) 66 | print(stock_hk_valuation_baidu_df) 67 | -------------------------------------------------------------------------------- /akshare/bond/bond_nafmii.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/3/16 9:00 5 | Desc:中国银行间市场交易商协会(https://www.nafmii.org.cn/) 6 | 孔雀开屏(http://zhuce.nafmii.org.cn/fans/publicQuery/manager)的债券基本信息数据 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def bond_debt_nafmii(page: str = "1") -> pd.DataFrame: 14 | """ 15 | 中国银行间市场交易商协会-非金融企业债务融资工具注册信息系统 16 | http://zhuce.nafmii.org.cn/fans/publicQuery/manager 17 | :param page: 输入数字页码 18 | :type page: int 19 | :return: 指定 sector 和 indicator 的数据 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = "http://zhuce.nafmii.org.cn/fans/publicQuery/releFileProjDataGrid" 23 | payload = { 24 | "regFileName": "", 25 | "itemType": "", 26 | "startTime": "", 27 | "endTime": "", 28 | "entityName": "", 29 | "leadManager": "", 30 | "regPrdtType": "", 31 | "page": page, 32 | "rows": 50, 33 | } 34 | payload.update({"page": page}) 35 | r = requests.post(url, data=payload) 36 | data_json = r.json() # 数据类型为 json 格式 37 | temp_df = pd.DataFrame(data_json["rows"]) 38 | temp_df.rename( 39 | columns={ 40 | "firstIssueAmount": "金额", 41 | "isReg": "注册或备案", 42 | "regFileName": "债券名称", 43 | "regNoticeNo": "注册通知书文号", 44 | "regPrdtType": "品种", 45 | "releaseTime": "更新日期", 46 | "projPhase": "项目状态", 47 | }, 48 | inplace=True, 49 | ) 50 | if "注册通知书文号" not in temp_df.columns: 51 | temp_df["注册通知书文号"] = pd.NA 52 | temp_df = temp_df[ 53 | [ 54 | "债券名称", 55 | "品种", 56 | "注册或备案", 57 | "金额", 58 | "注册通知书文号", 59 | "更新日期", 60 | "项目状态", 61 | ] 62 | ] 63 | temp_df["金额"] = pd.to_numeric(temp_df["金额"], errors="coerce") 64 | temp_df["更新日期"] = pd.to_datetime(temp_df["更新日期"], errors="coerce").dt.date 65 | return temp_df 66 | 67 | 68 | if __name__ == "__main__": 69 | bond_debt_nafmii_df = bond_debt_nafmii(page="1") 70 | print(bond_debt_nafmii_df) 71 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_buffett_index_lg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/9/20 18:05 5 | Desc: 乐估乐股-底部研究-巴菲特指标 6 | https://legulegu.com/stockdata/marketcap-gdp 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | from akshare.stock_feature.stock_a_indicator import get_token_lg, get_cookie_csrf 13 | 14 | 15 | def stock_buffett_index_lg() -> pd.DataFrame: 16 | """ 17 | 乐估乐股-底部研究-巴菲特指标 18 | https://legulegu.com/stockdata/marketcap-gdp 19 | :return: 巴菲特指标 20 | :rtype: pandas.DataFrame 21 | """ 22 | token = get_token_lg() 23 | url = "https://legulegu.com/api/stockdata/marketcap-gdp/get-marketcap-gdp" 24 | params = {"token": token} 25 | r = requests.get( 26 | url, 27 | params=params, 28 | **get_cookie_csrf(url="https://legulegu.com/stockdata/marketcap-gdp"), 29 | ) 30 | data_json = r.json() 31 | temp_df = pd.DataFrame(data_json["data"]) 32 | temp_df.rename( 33 | columns={ 34 | "marketCap": "总市值", 35 | "gdp": "GDP", 36 | "close": "收盘价", 37 | "date": "日期", 38 | "quantileInAllHistory": "总历史分位数", 39 | "quantileInRecent10Years": "近十年分位数", 40 | }, 41 | inplace=True, 42 | ) 43 | temp_df = temp_df[ 44 | [ 45 | "日期", 46 | "收盘价", 47 | "总市值", 48 | "GDP", 49 | "近十年分位数", 50 | "总历史分位数", 51 | ] 52 | ] 53 | temp_df["日期"] = pd.to_datetime(temp_df["日期"], unit="ms") 54 | temp_df["日期"] = pd.to_datetime(temp_df["日期"] + pd.Timedelta(hours=8)).dt.date 55 | temp_df["收盘价"] = pd.to_numeric(temp_df["收盘价"], errors="coerce") 56 | temp_df["总市值"] = pd.to_numeric(temp_df["总市值"], errors="coerce") 57 | temp_df["GDP"] = pd.to_numeric(temp_df["GDP"], errors="coerce") 58 | temp_df["近十年分位数"] = pd.to_numeric(temp_df["近十年分位数"], errors="coerce") 59 | temp_df["总历史分位数"] = pd.to_numeric(temp_df["总历史分位数"], errors="coerce") 60 | return temp_df 61 | 62 | 63 | if __name__ == "__main__": 64 | stock_buffett_index_lg_df = stock_buffett_index_lg() 65 | print(stock_buffett_index_lg_df) 66 | -------------------------------------------------------------------------------- /akshare/stock/stock_hk_fhpx_ths.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/1/16 15:30 5 | Desc: 同花顺-港股-分红派息 6 | https://stockpage.10jqka.com.cn/HK0700/bonus/ 7 | """ 8 | 9 | from io import StringIO 10 | 11 | import pandas as pd 12 | import requests 13 | 14 | 15 | def stock_hk_fhpx_detail_ths(symbol: str = "0700") -> pd.DataFrame: 16 | """ 17 | 同花顺-港股-分红派息 18 | https://stockpage.10jqka.com.cn/HK0700/bonus/ 19 | :param symbol: 港股代码 20 | :type symbol: str 21 | :return: 分红派息 22 | :rtype: pandas.DataFrame 23 | """ 24 | url = f"https://basic.10jqka.com.cn/176/HK{symbol}/bonus.html" 25 | headers = { 26 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " 27 | "AppleWebKit/537.36 (KHTML, like Gecko) " 28 | "Chrome/89.0.4389.90 Safari/537.36", 29 | } 30 | r = requests.get(url, headers=headers) 31 | r.encoding = "utf-8" 32 | temp_df = pd.read_html(StringIO(r.text))[0] 33 | temp_df.columns = [ 34 | "公告日期", 35 | "方案", 36 | "除净日", 37 | "派息日", 38 | "过户日期起止日-起始", 39 | "过户日期起止日-截止", 40 | "类型", 41 | "进度", 42 | "以股代息", 43 | ] 44 | # 剔除异常格式,由以股代息产生的异常 45 | temp_df.dropna(subset=["派息日", "除净日"], inplace=True, ignore_index=True) 46 | temp_df["公告日期"] = pd.to_datetime( 47 | temp_df["公告日期"], format="%Y-%m-%d", errors="coerce" 48 | ).dt.date 49 | temp_df["除净日"] = pd.to_datetime( 50 | temp_df["除净日"], format="%Y-%m-%d", errors="coerce" 51 | ).dt.date 52 | temp_df["派息日"] = pd.to_datetime( 53 | temp_df["派息日"], format="%Y-%m-%d", errors="coerce" 54 | ).dt.date 55 | temp_df["过户日期起止日-起始"] = pd.to_datetime( 56 | temp_df["过户日期起止日-起始"], format="%Y-%m-%d", errors="coerce" 57 | ).dt.date 58 | temp_df["过户日期起止日-截止"] = pd.to_datetime( 59 | temp_df["过户日期起止日-截止"], format="%Y-%m-%d", errors="coerce" 60 | ).dt.date 61 | temp_df.sort_values(["公告日期"], inplace=True, ignore_index=True) 62 | return temp_df 63 | 64 | 65 | if __name__ == "__main__": 66 | stock_hk_fhpx_detail_ths_df = stock_hk_fhpx_detail_ths(symbol="0700") 67 | print(stock_hk_fhpx_detail_ths_df) 68 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_a_high_low.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2023/9/10 15:32 5 | Desc: 乐咕乐股-创新高、新低的股票数量 6 | https://www.legulegu.com/stockdata/high-low-statistics 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | from akshare.utils.cons import headers 13 | 14 | 15 | def stock_a_high_low_statistics(symbol: str = "all") -> pd.DataFrame: 16 | """ 17 | 乐咕乐股-创新高、新低的股票数量 18 | https://www.legulegu.com/stockdata/high-low-statistics 19 | :param symbol: choice of {"all", "sz50", "hs300", "zz500"} 20 | :type symbol: str 21 | :return: 创新高、新低的股票数量 22 | :rtype: pandas.DataFrame 23 | """ 24 | url = f"https://www.legulegu.com/stockdata/member-ship/get-high-low-statistics/{symbol}" 25 | r = requests.get(url, headers=headers) 26 | data_json = r.json() 27 | temp_df = pd.DataFrame(data_json) 28 | del temp_df["indexCode"] 29 | temp_df["date"] = pd.to_datetime(temp_df["date"], unit="ms").dt.date 30 | temp_df["close"] = pd.to_numeric(temp_df["close"], errors="coerce") 31 | temp_df["high20"] = pd.to_numeric(temp_df["high20"], errors="coerce") 32 | temp_df["low20"] = pd.to_numeric(temp_df["low20"], errors="coerce") 33 | temp_df["high60"] = pd.to_numeric(temp_df["high60"], errors="coerce") 34 | temp_df["low60"] = pd.to_numeric(temp_df["low60"], errors="coerce") 35 | temp_df["high120"] = pd.to_numeric(temp_df["high120"], errors="coerce") 36 | temp_df["low120"] = pd.to_numeric(temp_df["low120"], errors="coerce") 37 | temp_df.sort_values(by=["date"], inplace=True, ignore_index=True) 38 | return temp_df 39 | 40 | 41 | if __name__ == "__main__": 42 | stock_a_high_low_statistics_df = stock_a_high_low_statistics(symbol="all") 43 | print(stock_a_high_low_statistics_df) 44 | 45 | stock_a_high_low_statistics_df = stock_a_high_low_statistics(symbol="sz50") 46 | print(stock_a_high_low_statistics_df) 47 | 48 | stock_a_high_low_statistics_df = stock_a_high_low_statistics(symbol="hs300") 49 | print(stock_a_high_low_statistics_df) 50 | 51 | stock_a_high_low_statistics_df = stock_a_high_low_statistics(symbol="zz500") 52 | print(stock_a_high_low_statistics_df) 53 | -------------------------------------------------------------------------------- /akshare/index/index_eri.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2023/6/19 18:16 5 | Desc: 浙江省排污权交易指数 6 | https://zs.zjpwq.net/ 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def index_eri(symbol: str = "月度") -> pd.DataFrame: 14 | """ 15 | 浙江省排污权交易指数 16 | https://zs.zjpwq.net 17 | :param symbol: choice of {"月度", "季度"} 18 | :type symbol: str 19 | :return: 浙江省排污权交易指数 20 | :rtype: pandas.DataFrame 21 | """ 22 | symbol_map = { 23 | "月度": "MONTH", 24 | "季度": "QUARTER", 25 | } 26 | url = "https://zs.zjpwq.net/pwq-index-webapi/indexData" 27 | params = { 28 | "cycle": symbol_map[symbol], 29 | "regionId": "1", 30 | "structId": "1", 31 | "pageSize": "5000", 32 | "indexId": "1", 33 | "orderBy": "stage.publishTime", 34 | } 35 | headers = { 36 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" 37 | } 38 | r = requests.get(url, params=params, headers=headers) 39 | data_json = r.json() 40 | temp_df = pd.DataFrame(data_json["data"]) 41 | index_value = temp_df["indexValue"].tolist() 42 | index_time = [item["stage"]["publishTime"] for item in data_json["data"]] 43 | big_df = pd.DataFrame([index_time, index_value], index=["日期", "交易指数"]).T 44 | url = "https://zs.zjpwq.net/pwq-index-webapi/dataStatistics" 45 | r = requests.get(url, params=params, headers=headers) 46 | data_json = r.json() 47 | temp_df = pd.DataFrame(data_json["data"]) 48 | big_df["成交量"] = temp_df["totalQuantity"].tolist() 49 | big_df["成交额"] = temp_df["totalCost"].tolist() 50 | big_df["日期"] = pd.to_datetime(big_df["日期"], errors="coerce").dt.date 51 | big_df["交易指数"] = pd.to_numeric(big_df["交易指数"], errors="coerce") 52 | big_df["成交量"] = pd.to_numeric(big_df["成交量"], errors="coerce") 53 | big_df["成交额"] = pd.to_numeric(big_df["成交额"], errors="coerce") 54 | return big_df 55 | 56 | 57 | if __name__ == "__main__": 58 | index_eri_df = index_eri(symbol="月度") 59 | print(index_eri_df) 60 | 61 | index_eri_df = index_eri(symbol="季度") 62 | print(index_eri_df) 63 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_fhps_ths.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/5/13 10:30 5 | Desc: 同花顺-分红情况 6 | https://basic.10jqka.com.cn/new/603444/bonus.html 7 | """ 8 | 9 | from io import StringIO 10 | 11 | import pandas as pd 12 | import requests 13 | 14 | 15 | def stock_fhps_detail_ths(symbol: str = "603444") -> pd.DataFrame: 16 | """ 17 | 同花顺-分红情况 18 | https://basic.10jqka.com.cn/new/603444/bonus.html 19 | :param symbol: 股票代码 20 | :type symbol: str 21 | :return: 分红融资 22 | :rtype: pandas.DataFrame 23 | """ 24 | url = f"https://basic.10jqka.com.cn/new/{symbol}/bonus.html" 25 | headers = { 26 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " 27 | "AppleWebKit/537.36 (KHTML, like Gecko) " 28 | "Chrome/89.0.4389.90 Safari/537.36", 29 | } 30 | r = requests.get(url, headers=headers) 31 | r.encoding = "gbk" 32 | temp_df = pd.read_html(StringIO(r.text))[0] 33 | temp_df["董事会日期"] = pd.to_datetime( 34 | temp_df["董事会日期"], format="%Y-%m-%d", errors="coerce" 35 | ).dt.date 36 | temp_df["股东大会预案公告日期"] = pd.to_datetime( 37 | temp_df["股东大会预案公告日期"], format="%Y-%m-%d", errors="coerce" 38 | ).dt.date 39 | temp_df["实施公告日"] = pd.to_datetime( 40 | temp_df["实施公告日"], format="%Y-%m-%d", errors="coerce" 41 | ).dt.date 42 | if "A股股权登记日" in temp_df.columns: 43 | temp_df["A股股权登记日"] = pd.to_datetime( 44 | temp_df["A股股权登记日"], format="%Y-%m-%d", errors="coerce" 45 | ).dt.date 46 | temp_df["A股除权除息日"] = pd.to_datetime( 47 | temp_df["A股除权除息日"], format="%Y-%m-%d", errors="coerce" 48 | ).dt.date 49 | else: 50 | temp_df["B股股权登记日"] = pd.to_datetime( 51 | temp_df["B股股权登记日"], format="%Y-%m-%d", errors="coerce" 52 | ).dt.date 53 | temp_df["B股除权除息日"] = pd.to_datetime( 54 | temp_df["B股除权除息日"], format="%Y-%m-%d", errors="coerce" 55 | ).dt.date 56 | temp_df.sort_values(by=["董事会日期"], ignore_index=True, inplace=True) 57 | return temp_df 58 | 59 | 60 | if __name__ == "__main__": 61 | stock_fhps_detail_ths_df = stock_fhps_detail_ths(symbol="200596") 62 | print(stock_fhps_detail_ths_df) 63 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.ruff] 2 | # Exclude a variety of commonly ignored directories. 3 | exclude = [ 4 | "akshare/__init__.py", # 初始化导入库文件,必须包含本文件 5 | ".bzr", 6 | ".direnv", 7 | ".eggs", 8 | ".git", 9 | ".git-rewrite", 10 | ".hg", 11 | ".ipynb_checkpoints", 12 | ".mypy_cache", 13 | ".nox", 14 | ".pants.d", 15 | ".pyenv", 16 | ".pytest_cache", 17 | ".pytype", 18 | ".ruff_cache", 19 | ".svn", 20 | ".tox", 21 | ".venv", 22 | ".vscode", 23 | "__pypackages__", 24 | "_build", 25 | "buck-out", 26 | "build", 27 | "dist", 28 | "node_modules", 29 | "site-packages", 30 | "venv", 31 | ] 32 | 33 | # Same as Black. 34 | line-length = 88 35 | indent-width = 4 36 | 37 | # Assume Python 3.12 38 | target-version = "py312" 39 | 40 | [tool.ruff.lint] 41 | # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. 42 | # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or 43 | # McCabe complexity (`C901`) by default. 44 | select = ["E4", "E7", "E9", "F"] 45 | ignore = [] 46 | 47 | # Allow fix for all enabled rules (when `--fix`) is provided. 48 | fixable = ["ALL"] 49 | unfixable = [] 50 | 51 | # Allow unused variables when underscore-prefixed. 52 | dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" 53 | 54 | [tool.ruff.format] 55 | # Like Black, use double quotes for strings. 56 | quote-style = "double" 57 | 58 | # Like Black, indent with spaces, rather than tabs. 59 | indent-style = "space" 60 | 61 | # Like Black, respect magic trailing commas. 62 | skip-magic-trailing-comma = false 63 | 64 | # Like Black, automatically detect the appropriate line ending. 65 | line-ending = "auto" 66 | 67 | # Enable auto-formatting of code examples in docstrings. Markdown, 68 | # reStructuredText code/literal blocks and doctests are all supported. 69 | # 70 | # This is currently disabled by default, but it is planned for this 71 | # to be opt-out in the future. 72 | docstring-code-format = false 73 | 74 | # Set the line length limit used when formatting code snippets in 75 | # docstrings. 76 | # 77 | # This only has an effect when the `docstring-code-format` setting is 78 | # enabled. 79 | docstring-code-line-length = "dynamic" 80 | -------------------------------------------------------------------------------- /akshare/cost/cost_living.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/8/28 15:20 5 | Desc: 世界各大城市生活成本数据 6 | https://expatistan.com/cost-of-living/index 7 | """ 8 | 9 | from io import StringIO 10 | 11 | import pandas as pd 12 | import requests 13 | from bs4 import BeautifulSoup 14 | 15 | 16 | def _get_region() -> dict: 17 | """ 18 | 获取主要板块, 一般不调用 19 | :return: 主要板块 20 | :rtype: dict 21 | """ 22 | url = "https://www.expatistan.com/cost-of-living/index" 23 | r = requests.get(url) 24 | soup = BeautifulSoup(r.text, features="lxml") 25 | half_url_list = [ 26 | item["href"] 27 | for item in soup.find(name="ul", attrs={"class": "regions"}).find_all("a") 28 | ] 29 | name_list = [ 30 | item["href"].split("/")[-1] 31 | for item in soup.find(name="ul", attrs={"class": "regions"}).find_all("a") 32 | ] 33 | name_url_dict = dict(zip(name_list, half_url_list)) 34 | name_url_dict["world"] = "/cost-of-living/index" 35 | return name_url_dict 36 | 37 | 38 | def cost_living(symbol: str = "world") -> pd.DataFrame: 39 | """ 40 | 国家或地区生活成本数据 41 | https://expatistan.com/cost-of-living/index 42 | :param symbol: choice of {"europe", "north-america", "latin-america", 43 | "asia", "middle-east", "africa", "oceania", "world"} 44 | :type symbol: str 45 | :return: 国家或地区生活成本数据 46 | :rtype: pandas.DataFrame 47 | """ 48 | name_url_map = { 49 | "europe": "/cost-of-living/index/europe", 50 | "north-america": "/cost-of-living/index/north-america", 51 | "latin-america": "/cost-of-living/index/latin-america", 52 | "asia": "/cost-of-living/index/asia", 53 | "middle-east": "/cost-of-living/index/middle-east", 54 | "africa": "/cost-of-living/index/africa", 55 | "oceania": "/cost-of-living/index/oceania", 56 | "world": "/cost-of-living/index", 57 | } 58 | url = f"https://www.expatistan.com{name_url_map[symbol]}" 59 | r = requests.get(url) 60 | temp_df = pd.read_html(StringIO(r.text))[0] 61 | temp_df.columns = ["rank", "city", "index"] 62 | return temp_df 63 | 64 | 65 | if __name__ == "__main__": 66 | cost_living_df = cost_living(symbol="world") 67 | print(cost_living_df) 68 | -------------------------------------------------------------------------------- /akshare/fund/fund_init_em.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2023/11/7 18:30 5 | Desc: 基金数据-新发基金-新成立基金 6 | https://fund.eastmoney.com/data/xinfound.html 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | from akshare.utils import demjson 13 | 14 | 15 | def fund_new_found_em() -> pd.DataFrame: 16 | """ 17 | 基金数据-新发基金-新成立基金 18 | https://fund.eastmoney.com/data/xinfound.html 19 | :return: 新成立基金 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = "https://fund.eastmoney.com/data/FundNewIssue.aspx" 23 | params = { 24 | "t": "xcln", 25 | "sort": "jzrgq,desc", 26 | "y": "", 27 | "page": "1,50000", 28 | "isbuy": "1", 29 | "v": "0.4069919776543214", 30 | } 31 | r = requests.get(url, params=params) 32 | data_text = r.text 33 | data_json = demjson.decode(data_text.strip("var newfunddata=")) 34 | temp_df = pd.DataFrame(data_json["datas"]) 35 | temp_df.columns = [ 36 | "基金代码", 37 | "基金简称", 38 | "发行公司", 39 | "_", 40 | "基金类型", 41 | "募集份额", 42 | "成立日期", 43 | "成立来涨幅", 44 | "基金经理", 45 | "申购状态", 46 | "集中认购期", 47 | "_", 48 | "_", 49 | "_", 50 | "_", 51 | "_", 52 | "_", 53 | "_", 54 | "优惠费率", 55 | ] 56 | temp_df = temp_df[ 57 | [ 58 | "基金代码", 59 | "基金简称", 60 | "发行公司", 61 | "基金类型", 62 | "集中认购期", 63 | "募集份额", 64 | "成立日期", 65 | "成立来涨幅", 66 | "基金经理", 67 | "申购状态", 68 | "优惠费率", 69 | ] 70 | ] 71 | temp_df["募集份额"] = pd.to_numeric(temp_df["募集份额"], errors="coerce") 72 | temp_df["成立日期"] = pd.to_datetime(temp_df["成立日期"], errors="coerce").dt.date 73 | temp_df["成立来涨幅"] = pd.to_numeric( 74 | temp_df["成立来涨幅"].str.replace(",", ""), errors="coerce" 75 | ) 76 | temp_df["优惠费率"] = temp_df["优惠费率"].str.strip("%") 77 | temp_df["优惠费率"] = pd.to_numeric(temp_df["优惠费率"], errors="coerce") 78 | return temp_df 79 | 80 | 81 | if __name__ == "__main__": 82 | fund_new_found_em_df = fund_new_found_em() 83 | print(fund_new_found_em_df) 84 | -------------------------------------------------------------------------------- /akshare/futures/futures_foreign.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/3/5 18:00 5 | Desc: 外盘期货-历史行情数据-日频率 6 | https://finance.sina.com.cn/money/future/hf.html 7 | """ 8 | 9 | from datetime import datetime 10 | from io import StringIO 11 | 12 | import pandas as pd 13 | import requests 14 | 15 | from akshare.futures.futures_hq_sina import ( 16 | futures_foreign_commodity_subscribe_exchange_symbol, 17 | ) 18 | 19 | 20 | def futures_foreign_hist(symbol: str = "ZSD") -> pd.DataFrame: 21 | """ 22 | 外盘期货-历史行情数据-日频率 23 | https://finance.sina.com.cn/money/future/hf.html 24 | :param symbol: 外盘期货代码, 可以通过 ak.futures_foreign_commodity_subscribe_exchange_symbol() 来获取所有品种代码 25 | :type symbol: str 26 | :return: 历史行情数据-日频率 27 | :rtype: pandas.DataFrame 28 | """ 29 | today = f"{datetime.today().year}_{datetime.today().month}_{datetime.today().day}" 30 | url = ( 31 | f"https://stock2.finance.sina.com.cn/futures/api/jsonp.php/var%20_S{today}=/" 32 | f"GlobalFuturesService.getGlobalFuturesDailyKLine" 33 | ) 34 | params = { 35 | "symbol": symbol, 36 | "_": today, 37 | "source": "web", 38 | } 39 | r = requests.get(url, params=params) 40 | data_text = r.text 41 | data_df = pd.read_json(StringIO(data_text[data_text.find("[") : -2])) 42 | return data_df 43 | 44 | 45 | def futures_foreign_detail(symbol: str = "ZSD") -> pd.DataFrame: 46 | """ 47 | foreign futures contract detail data 48 | :param symbol: futures symbol, you can get it from hf_subscribe_exchange_symbol function 49 | :type symbol: str 50 | :return: contract detail 51 | :rtype: pandas.DataFrame 52 | """ 53 | url = f"https://finance.sina.com.cn/futures/quotes/{symbol}.shtml" 54 | r = requests.get(url) 55 | r.encoding = "gbk" 56 | data_text = r.text 57 | data_df = pd.read_html(StringIO(data_text))[6] 58 | return data_df 59 | 60 | 61 | if __name__ == "__main__": 62 | futures_foreign_hist_df = futures_foreign_hist(symbol="ZSD") 63 | print(futures_foreign_hist_df) 64 | 65 | subscribes = futures_foreign_commodity_subscribe_exchange_symbol() 66 | 67 | for item in subscribes: 68 | futures_foreign_detail_df = futures_foreign_detail(symbol=item) 69 | print(futures_foreign_detail_df) 70 | -------------------------------------------------------------------------------- /akshare/utils/func.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python 2 | """ 3 | Date: 2025/3/10 18:00 4 | Desc: 通用帮助函数 5 | """ 6 | 7 | import math 8 | from typing import List, Dict 9 | 10 | import pandas as pd 11 | import requests 12 | 13 | from akshare.utils.tqdm import get_tqdm 14 | 15 | 16 | def fetch_paginated_data(url: str, base_params: Dict, timeout: int = 15): 17 | """ 18 | 东方财富-分页获取数据并合并结果 19 | https://quote.eastmoney.com/f1.html?newcode=0.000001 20 | :param url: 股票代码 21 | :type url: str 22 | :param base_params: 基础请求参数 23 | :type base_params: dict 24 | :param timeout: 请求超时时间 25 | :type timeout: str 26 | :return: 合并后的数据 27 | :rtype: pandas.DataFrame 28 | """ 29 | # 复制参数以避免修改原始参数 30 | params = base_params.copy() 31 | # 获取第一页数据,用于确定分页信息 32 | r = requests.get(url, params=params, timeout=timeout) 33 | data_json = r.json() 34 | # 计算分页信息 35 | per_page_num = len(data_json["data"]["diff"]) 36 | total_page = math.ceil(data_json["data"]["total"] / per_page_num) 37 | # 存储所有页面数据 38 | temp_list = [] 39 | # 添加第一页数据 40 | temp_list.append(pd.DataFrame(data_json["data"]["diff"])) 41 | # 获取进度条 42 | tqdm = get_tqdm() 43 | # 获取剩余页面数据 44 | for page in tqdm(range(2, total_page + 1), leave=False): 45 | params.update({"pn": page}) 46 | r = requests.get(url, params=params, timeout=timeout) 47 | data_json = r.json() 48 | inner_temp_df = pd.DataFrame(data_json["data"]["diff"]) 49 | temp_list.append(inner_temp_df) 50 | # 合并所有数据 51 | temp_df = pd.concat(temp_list, ignore_index=True) 52 | temp_df["f3"] = pd.to_numeric(temp_df["f3"], errors="coerce") 53 | temp_df.sort_values(by=["f3"], ascending=False, inplace=True, ignore_index=True) 54 | temp_df.reset_index(inplace=True) 55 | temp_df["index"] = temp_df["index"].astype(int) + 1 56 | return temp_df 57 | 58 | 59 | def set_df_columns(df: pd.DataFrame, cols: List[str]) -> pd.DataFrame: 60 | """ 61 | 设置 pandas.DataFrame 为空的情况 62 | :param df: 需要设置命名的数据框 63 | :type df: pandas.DataFrame 64 | :param cols: 字段的列表 65 | :type cols: list 66 | :return: 重新设置后的数据 67 | :rtype: pandas.DataFrame 68 | """ 69 | if df.shape == (0, 0): 70 | return pd.DataFrame(data=[], columns=cols) 71 | else: 72 | df.columns = cols 73 | return df 74 | -------------------------------------------------------------------------------- /akshare/crypto/crypto_hold.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2023/8/31 23:00 5 | Desc: 金十数据-比特币持仓报告 6 | https://datacenter.jin10.com/dc_report?name=bitcoint 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def crypto_bitcoin_hold_report(): 14 | """ 15 | 金十数据-比特币持仓报告 16 | https://datacenter.jin10.com/dc_report?name=bitcoint 17 | :return: 比特币持仓报告 18 | :rtype: pandas.DataFrame 19 | """ 20 | url = "https://datacenter-api.jin10.com/bitcoin_treasuries/list" 21 | headers = { 22 | "X-App-Id": "lnFP5lxse24wPgtY", 23 | "X-Version": "1.0.0", 24 | } 25 | r = requests.get(url, headers=headers) 26 | data_json = r.json() 27 | temp_df = pd.DataFrame(data_json["data"]["values"]) 28 | temp_df.columns = [ 29 | "代码", 30 | "公司名称-英文", 31 | "国家/地区", 32 | "市值", 33 | "比特币占市值比重", 34 | "持仓成本", 35 | "持仓占比", 36 | "持仓量", 37 | "当日持仓市值", 38 | "查询日期", 39 | "公告链接", 40 | "_", 41 | "分类", 42 | "倍数", 43 | "_", 44 | "公司名称-中文", 45 | ] 46 | temp_df = temp_df[ 47 | [ 48 | "代码", 49 | "公司名称-英文", 50 | "公司名称-中文", 51 | "国家/地区", 52 | "市值", 53 | "比特币占市值比重", 54 | "持仓成本", 55 | "持仓占比", 56 | "持仓量", 57 | "当日持仓市值", 58 | "查询日期", 59 | "公告链接", 60 | "分类", 61 | "倍数", 62 | ] 63 | ] 64 | temp_df["市值"] = pd.to_numeric(temp_df["市值"], errors="coerce") 65 | temp_df["比特币占市值比重"] = pd.to_numeric( 66 | temp_df["比特币占市值比重"], errors="coerce" 67 | ) 68 | temp_df["持仓成本"] = pd.to_numeric(temp_df["持仓成本"], errors="coerce") 69 | temp_df["持仓占比"] = pd.to_numeric(temp_df["持仓占比"], errors="coerce") 70 | temp_df["持仓量"] = pd.to_numeric(temp_df["持仓量"], errors="coerce") 71 | temp_df["当日持仓市值"] = pd.to_numeric(temp_df["当日持仓市值"], errors="coerce") 72 | temp_df["倍数"] = pd.to_numeric(temp_df["倍数"], errors="coerce") 73 | temp_df["查询日期"] = pd.to_datetime(temp_df["查询日期"], errors="coerce").dt.date 74 | return temp_df 75 | 76 | 77 | if __name__ == "__main__": 78 | crypto_bitcoin_hold_report_df = crypto_bitcoin_hold_report() 79 | print(crypto_bitcoin_hold_report_df) 80 | -------------------------------------------------------------------------------- /akshare/futures_derivative/futures_contract_info_gfex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/2/28 16:00 5 | Desc: 广州期货交易所-业务/服务-合约信息 6 | http://www.gfex.com.cn/gfex/hyxx/ywcs.shtml 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def futures_contract_info_gfex() -> pd.DataFrame: 14 | """ 15 | 广州期货交易所-业务/服务-合约信息 16 | http://www.gfex.com.cn/gfex/hyxx/ywcs.shtml 17 | :return: 交易参数汇总查询 18 | :rtype: pandas.DataFrame 19 | """ 20 | url = "http://www.gfex.com.cn/u/interfacesWebTtQueryContractInfo/loadList" 21 | params = { 22 | "variety": "", 23 | "trade_type": "0", 24 | } 25 | headers = { 26 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36" 27 | } 28 | r = requests.post(url, params=params, headers=headers) 29 | data_json = r.json() 30 | temp_df = pd.DataFrame(data_json["data"]) 31 | temp_df.rename( 32 | columns={ 33 | "tradeType": "-", 34 | "variety": "品种", 35 | "varietyOrder": "-", 36 | "contractId": "合约代码", 37 | "unit": "交易单位", 38 | "tick": "最小变动单位", 39 | "startTradeDate": "开始交易日", 40 | "endTradeDate": "最后交易日", 41 | "endDeliveryDate0": "最后交割日", 42 | }, 43 | inplace=True, 44 | ) 45 | temp_df["交易单位"] = pd.to_numeric(temp_df["交易单位"], errors="coerce") 46 | temp_df["最小变动单位"] = pd.to_numeric(temp_df["最小变动单位"], errors="coerce") 47 | temp_df["开始交易日"] = pd.to_datetime( 48 | temp_df["开始交易日"], format="%Y%m%d", errors="coerce" 49 | ).dt.date 50 | temp_df["最后交易日"] = pd.to_datetime( 51 | temp_df["最后交易日"], format="%Y%m%d", errors="coerce" 52 | ).dt.date 53 | temp_df["最后交割日"] = pd.to_datetime( 54 | temp_df["最后交割日"], format="%Y%m%d", errors="coerce" 55 | ).dt.date 56 | temp_df = temp_df[ 57 | [ 58 | "品种", 59 | "合约代码", 60 | "交易单位", 61 | "最小变动单位", 62 | "开始交易日", 63 | "最后交易日", 64 | "最后交割日", 65 | ] 66 | ] 67 | return temp_df 68 | 69 | 70 | if __name__ == "__main__": 71 | futures_contract_info_gfex_df = futures_contract_info_gfex() 72 | print(futures_contract_info_gfex_df) 73 | -------------------------------------------------------------------------------- /akshare/stock/stock_zh_a_tick_tx.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2023/10/27 22:08 5 | Desc: 腾讯-股票-实时行情-成交明细 6 | 成交明细-每个交易日 16:00 提供当日数据 7 | 港股报价延时 15 分钟 8 | """ 9 | 10 | import warnings 11 | 12 | import pandas as pd 13 | import requests 14 | 15 | 16 | def stock_zh_a_tick_tx_js(symbol: str = "sz000001") -> pd.DataFrame: 17 | """ 18 | 腾讯财经-历史分笔数据 19 | https://gu.qq.com/sz300494/gp/detail 20 | :param symbol: 股票代码 21 | :type symbol: str 22 | :return: 历史分笔数据 23 | :rtype: pandas.DataFrame 24 | """ 25 | big_df = pd.DataFrame() 26 | page = 0 27 | warnings.warn("正在下载数据,请稍等") 28 | while True: 29 | try: 30 | url = "http://stock.gtimg.cn/data/index.php" 31 | params = { 32 | "appn": "detail", 33 | "action": "data", 34 | "c": symbol, 35 | "p": page, 36 | } 37 | r = requests.get(url, params=params) 38 | text_data = r.text 39 | temp_df = ( 40 | pd.DataFrame(eval(text_data[text_data.find("[") :])[1].split("|")) 41 | .iloc[:, 0] 42 | .str.split("/", expand=True) 43 | ) 44 | page += 1 45 | big_df = pd.concat([big_df, temp_df], ignore_index=True) 46 | except: # noqa: E722 47 | break 48 | if not big_df.empty: 49 | big_df = big_df.iloc[:, 1:].copy() 50 | big_df.columns = [ 51 | "成交时间", 52 | "成交价格", 53 | "价格变动", 54 | "成交量", 55 | "成交金额", 56 | "性质", 57 | ] 58 | big_df.reset_index(drop=True, inplace=True) 59 | property_map = { 60 | "S": "卖盘", 61 | "B": "买盘", 62 | "M": "中性盘", 63 | } 64 | big_df["性质"] = big_df["性质"].map(property_map) 65 | big_df = big_df.astype( 66 | { 67 | "成交时间": str, 68 | "成交价格": float, 69 | "价格变动": float, 70 | "成交量": int, 71 | "成交金额": int, 72 | "性质": str, 73 | } 74 | ) 75 | return big_df 76 | 77 | 78 | if __name__ == "__main__": 79 | stock_zh_a_tick_tx_js_df = stock_zh_a_tick_tx_js(symbol="sz000001") 80 | print(stock_zh_a_tick_tx_js_df) 81 | -------------------------------------------------------------------------------- /akshare/economic/marco_cnbs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2023/8/14 11:10 5 | Desc: 国家金融与发展实验室-中国宏观杠杆率数据 6 | http://114.115.232.154:8080/ 7 | """ 8 | 9 | import pandas as pd 10 | 11 | 12 | def macro_cnbs() -> pd.DataFrame: 13 | """ 14 | 国家金融与发展实验室-中国宏观杠杆率数据 15 | http://114.115.232.154:8080/ 16 | :return: 中国宏观杠杆率数据 17 | :rtype: pandas.DataFrame 18 | """ 19 | url = "http://114.115.232.154:8080/handler/download.ashx" 20 | temp_df = pd.read_excel( 21 | url, sheet_name="Data", header=0, skiprows=1, engine="openpyxl" 22 | ) 23 | 24 | temp_df["Period"] = pd.to_datetime(temp_df["Period"]).dt.strftime("%Y-%m") 25 | temp_df.dropna(axis=1, inplace=True) 26 | 27 | temp_df.rename( 28 | columns={ 29 | "Period": "年份", 30 | "Household": "居民部门", 31 | "Non-financial corporations": "非金融企业部门", 32 | "Central government ": "中央政府", 33 | "Local government": "地方政府", 34 | "General government": "政府部门", 35 | "Non financial sector": "实体经济部门", 36 | "Financial sector(asset side)": "金融部门资产方", 37 | "Financial sector(liability side)": "金融部门负债方", 38 | }, 39 | inplace=True, 40 | ) 41 | 42 | column_order = [ 43 | "年份", 44 | "居民部门", 45 | "非金融企业部门", 46 | "政府部门", 47 | "中央政府", 48 | "地方政府", 49 | "实体经济部门", 50 | "金融部门资产方", 51 | "金融部门负债方", 52 | ] 53 | temp_df = temp_df.reindex(columns=column_order) 54 | temp_df["居民部门"] = pd.to_numeric(temp_df["居民部门"], errors="coerce") 55 | temp_df["非金融企业部门"] = pd.to_numeric( 56 | temp_df["非金融企业部门"], errors="coerce" 57 | ) 58 | temp_df["政府部门"] = pd.to_numeric(temp_df["政府部门"], errors="coerce") 59 | temp_df["中央政府"] = pd.to_numeric(temp_df["中央政府"], errors="coerce") 60 | temp_df["地方政府"] = pd.to_numeric(temp_df["地方政府"], errors="coerce") 61 | temp_df["实体经济部门"] = pd.to_numeric(temp_df["实体经济部门"], errors="coerce") 62 | temp_df["金融部门资产方"] = pd.to_numeric( 63 | temp_df["金融部门资产方"], errors="coerce" 64 | ) 65 | temp_df["金融部门负债方"] = pd.to_numeric( 66 | temp_df["金融部门负债方"], errors="coerce" 67 | ) 68 | return temp_df 69 | 70 | 71 | if __name__ == "__main__": 72 | macro_cnbs_df = macro_cnbs() 73 | print(macro_cnbs_df) 74 | -------------------------------------------------------------------------------- /akshare/pro/client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2019/11/10 22:52 5 | Desc: 数据接口源代码 6 | """ 7 | 8 | from functools import partial 9 | from urllib import parse 10 | 11 | import pandas as pd 12 | import requests 13 | 14 | 15 | class DataApi: 16 | __token = "" 17 | __http_url = "https://api.qhkch.com" 18 | 19 | def __init__(self, token, timeout=10): 20 | """ 21 | 初始化函数 22 | :param token: API接口TOKEN,用于用户认证 23 | :type token: str 24 | :param timeout: 超时设置 25 | :type timeout: int 26 | """ 27 | self.__token = token 28 | self.__timeout = timeout 29 | 30 | def query(self, api_name, fields="", **kwargs): 31 | """ 32 | :param api_name: 需要调取的接口 33 | :type api_name: str 34 | :param fields: 想要获取的字段 35 | :type fields: str 36 | :param kwargs: 指定需要输入的参数 37 | :type kwargs: 键值对 38 | :return: 指定的数据 39 | :rtype: dict or pandas.DataFrame 40 | """ 41 | headers = { 42 | "X-Token": self.__token, 43 | } 44 | url = parse.urljoin(self.__http_url, "/".join([api_name, *kwargs.values()])) 45 | res = requests.get(url, headers=headers, timeout=self.__timeout) 46 | if res.status_code != 200: 47 | raise Exception("连接异常, 请检查您的Token是否过期和输入的参数是否正确") 48 | data_json = res.json() 49 | if fields == "": 50 | try: 51 | return pd.DataFrame(data_json) 52 | except ValueError: 53 | result_df = pd.DataFrame.from_dict( 54 | data_json, orient="index", columns=[api_name] 55 | ) 56 | return result_df 57 | else: # 此处增加处理 58 | if api_name == "variety_all_positions": 59 | big_df = pd.DataFrame() 60 | for item in data_json[fields].keys(): 61 | temp_df = pd.DataFrame(data_json[fields][item]) 62 | temp_df["code"] = item 63 | big_df = big_df.append(temp_df, ignore_index=True) 64 | big_df.reset_index(inplace=True, drop=True) 65 | return big_df 66 | else: 67 | return pd.DataFrame(data_json[fields]) 68 | 69 | def __getattr__(self, name): 70 | return partial(self.query, name) 71 | 72 | 73 | if __name__ == "__main__": 74 | pass 75 | -------------------------------------------------------------------------------- /docs/introduction.md: -------------------------------------------------------------------------------- 1 | # [AKShare](https://github.com/akfamily/akshare) 项目概览 2 | 3 | 本次发布 [AKTools](https://github.com/akfamily/aktools) 作为 AKShare 的 HTTP API 版本,突破 Python 语言的限制,欢迎各位小伙伴试用并提出更好的意见或建议! 4 | 点击 [AKTools](https://github.com/akfamily/aktools) 查看使用指南。 5 | 6 | **风险提示**:[AKShare](https://github.com/akfamily/akshare) 开源财经数据接口库所采集的数据皆来自公开的数据源,不涉及任何个人隐私数据和非公开数据。 7 | 同时本项目提供的数据接口及相关数据仅用于学术研究,任何个人、机构及团体使用本项目的数据接口及相关数据请注意商业风险。 8 | 9 | 1. 本文档更新时间:**2025-12-20**; 10 | 2. 如有 [AKShare](https://github.com/akfamily/akshare) 库、文档及数据的相关问题,请在 [AKShare Issues](https://github.com/akfamily/akshare/issues) 中提 Issues; 11 | 12 | ## 引用 13 | 14 | 如果您想在文章或者项目中引用 [AKShare](https://github.com/akfamily/akshare/),请使用如下 **bibtex** 格式: 15 | 16 | ``` 17 | @misc{akshare2022, 18 | author = {Albert King}, 19 | title = {AKShare}, 20 | year = {2022}, 21 | publisher = {GitHub}, 22 | journal = {GitHub repository}, 23 | howpublished = {\url{https://github.com/akfamily/akshare}}, 24 | } 25 | ``` 26 | 27 | ## [AKShare](https://github.com/akfamily/akshare) 的介绍 28 | 29 | 首先要特别感谢 [FuShare](https://github.com/LowinLi/fushare) 和 [TuShare](https://github.com/waditu/tushare) 在代码和项目开发上对本项目提供的借鉴和学习的机会! 30 | 31 | [AKShare](https://github.com/akfamily/akshare) 是基于 Python 的财经数据接口库,目的是实现对股票、期货、期权、基金、外汇、债券、指数、加密货币等金融产品的基本面数据、实时和历史行情数据、衍生数据从数据采集、数据清洗到数据落地的一套工具,主要用于学术研究目的。 32 | 33 | [AKShare](https://github.com/akfamily/akshare) 的特点是获取的是相对权威的财经数据网站公布的原始数据,通过利用原始数据进行各数据源之间的交叉验证,进而再加工,从而得出科学的结论。 34 | 35 | **[AKShare](https://github.com/akfamily/akshare) 后续会基于学术论文和研究报告来添加更多数据接口和衍生指标,并提供相应的计算代码,敬请关注。** 36 | 37 | ## [AKShare](https://github.com/akfamily/akshare) 的特色 38 | 39 | [AKShare](https://github.com/akfamily/akshare) 主要改进如下: 40 | 41 | 1. 代码语法符合 [PEP8](https://peps.python.org/pep-0008/) 规范,数据接口的命名统一; 42 | 2. 最佳支持 Python 3.12 及其以上版本; 43 | 3. 提供最佳的文档支持,每个数据接口均提供详细的说明和示例,只需要复制粘贴就可以下载数据; 44 | 4. 持续维护由于目标网页变化而导致的部分数据接口运行异常问题; 45 | 5. 持续更新财经数据接口,同时优化源代码; 46 | 6. 提供完善的接口文档,提高 [AKShare](https://github.com/akfamily/akshare) 的易用性; 47 | 7. 对于非 Python 用户,提供 HTTP API 接口工具 [AKTools](https://aktools.akfamily.xyz/)。 48 | 49 | ## [AKShare](https://github.com/akfamily/akshare) 的初衷 50 | 51 | [AKShare](https://github.com/akfamily/akshare) 主要是用于财经研究,解决在财经研究中数据获取的问题。目前的版本主要是基于 Python 52 | 语言,通过调用相关的数据接口来获取数据到本地。原理上,就是在用户本地运行 Python 53 | 代码,实时从网络采集数据到本地,便利与数据分析。由于网络数据采集需要维护的接口众多,且经常由于目标网站变换网页格式需要维护及更新相关接口,所以用户在使用本项目的过程中需要经常更新本项目到最新版本。同时也需要关注项目文档的更新,因为最新的使用方式和接口变更都会第一时间更新到文档中。 54 | -------------------------------------------------------------------------------- /akshare/futures_derivative/futures_contract_info_ine.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/11/30 19:00 5 | Desc: 上海国际能源交易中心-业务指南-交易参数汇总(期货) 6 | https://www.ine.cn/bourseService/summary/?name=currinstrumentprop 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def futures_contract_info_ine(date: str = "20241129") -> pd.DataFrame: 14 | """ 15 | 上海国际能源交易中心-业务指南-交易参数汇总(期货) 16 | https://www.ine.cn/bourseService/summary/?name=currinstrumentprop 17 | :param date: 查询日期; 交易日 18 | :type date: str 19 | :return: 交易参数汇总查询 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = f"https://www.ine.cn/data/busiparamdata/future/ContractBaseInfo{date}.dat" 23 | params = {"rnd": "0.8312696798757147"} 24 | headers = { 25 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " 26 | "Chrome/119.0.0.0 Safari/537.36" 27 | } 28 | r = requests.get(url, params=params, headers=headers) 29 | data_json = r.json() 30 | temp_df = pd.DataFrame(data_json["ContractBaseInfo"]) 31 | temp_df.rename( 32 | columns={ 33 | "BASISPRICE": "挂牌基准价", 34 | "ENDDELIVDATE": "最后交割日", 35 | "EXPIREDATE": "到期日", 36 | "INSTRUMENTID": "合约代码", 37 | "OPENDATE": "上市日", 38 | "STARTDELIVDATE": "开始交割日", 39 | "TRADINGDAY": "交易日", 40 | }, 41 | inplace=True, 42 | ) 43 | temp_df = temp_df[ 44 | [ 45 | "合约代码", 46 | "上市日", 47 | "到期日", 48 | "开始交割日", 49 | "最后交割日", 50 | "挂牌基准价", 51 | "交易日", 52 | ] 53 | ] 54 | temp_df["上市日"] = pd.to_datetime(temp_df["上市日"], errors="coerce").dt.date 55 | temp_df["到期日"] = pd.to_datetime(temp_df["到期日"], errors="coerce").dt.date 56 | temp_df["开始交割日"] = pd.to_datetime( 57 | temp_df["开始交割日"], errors="coerce" 58 | ).dt.date 59 | temp_df["最后交割日"] = pd.to_datetime( 60 | temp_df["最后交割日"], errors="coerce" 61 | ).dt.date 62 | temp_df["交易日"] = pd.to_datetime(temp_df["交易日"], errors="coerce").dt.date 63 | temp_df["挂牌基准价"] = pd.to_numeric(temp_df["挂牌基准价"], errors="coerce") 64 | return temp_df 65 | 66 | 67 | if __name__ == "__main__": 68 | futures_contract_info_ine_df = futures_contract_info_ine(date="20241129") 69 | print(futures_contract_info_ine_df) 70 | -------------------------------------------------------------------------------- /akshare/option/option_margin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/6/16 18:00 5 | Desc: 唯爱期货-期权保证金 6 | https://www.iweiai.com/qihuo/yuanyou 7 | """ 8 | import requests 9 | import pandas as pd 10 | from io import StringIO 11 | 12 | from bs4 import BeautifulSoup 13 | from functools import lru_cache 14 | 15 | 16 | @lru_cache() 17 | def option_margin_symbol() -> pd.DataFrame: 18 | """ 19 | 获取商品期权品种代码和名称 20 | :return: 商品期权品种代码和名称 21 | :rtype: pandas.DataFrame 22 | """ 23 | url = "https://www.iweiai.com/qiquan/yuanyou" 24 | r = requests.get(url) 25 | soup = BeautifulSoup(r.content, features="lxml") 26 | symbol_text = [item.get_text() for item in soup.find_all("a") if "qiquan" in item['href']] 27 | symbol_url = [item['href'] for item in soup.find_all("a") if "qiquan" in item['href']] 28 | symbol_df = pd.DataFrame([symbol_text, symbol_url]).T 29 | symbol_df.columns = ["symbol", "url"] 30 | return symbol_df 31 | 32 | 33 | def option_margin(symbol: str = "原油期权") -> pd.DataFrame: 34 | """ 35 | 获取商品期权保证金 36 | :param symbol: 商品期权品种名称, 如 "原油期权",可以通过 ak.option_margin_symbol() 获取所有商品期权品种代码和名称 37 | :type symbol: str 38 | :return: 商品期权保证金 39 | :rtype: pandas.DataFrame 40 | """ 41 | option_margin_symbol_df = option_margin_symbol() 42 | url = option_margin_symbol_df[option_margin_symbol_df['symbol'] == symbol]['url'].values[0] 43 | r = requests.get(url) 44 | soup = BeautifulSoup(r.content, features="lxml") 45 | updated_time = soup.find_all("small")[0].get_text().strip("最近更新:") 46 | temp_df = pd.read_html(StringIO(r.text))[0] 47 | temp_df['更新时间'] = updated_time 48 | 49 | temp_df['结算价'] = pd.to_numeric(temp_df['结算价'], errors='coerce') 50 | temp_df['交易乘数'] = pd.to_numeric(temp_df['交易乘数'], errors='coerce') 51 | temp_df['买方权利金'] = pd.to_numeric(temp_df['买方权利金'], errors='coerce') 52 | temp_df['卖方保证金'] = pd.to_numeric(temp_df['卖方保证金'], errors='coerce') 53 | temp_df['开仓手续费'] = pd.to_numeric(temp_df['开仓手续费'], errors='coerce') 54 | temp_df['平今手续费'] = pd.to_numeric(temp_df['平今手续费'], errors='coerce') 55 | temp_df['平昨手续费'] = pd.to_numeric(temp_df['平昨手续费'], errors='coerce') 56 | temp_df['手续费(开+平今)'] = pd.to_numeric(temp_df['手续费(开+平今)'], errors='coerce') 57 | return temp_df 58 | 59 | 60 | if __name__ == '__main__': 61 | option_margin_df = option_margin(symbol="原油期权") 62 | print(option_margin_df) 63 | -------------------------------------------------------------------------------- /akshare/futures_derivative/futures_contract_info_shfe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/5/13 17:45 5 | Desc: 上海期货交易所-交易所服务-业务数据-交易参数汇总查询 6 | https://tsite.shfe.com.cn/bourseService/businessdata/summaryinquiry/ 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def futures_contract_info_shfe(date: str = "20240513") -> pd.DataFrame: 14 | """ 15 | 上海期货交易所-交易所服务-业务数据-交易参数汇总查询 16 | https://tsite.shfe.com.cn/bourseService/businessdata/summaryinquiry/ 17 | :param date: 查询日期; 交易日 18 | :type date: str 19 | :return: 交易参数汇总查询 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = f"https://www.shfe.com.cn/data/busiparamdata/future/ContractBaseInfo{date}.dat" 23 | headers = { 24 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " 25 | "Chrome/119.0.0.0 Safari/537.36" 26 | } 27 | r = requests.get(url, headers=headers) 28 | data_json = r.json() 29 | temp_df = pd.DataFrame(data_json["ContractBaseInfo"]) 30 | temp_df.rename( 31 | columns={ 32 | "BASISPRICE": "挂牌基准价", 33 | "ENDDELIVDATE": "最后交割日", 34 | "EXPIREDATE": "到期日", 35 | "INSTRUMENTID": "合约代码", 36 | "OPENDATE": "上市日", 37 | "STARTDELIVDATE": "开始交割日", 38 | "TRADINGDAY": "交易日", 39 | }, 40 | inplace=True, 41 | ) 42 | temp_df = temp_df[ 43 | [ 44 | "合约代码", 45 | "上市日", 46 | "到期日", 47 | "开始交割日", 48 | "最后交割日", 49 | "挂牌基准价", 50 | "交易日", 51 | ] 52 | ] 53 | temp_df["上市日"] = pd.to_datetime(temp_df["上市日"], errors="coerce").dt.date 54 | temp_df["到期日"] = pd.to_datetime(temp_df["到期日"], errors="coerce").dt.date 55 | temp_df["开始交割日"] = pd.to_datetime( 56 | temp_df["开始交割日"], errors="coerce" 57 | ).dt.date 58 | temp_df["最后交割日"] = pd.to_datetime( 59 | temp_df["最后交割日"], errors="coerce" 60 | ).dt.date 61 | temp_df["交易日"] = pd.to_datetime(temp_df["交易日"], errors="coerce").dt.date 62 | temp_df["挂牌基准价"] = pd.to_numeric(temp_df["挂牌基准价"], errors="coerce") 63 | temp_df["更新时间"] = data_json['update_date'] 64 | return temp_df 65 | 66 | 67 | if __name__ == "__main__": 68 | futures_contract_info_shfe_df = futures_contract_info_shfe(date="20250611") 69 | print(futures_contract_info_shfe_df) 70 | -------------------------------------------------------------------------------- /akshare/stock/stock_intraday_em.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/3/10 18:00 5 | Desc: 东财财富-日内分时数据 6 | https://quote.eastmoney.com/f1.html?newcode=0.000001 7 | """ 8 | 9 | import json 10 | 11 | import pandas as pd 12 | import requests 13 | 14 | 15 | def __event_stream(url, params): 16 | # 使用 stream=True 参数来启用流式请求 17 | response = requests.get(url, params=params, stream=True) 18 | event_data = "" 19 | 20 | for line in response.iter_lines(): 21 | # 过滤掉保持连接的空行 22 | if line: 23 | event_data += line.decode() + "\n" 24 | elif event_data: 25 | yield event_data 26 | event_data = "" 27 | 28 | 29 | def stock_intraday_em(symbol: str = "000001") -> pd.DataFrame: 30 | """ 31 | 东方财富-分时数据 32 | https://quote.eastmoney.com/f1.html?newcode=0.000001 33 | :param symbol: 股票代码 34 | :type symbol: str 35 | :return: 分时数据 36 | :rtype: pandas.DataFrame 37 | """ 38 | market_code = 1 if symbol.startswith("6") else 0 39 | url = "https://70.push2.eastmoney.com/api/qt/stock/details/sse" 40 | params = { 41 | "fields1": "f1,f2,f3,f4", 42 | "fields2": "f51,f52,f53,f54,f55", 43 | "mpi": "2000", 44 | "ut": "bd1d9ddb04089700cf9c27f6f7426281", 45 | "fltt": "2", 46 | "pos": "-0", 47 | "secid": f"{market_code}.{symbol}", 48 | "wbp2u": "|0|0|0|web", 49 | } 50 | 51 | big_df = pd.DataFrame() # 创建一个空的 DataFrame 52 | 53 | for event in __event_stream(url, params): 54 | # 从每个事件的数据行中删除 "data: ",然后解析 JSON 55 | event_json = json.loads(event.replace("data: ", "")) 56 | # 将 JSON 数据转换为 DataFrame,然后添加到主 DataFrame 中 57 | temp_df = pd.DataFrame( 58 | [item.split(",") for item in event_json["data"]["details"]] 59 | ) 60 | big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True) 61 | break 62 | 63 | big_df.columns = ["时间", "成交价", "手数", "-", "买卖盘性质"] 64 | big_df["买卖盘性质"] = big_df["买卖盘性质"].map( 65 | {"2": "买盘", "1": "卖盘", "4": "中性盘"} 66 | ) 67 | big_df = big_df[["时间", "成交价", "手数", "买卖盘性质"]] 68 | big_df["成交价"] = pd.to_numeric(big_df["成交价"], errors="coerce") 69 | big_df["手数"] = pd.to_numeric(big_df["手数"], errors="coerce") 70 | return big_df 71 | 72 | 73 | if __name__ == "__main__": 74 | stock_intraday_em_df = stock_intraday_em(symbol="000001") 75 | print(stock_intraday_em_df) 76 | -------------------------------------------------------------------------------- /akshare/article/fred_md.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2020/4/10 19:58 5 | Desc: Economic Research from Federal Reserve Bank of St. Louis 6 | https://research.stlouisfed.org/econ/mccracken/fred-databases/ 7 | FRED-MD and FRED-QD are large macroeconomic databases designed for the empirical analysis of “big data.” The datasets of monthly and quarterly observations mimic the coverage of datasets already used in the literature, but they add three appealing features. They are updated in real-time through the FRED database. They are publicly accessible, facilitating the replication of empirical work. And they relieve the researcher of the task of incorporating data changes and revisions (a task accomplished by the data desk at the Federal Reserve Bank of St. Louis). 8 | """ 9 | 10 | import pandas as pd 11 | 12 | 13 | def fred_md(date: str = "2020-01") -> pd.DataFrame: 14 | """ 15 | The accompanying paper shows that factors extracted from the FRED-MD dataset share the same predictive content as those based on the various vintages of the so-called Stock-Watson data. In addition, it suggests that diffusion indexes constructed as the partial sum of the factor estimates can potentially be useful for the study of business cycle chronology. 16 | :param date: e.g., "2020-03"; from "2015-01" to now 17 | :type date: str 18 | :return: Monthly Data 19 | :rtype: pandas.DataFrame 20 | """ 21 | url = ( 22 | f"https://s3.amazonaws.com/files.fred.stlouisfed.org/fred-md/monthly/{date}.csv" 23 | ) 24 | temp_df = pd.read_csv(url) 25 | return temp_df 26 | 27 | 28 | def fred_qd(date: str = "2020-01") -> pd.DataFrame: 29 | """ 30 | FRED-QD is a quarterly frequency companion to FRED-MD. It is designed to emulate the dataset used in "Disentangling the Channels of the 2007-2009 Recession" by Stock and Watson (2012, NBER WP No. 18094) but also contains several additional series. Comments or suggestions are welcome. 31 | :param date: e.g., "2020-03"; from "2015-01" to now 32 | :type date: str 33 | :return: Quarterly Data 34 | :rtype: pandas.DataFrame 35 | """ 36 | url = f"https://s3.amazonaws.com/files.fred.stlouisfed.org/fred-md/quarterly/{date}.csv" 37 | temp_df = pd.read_csv(url) 38 | return temp_df 39 | 40 | 41 | if __name__ == "__main__": 42 | fred_md_df = fred_md(date="2023-03") 43 | print(fred_md_df) 44 | 45 | fred_qd_df = fred_qd(date="2023-03") 46 | print(fred_qd_df) 47 | -------------------------------------------------------------------------------- /akshare/fx/fx_quote_baidu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2023/3/5 18:12 5 | Desc: 百度股市通-外汇-行情榜单 6 | https://gushitong.baidu.com/top/foreign-common-%E5%B8%B8%E7%94%A8 7 | """ 8 | 9 | import http.client 10 | import json 11 | import urllib 12 | 13 | import pandas as pd 14 | 15 | 16 | def fx_quote_baidu(symbol: str = "人民币") -> pd.DataFrame: 17 | """ 18 | 百度股市通-外汇-行情榜单 19 | https://gushitong.baidu.com/top/foreign-common-%E5%B8%B8%E7%94%A8 20 | :param symbol: choice of {"人民币", 美元"} 21 | :type symbol: str 22 | :return: 外汇行情数据 23 | :rtype: pandas.DataFrame 24 | """ 25 | symbol_map = { 26 | "人民币": "rmb", 27 | "美元": "dollar", 28 | } 29 | num = 0 30 | out_df = pd.DataFrame() 31 | while True: 32 | try: 33 | conn = http.client.HTTPSConnection("finance.pae.baidu.com") 34 | params = { 35 | "pn": num, 36 | "rn": "20", 37 | "type": symbol_map[symbol], 38 | "finClientType": "pc", 39 | } 40 | conn.request("GET", f"/api/getforeignrank?{urllib.parse.urlencode(params)}") 41 | res = conn.getresponse() 42 | data = res.read() 43 | data_json = json.loads(data.decode("utf-8")) 44 | temp_df = pd.DataFrame(data_json["Result"]) 45 | temp_list = [] 46 | for item in temp_df["list"]: 47 | temp_list.append(list(pd.DataFrame(item).T.iloc[1, :].values)) 48 | value_df = pd.DataFrame( 49 | temp_list, columns=pd.DataFrame(item).T.iloc[0, :].values 50 | ) 51 | big_df = pd.concat([temp_df, value_df], axis=1) 52 | del big_df["market"] 53 | del big_df["list"] 54 | del big_df["status"] 55 | del big_df["icon1"] 56 | del big_df["icon2"] 57 | big_df.columns = ["代码", "名称", "最新价", "涨跌额", "涨跌幅"] 58 | big_df["最新价"] = pd.to_numeric(big_df["最新价"]) 59 | big_df["涨跌额"] = pd.to_numeric(big_df["涨跌额"]) 60 | big_df["涨跌幅"] = pd.to_numeric(big_df["涨跌幅"].str.strip("%")) / 100 61 | out_df = pd.concat([out_df, big_df], ignore_index=True) 62 | num = num + 20 63 | except: # noqa: E722 64 | break 65 | return out_df 66 | 67 | 68 | if __name__ == "__main__": 69 | fx_quote_baidu_df = fx_quote_baidu(symbol="人民币") 70 | print(fx_quote_baidu_df) 71 | -------------------------------------------------------------------------------- /akshare/crypto/crypto_bitcoin_cme.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2023/9/5 15:41 5 | Desc: 芝加哥商业交易所-比特币成交量报告 6 | https://datacenter.jin10.com/reportType/dc_cme_btc_report 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def crypto_bitcoin_cme(date: str = "20230830") -> pd.DataFrame: 14 | """ 15 | 芝加哥商业交易所-比特币成交量报告 16 | https://datacenter.jin10.com/reportType/dc_cme_btc_report 17 | :param date: Specific date, e.g., "20230830" 18 | :type date: str 19 | :return: 比特币成交量报告 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = "https://datacenter-api.jin10.com/reports/list" 23 | params = { 24 | "category": "cme", 25 | "date": "-".join([date[:4], date[4:6], date[6:]]), 26 | "attr_id": "4", 27 | } 28 | headers = { 29 | "accept": "*/*", 30 | "accept-encoding": "gzip, deflate, br", 31 | "accept-language": "zh-CN,zh;q=0.9,en;q=0.8", 32 | "cache-control": "no-cache", 33 | "origin": "https://datacenter.jin10.com", 34 | "pragma": "no-cache", 35 | "referer": "https://datacenter.jin10.com/", 36 | "sec-ch-ua": '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"', 37 | "sec-ch-ua-mobile": "?0", 38 | "sec-fetch-dest": "empty", 39 | "sec-fetch-mode": "cors", 40 | "sec-fetch-site": "same-site", 41 | "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36", 42 | "x-app-id": "rU6QIu7JHe2gOUeR", 43 | "x-csrf-token": "", 44 | "x-version": "1.0.0", 45 | } 46 | r = requests.get(url, params=params, headers=headers) 47 | data_json = r.json() 48 | temp_df = pd.DataFrame( 49 | [item for item in data_json["data"]["values"]], 50 | columns=[item["name"] for item in data_json["data"]["keys"]], 51 | ) 52 | temp_df["电子交易合约"] = pd.to_numeric(temp_df["电子交易合约"], errors="coerce") 53 | temp_df["场内成交合约"] = pd.to_numeric(temp_df["场内成交合约"], errors="coerce") 54 | temp_df["场外成交合约"] = pd.to_numeric(temp_df["场外成交合约"], errors="coerce") 55 | temp_df["成交量"] = pd.to_numeric(temp_df["成交量"], errors="coerce") 56 | temp_df["未平仓合约"] = pd.to_numeric(temp_df["未平仓合约"], errors="coerce") 57 | temp_df["持仓变化"] = pd.to_numeric(temp_df["持仓变化"], errors="coerce") 58 | return temp_df 59 | 60 | 61 | if __name__ == "__main__": 62 | crypto_bitcoin_cme_df = crypto_bitcoin_cme(date="20230830") 63 | print(crypto_bitcoin_cme_df) 64 | -------------------------------------------------------------------------------- /akshare/option/option_premium_analysis_em.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2025/3/11 17:00 5 | Desc: 东方财富网-数据中心-特色数据-期权折溢价 6 | https://data.eastmoney.com/other/premium.html 7 | """ 8 | 9 | import pandas as pd 10 | 11 | from akshare.utils.func import fetch_paginated_data 12 | 13 | 14 | def option_premium_analysis_em() -> pd.DataFrame: 15 | """ 16 | 东方财富网-数据中心-特色数据-期权折溢价 17 | https://data.eastmoney.com/other/premium.html 18 | :return: 期权折溢价 19 | :rtype: pandas.DataFrame 20 | """ 21 | url = "https://push2.eastmoney.com/api/qt/clist/get" 22 | params = { 23 | "fid": "f250", 24 | "po": "1", 25 | "pz": "100", 26 | "pn": "1", 27 | "np": "1", 28 | "fltt": "2", 29 | "invt": "2", 30 | "ut": "b2884a393a59ad64002292a3e90d46a5", 31 | "fields": "f1,f2,f3,f12,f13,f14,f161,f250,f330,f331,f332,f333,f334,f335,f337,f301,f152", 32 | "fs": "m:10", 33 | } 34 | temp_df = fetch_paginated_data(url, params) 35 | temp_df.columns = [ 36 | "-", 37 | "-", 38 | "最新价", 39 | "涨跌幅", 40 | "期权代码", 41 | "-", 42 | "期权名称", 43 | "-", 44 | "行权价", 45 | "折溢价率", 46 | "到期日", 47 | "-", 48 | "-", 49 | "-", 50 | "标的名称", 51 | "标的最新价", 52 | "标的涨跌幅", 53 | "盈亏平衡价", 54 | ] 55 | temp_df = temp_df[ 56 | [ 57 | "期权代码", 58 | "期权名称", 59 | "最新价", 60 | "涨跌幅", 61 | "行权价", 62 | "折溢价率", 63 | "标的名称", 64 | "标的最新价", 65 | "标的涨跌幅", 66 | "盈亏平衡价", 67 | "到期日", 68 | ] 69 | ] 70 | temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce") 71 | temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce") 72 | temp_df["行权价"] = pd.to_numeric(temp_df["行权价"], errors="coerce") 73 | temp_df["折溢价率"] = pd.to_numeric(temp_df["折溢价率"], errors="coerce") 74 | temp_df["标的最新价"] = pd.to_numeric(temp_df["标的最新价"], errors="coerce") 75 | temp_df["标的涨跌幅"] = pd.to_numeric(temp_df["标的涨跌幅"], errors="coerce") 76 | temp_df["盈亏平衡价"] = pd.to_numeric(temp_df["盈亏平衡价"], errors="coerce") 77 | temp_df["到期日"] = pd.to_datetime( 78 | temp_df["到期日"].astype(str), errors="coerce" 79 | ).dt.date 80 | return temp_df 81 | 82 | 83 | if __name__ == "__main__": 84 | option_premium_analysis_em_df = option_premium_analysis_em() 85 | print(option_premium_analysis_em_df) 86 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_tfp_em.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/4/29 15:00 5 | Desc: 东方财富网-数据中心-特色数据-停复牌信息 6 | https://data.eastmoney.com/tfpxx/ 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def stock_tfp_em(date: str = "20240426") -> pd.DataFrame: 14 | """ 15 | 东方财富网-数据中心-特色数据-停复牌信息 16 | https://data.eastmoney.com/tfpxx/ 17 | :param date: 查询参数 "20240426" 18 | :type date: str 19 | :return: 停复牌信息表 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = "https://datacenter-web.eastmoney.com/api/data/v1/get" 23 | params = { 24 | "sortColumns": "SUSPEND_START_DATE", 25 | "sortTypes": "-1", 26 | "pageSize": "500", 27 | "pageNumber": "1", 28 | "reportName": "RPT_CUSTOM_SUSPEND_DATA_INTERFACE", 29 | "columns": "ALL", 30 | "source": "WEB", 31 | "client": "WEB", 32 | "filter": f"""(MARKET="全部")(DATETIME='{"-".join([date[:4], date[4:6], date[6:]])}')""", 33 | } 34 | r = requests.get(url, params=params) 35 | data_json = r.json() 36 | total_page = data_json["result"]["pages"] 37 | big_df = pd.DataFrame() 38 | for page in range(1, total_page + 1): 39 | params.update({"pageNumber": page}) 40 | r = requests.get(url, params=params) 41 | data_json = r.json() 42 | temp_df = pd.DataFrame(data_json["result"]["data"]) 43 | big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True) 44 | 45 | big_df.reset_index(inplace=True) 46 | big_df.columns = [ 47 | "序号", 48 | "代码", 49 | "名称", 50 | "停牌时间", 51 | "停牌截止时间", 52 | "停牌期限", 53 | "停牌原因", 54 | "所属市场", 55 | "停牌开始日期", 56 | "预计复牌时间", 57 | "-", 58 | "-", 59 | "-", 60 | ] 61 | big_df = big_df[ 62 | [ 63 | "序号", 64 | "代码", 65 | "名称", 66 | "停牌时间", 67 | "停牌截止时间", 68 | "停牌期限", 69 | "停牌原因", 70 | "所属市场", 71 | "预计复牌时间", 72 | ] 73 | ] 74 | big_df["停牌时间"] = pd.to_datetime(big_df["停牌时间"], errors="coerce").dt.date 75 | big_df["停牌截止时间"] = pd.to_datetime( 76 | big_df["停牌截止时间"], errors="coerce" 77 | ).dt.date 78 | big_df["预计复牌时间"] = pd.to_datetime( 79 | big_df["预计复牌时间"], errors="coerce" 80 | ).dt.date 81 | return big_df 82 | 83 | 84 | if __name__ == "__main__": 85 | stock_tfp_em_df = stock_tfp_em(date="20240426") 86 | print(stock_tfp_em_df) 87 | -------------------------------------------------------------------------------- /akshare/option/option_czce.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/10/17 16:30 5 | Desc: 郑州商品交易所-交易数据-历史行情下载-期权历史行情下载 6 | http://www.czce.com.cn/cn/jysj/lshqxz/H770319index_1.htm 7 | 自 20200101 起,成交量、空盘量、成交额、行权量均为单边计算 8 | 郑州商品交易所-期权上市时间表 9 | "SR": "20170419" 10 | "CF": "20190410" 11 | "TA": "20191216" 12 | "MA": "20191217" 13 | "RM": "20200116" 14 | "ZC": "20200630" 15 | "OI": "20220826" 16 | "PK": "20220826" 17 | "PX": "20230915" 18 | "SH": "20230915" 19 | "SA": "20231020" 20 | "PF": "20231020" 21 | "SM": "20231020" 22 | "SF": "20231020" 23 | "UR": "20231020" 24 | "AP": "20231020" 25 | "CJ": "20240621" 26 | "FG": "20240621" 27 | "PR": "20241227" 28 | """ 29 | 30 | import warnings 31 | from io import StringIO 32 | 33 | import pandas as pd 34 | import requests 35 | 36 | 37 | def option_hist_yearly_czce(symbol: str = "SR", year: str = "2021") -> pd.DataFrame: 38 | """ 39 | 郑州商品交易所-交易数据-历史行情下载-期权历史行情下载 40 | http://www.czce.com.cn/cn/jysj/lshqxz/H770319index_1.htm 41 | :param symbol: choice of {"白糖": "SR", "棉花": "CF", "PTA": "TA", "甲醇": "MA", "菜籽粕": "RM", 42 | "动力煤": "ZC", "菜籽油": "OI", "花生": "PK", "对二甲苯": "PX", "烧碱": "SH", "纯碱": "SA", "短纤": "PF", 43 | "锰硅": "SM", "硅铁": "SF", "尿素": "UR", "苹果": "AP", "红枣": "CJ", "玻璃": "FG", "瓶片": "PR"} 44 | :type symbol: str 45 | :param year: 需要获取数据的年份, 注意品种的上市时间 46 | :type year: str 47 | :return: 指定年份的日频期权数据 48 | :rtype: pandas.DataFrame 49 | """ 50 | symbol_year_dict = { 51 | "SR": "2017", 52 | "CF": "2019", 53 | "TA": "2019", 54 | "MA": "2019", 55 | "RM": "2020", 56 | "ZC": "2020", 57 | "OI": "2022", 58 | "PK": "2022", 59 | "PX": "2023", 60 | "SH": "2023", 61 | "SA": "2023", 62 | "PF": "2023", 63 | "SM": "2023", 64 | "SF": "2023", 65 | "UR": "2023", 66 | "AP": "2023", 67 | "CJ": "2024", 68 | "FG": "2024", 69 | "PR": "2024", 70 | } 71 | if int(symbol_year_dict[symbol]) > int(year): 72 | warnings.warn(f"{year} year, symbol {symbol} is not on trade") 73 | return pd.DataFrame() 74 | url = f"http://www.czce.com.cn/cn/DFSStaticFiles/Option/{year}/OptionDataAllHistory/{symbol}OPTIONS{year}.txt" 75 | r = requests.get(url) 76 | option_df = pd.read_table(StringIO(r.text), skiprows=1, sep="|", low_memory=False) 77 | return option_df 78 | 79 | 80 | if __name__ == "__main__": 81 | option_hist_yearly_czce_df = option_hist_yearly_czce(symbol="RM", year="2025") 82 | print(option_hist_yearly_czce_df) 83 | -------------------------------------------------------------------------------- /akshare/stock/stock_intraday_sina.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/9/28 13:30 5 | Desc: 新浪财经-日内分时数据 6 | https://quote.eastmoney.com/f1.html?newcode=0.000001 7 | """ 8 | 9 | import math 10 | 11 | import pandas as pd 12 | import requests 13 | 14 | from akshare.utils.tqdm import get_tqdm 15 | 16 | 17 | def stock_intraday_sina( 18 | symbol: str = "sz000001", date: str = "20240321" 19 | ) -> pd.DataFrame: 20 | """ 21 | 新浪财经-日内分时数据 22 | https://vip.stock.finance.sina.com.cn/quotes_service/view/cn_bill.php?symbol=sz000001 23 | :param symbol: 股票代码 24 | :type symbol: str 25 | :param date: 交易日 26 | :type date: str 27 | :return: 分时数据 28 | :rtype: pandas.DataFrame 29 | """ 30 | url = "https://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_Bill.GetBillListCount" 31 | params = { 32 | "symbol": f"{symbol}", 33 | "num": "60", 34 | "page": "1", 35 | "sort": "ticktime", 36 | "asc": "0", 37 | "volume": "0", 38 | "amount": "0", 39 | "type": "0", 40 | "day": "-".join([date[:4], date[4:6], date[6:]]), 41 | } 42 | headers = { 43 | "Referer": f"https://vip.stock.finance.sina.com.cn/quotes_service/view/cn_bill.php?symbol={symbol}", 44 | "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " 45 | "Chrome/107.0.0.0 Safari/537.36", 46 | } 47 | r = requests.get(url=url, params=params, headers=headers) 48 | data_json = r.json() 49 | total_page = math.ceil(int(data_json) / 60) 50 | url = "https://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_Bill.GetBillList" 51 | big_df = pd.DataFrame() 52 | tqdm = get_tqdm() 53 | for page in tqdm(range(1, total_page + 1), leave=False): 54 | params.update({"page": page}) 55 | r = requests.get(url=url, params=params, headers=headers) 56 | data_json = r.json() 57 | temp_df = pd.DataFrame(data_json) 58 | big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True) 59 | big_df.sort_values(by=["ticktime"], inplace=True, ignore_index=True) 60 | big_df["price"] = pd.to_numeric(big_df["price"], errors="coerce") 61 | big_df["volume"] = pd.to_numeric(big_df["volume"], errors="coerce") 62 | big_df["prev_price"] = pd.to_numeric(big_df["prev_price"], errors="coerce") 63 | return big_df 64 | 65 | 66 | if __name__ == "__main__": 67 | stock_intraday_sina_df = stock_intraday_sina(symbol="sz000001", date="20250926") 68 | print(stock_intraday_sina_df) 69 | -------------------------------------------------------------------------------- /docs/akdocker/akdocker.md: -------------------------------------------------------------------------------- 1 | # [AKShare](https://github.com/akfamily/akshare) Docker 部署 2 | 3 | 目前 [AKShare](https://github.com/akfamily/akshare) 数据接口是基于 Python 开发的,鉴于部分小伙伴难以在短时间部署 4 | [AKShare](https://github.com/akfamily/akshare) 的 Python 使用环境,特此提供基于 Docker 容器技术的使用教程。 5 | 6 | ## 安装 Docker 7 | 8 | ### 官方安装指导 9 | 10 | 1. Windows 11: [安装教程](https://hub.docker.com/editions/community/docker-ce-desktop-windows) 11 | 2. Mac: [安装教程](https://docs.docker.com/docker-for-mac/install) 12 | 3. Ubuntu: [安装教程](https://docs.docker.com/engine/install/ubuntu) 13 | 4. CentOS: [安装教程](https://docs.docker.com/engine/install/centos) 14 | 15 | ### 第三方安装指导 16 | 17 | 1. [Docker 安装教程](https://www.runoob.com/docker/docker-tutorial.html) 18 | 2. 建议 Windows 7 和 8 的用户升级到 Windows 10/11 系统进行安装 19 | 3. [Windows 镜像下载地址](https://msdn.itellyou.cn/) 20 | 21 | ### 配置国内镜像 22 | 23 | 1. [Docker 国内镜像加速教程](https://www.runoob.com/docker/docker-mirror-acceleration.html) 24 | 2. 请在国内使用的用户务必进行该项配置, 从而加速获取镜像的速度. 25 | 26 | ## AKDocker 镜像使用 27 | 28 | ### 拉取 AKDocker 镜像 29 | 30 | 此镜像会在每次 AKShare 更新版本时自动更新 31 | 32 | ``` 33 | docker pull registry.cn-shanghai.aliyuncs.com/akfamily/aktools:jupyter 34 | ``` 35 | 36 | ### 运行 AKDocker 容器 37 | 38 | ``` 39 | docker run -it registry.cn-shanghai.aliyuncs.com/akfamily/aktools:jupyter 40 | ``` 41 | 42 | ### 测试 AKDocker 容器 43 | 44 | ```python 45 | import akshare as ak 46 | 47 | print(ak.__version__) 48 | ``` 49 | 50 | ## 使用案例 51 | 52 | ### 背景说明 53 | 54 | 本案例是基于 AKDocker 容器中已经安装的 JupyterLab 来演示的. 主要是利用 JupyterLab 的 Python 交互式的开发环境, 使用户可以在 Web 输入 AKShare 55 | 的 Python 示例代码, 仅需要修改一些简单的参数, 就可以获取需要的数据. 为了能把 JupyterLab 中下载的数据从容器映射到本地, 请在 56 | 容器的 ```/home``` 目录下编辑 ```.ipynb``` 文件, 如果需要下载相关的文件也请保存到该目录. 57 | 58 | ### 命令行 59 | 60 | ``` 61 | docker run -it -p 8888:8888 --name akdocker -v /c/home:/home registry.cn-shanghai.aliyuncs.com/akfamily/aktools:jupyter jupyter-lab --allow-root --no-browser --ip=0.0.0.0 62 | ``` 63 | 64 | ### 注意事项 65 | 66 | 1. 其中 Windows 系统的路径如: ```C:\home``` 需要改写为: ```/c/home``` 的形式; 67 | 2. 在 Terminal 中运行上述指令后,会在 Terminal 中显示如下信息: ![](https://jfds-1252952517.cos.ap-chengdu.myqcloud.com/akshare/readme/akdocker/akdocker_terminal.png) 68 | 3. 打开本地游览器输入地址: ```http://127.0.0.1:8888/lab?token=bbe7c8633c098b67df913dce522b82e00828b311a6fc954d```; 69 | 4. 在本地游览器中的 JupyterLab 界面进入 ```home``` 文件夹, 该目录内容会与本地的 ```C:\home``` 保持同步, 可以在此编辑 notebook 文件和导入数据到该文件夹从而在本地的 ```C:\home``` 文件夹下获取数据; 70 | 5. 如果在 JupyterLab 中的 AKShare 版本不是最新版,有以下两种方法: 71 | 1. 在 JupyterLab 中运行 `!pip install akshare --upgrade` 命令来升级 AKShare 到最新版 72 | 2. 在容器中进行升级 AKShare 并保存为新的镜像文件后使用,参考:https://aktools.akfamily.xyz/aktools/ 中【升级镜像】部分 73 | -------------------------------------------------------------------------------- /akshare/stock/stock_hot_up_em.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2023/6/15 15:15 5 | Desc: 东方财富个股人气榜 6 | https://guba.eastmoney.com/rank/ 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def stock_hot_up_em() -> pd.DataFrame: 14 | """ 15 | 东方财富-个股人气榜-飙升榜 16 | https://guba.eastmoney.com/rank/ 17 | :return: 飙升榜 18 | :rtype: pandas.DataFrame 19 | """ 20 | url = "https://emappdata.eastmoney.com/stockrank/getAllHisRcList" 21 | payload = { 22 | "appId": "appId01", 23 | "globalId": "786e4c21-70dc-435a-93bb-38", 24 | "marketType": "", 25 | "pageNo": 1, 26 | "pageSize": 100, 27 | } 28 | r = requests.post(url, json=payload) 29 | data_json = r.json() 30 | temp_rank_df = pd.DataFrame(data_json["data"]) 31 | 32 | temp_rank_df["mark"] = [ 33 | "0" + "." + item[2:] if "SZ" in item else "1" + "." + item[2:] 34 | for item in temp_rank_df["sc"] 35 | ] 36 | ",".join(temp_rank_df["mark"]) + "?v=08926209912590994" 37 | params = { 38 | "ut": "f057cbcbce2a86e2866ab8877db1d059", 39 | "fltt": "2", 40 | "invt": "2", 41 | "fields": "f14,f3,f12,f2", 42 | "secids": ",".join(temp_rank_df["mark"]) + ",?v=08926209912590994", 43 | } 44 | url = "https://push2.eastmoney.com/api/qt/ulist.np/get" 45 | r = requests.get(url, params=params) 46 | data_json = r.json() 47 | temp_df = pd.DataFrame(data_json["data"]["diff"]) 48 | temp_df.columns = ["最新价", "涨跌幅", "代码", "股票名称"] 49 | temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce") 50 | temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce") 51 | temp_df["涨跌额"] = temp_df["最新价"] * temp_df["涨跌幅"] / 100 52 | temp_df["当前排名"] = temp_rank_df["rk"] 53 | temp_df["代码"] = temp_rank_df["sc"] 54 | temp_df["排名较昨日变动"] = temp_rank_df["hrc"] 55 | temp_df = temp_df[ 56 | [ 57 | "排名较昨日变动", 58 | "当前排名", 59 | "代码", 60 | "股票名称", 61 | "最新价", 62 | "涨跌额", 63 | "涨跌幅", 64 | ] 65 | ] 66 | temp_df["排名较昨日变动"] = pd.to_numeric( 67 | temp_df["排名较昨日变动"], errors="coerce" 68 | ) 69 | temp_df["当前排名"] = pd.to_numeric(temp_df["当前排名"], errors="coerce") 70 | temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce") 71 | temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce") 72 | return temp_df 73 | 74 | 75 | if __name__ == "__main__": 76 | stock_hot_up_em_df = stock_hot_up_em() 77 | print(stock_hot_up_em_df) 78 | -------------------------------------------------------------------------------- /akshare/option/option_value_analysis_em.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2025/3/11 17:00 5 | Desc: 东方财富网-数据中心-特色数据-期权价值分析 6 | https://data.eastmoney.com/other/valueAnal.html 7 | """ 8 | 9 | import pandas as pd 10 | 11 | from akshare.utils.func import fetch_paginated_data 12 | 13 | 14 | def option_value_analysis_em() -> pd.DataFrame: 15 | """ 16 | 东方财富网-数据中心-特色数据-期权价值分析 17 | https://data.eastmoney.com/other/valueAnal.html 18 | :return: 期权价值分析 19 | :rtype: pandas.DataFrame 20 | """ 21 | url = "https://push2.eastmoney.com/api/qt/clist/get" 22 | params = { 23 | "fid": "f301", 24 | "po": "1", 25 | "pz": "100", 26 | "pn": "1", 27 | "np": "1", 28 | "fltt": "2", 29 | "invt": "2", 30 | "ut": "b2884a393a59ad64002292a3e90d46a5", 31 | "fields": "f1,f2,f3,f12,f13,f14,f298,f299,f249,f300,f330,f331,f332,f333,f334,f335,f336,f301,f152", 32 | "fs": "m:10", 33 | } 34 | temp_df = fetch_paginated_data(url, params) 35 | temp_df.columns = [ 36 | "-", 37 | "-", 38 | "最新价", 39 | "-", 40 | "期权代码", 41 | "-", 42 | "期权名称", 43 | "-", 44 | "隐含波动率", 45 | "时间价值", 46 | "内在价值", 47 | "理论价格", 48 | "到期日", 49 | "-", 50 | "-", 51 | "-", 52 | "标的名称", 53 | "标的最新价", 54 | "-", 55 | "标的近一年波动率", 56 | ] 57 | temp_df = temp_df[ 58 | [ 59 | "期权代码", 60 | "期权名称", 61 | "最新价", 62 | "时间价值", 63 | "内在价值", 64 | "隐含波动率", 65 | "理论价格", 66 | "标的名称", 67 | "标的最新价", 68 | "标的近一年波动率", 69 | "到期日", 70 | ] 71 | ] 72 | temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce") 73 | temp_df["时间价值"] = pd.to_numeric(temp_df["时间价值"], errors="coerce") 74 | temp_df["内在价值"] = pd.to_numeric(temp_df["内在价值"], errors="coerce") 75 | temp_df["隐含波动率"] = pd.to_numeric(temp_df["隐含波动率"], errors="coerce") 76 | temp_df["理论价格"] = pd.to_numeric(temp_df["理论价格"], errors="coerce") 77 | temp_df["标的最新价"] = pd.to_numeric(temp_df["标的最新价"], errors="coerce") 78 | temp_df["标的近一年波动率"] = pd.to_numeric( 79 | temp_df["标的近一年波动率"], errors="coerce" 80 | ) 81 | temp_df["到期日"] = pd.to_datetime( 82 | temp_df["到期日"].astype(str), errors="coerce" 83 | ).dt.date 84 | return temp_df 85 | 86 | 87 | if __name__ == "__main__": 88 | option_value_analysis_em_df = option_value_analysis_em() 89 | print(option_value_analysis_em_df) 90 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_value_em.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2024/11/26 18:00 5 | Desc: 东方财富网-数据中心-估值分析-每日互动-每日互动-估值分析 6 | https://data.eastmoney.com/gzfx/detail/300766.html 7 | """ 8 | 9 | import pandas as pd 10 | 11 | from akshare.request import make_request_with_retry_json 12 | 13 | 14 | def stock_value_em(symbol: str = "300766") -> pd.DataFrame: 15 | """ 16 | 东方财富网-数据中心-估值分析-每日互动-每日互动-估值分析 17 | https://data.eastmoney.com/gzfx/detail/300766.html 18 | :param symbol: 股票代码 19 | :type symbol: str 20 | :return: 估值分析 21 | :rtype: pandas.DataFrame 22 | """ 23 | url = "https://datacenter-web.eastmoney.com/api/data/v1/get" 24 | params = { 25 | "sortColumns": "TRADE_DATE", 26 | "sortTypes": "-1", 27 | "pageSize": "5000", 28 | "pageNumber": "1", 29 | "reportName": "RPT_VALUEANALYSIS_DET", 30 | "columns": "ALL", 31 | "quoteColumns": "", 32 | "source": "WEB", 33 | "client": "WEB", 34 | "filter": f'(SECURITY_CODE="{symbol}")', 35 | } 36 | data_json = make_request_with_retry_json(url, params=params) 37 | temp_json = data_json["result"]["data"] 38 | temp_df = pd.DataFrame(temp_json) 39 | temp_df.rename( 40 | columns={ 41 | "TRADE_DATE": "数据日期", 42 | "CLOSE_PRICE": "当日收盘价", 43 | "CHANGE_RATE": "当日涨跌幅", 44 | "TOTAL_MARKET_CAP": "总市值", 45 | "NOTLIMITED_MARKETCAP_A": "流通市值", 46 | "TOTAL_SHARES": "总股本", 47 | "FREE_SHARES_A": "流通股本", 48 | "PE_TTM": "PE(TTM)", 49 | "PE_LAR": "PE(静)", 50 | "PB_MRQ": "市净率", 51 | "PEG_CAR": "PEG值", 52 | "PCF_OCF_TTM": "市现率", 53 | "PS_TTM": "市销率", 54 | }, 55 | inplace=True, 56 | ) 57 | temp_df = temp_df[ 58 | [ 59 | "数据日期", 60 | "当日收盘价", 61 | "当日涨跌幅", 62 | "总市值", 63 | "流通市值", 64 | "总股本", 65 | "流通股本", 66 | "PE(TTM)", 67 | "PE(静)", 68 | "市净率", 69 | "PEG值", 70 | "市现率", 71 | "市销率", 72 | ] 73 | ] 74 | temp_df["数据日期"] = pd.to_datetime(temp_df["数据日期"], errors="coerce").dt.date 75 | for item in temp_df.columns[1:]: 76 | temp_df[item] = pd.to_numeric(temp_df[item], errors="coerce") 77 | temp_df.sort_values(by="数据日期", ignore_index=True, inplace=True) 78 | return temp_df 79 | 80 | 81 | if __name__ == "__main__": 82 | stock_value_em_df = stock_value_em(symbol="300766") 83 | print(stock_value_em_df) 84 | -------------------------------------------------------------------------------- /akshare/stock/stock_us_js.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2022/11/27 13:30 5 | Desc: 美股目标价 or 港股目标价 6 | https://www.ushknews.com/report.html 7 | """ 8 | 9 | import requests 10 | import pandas as pd 11 | 12 | 13 | def stock_price_js(symbol: str = "us") -> pd.DataFrame: 14 | """ 15 | 美股目标价 or 港股目标价 16 | https://www.ushknews.com/report.html 17 | :param symbol: choice of {"us", "hk"} 18 | :type symbol: str 19 | :return: 美股目标价 or 港股目标价 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = "https://calendar-api.ushknews.com/getWebTargetPriceList" 23 | params = { 24 | "limit": "20", 25 | "category": symbol, 26 | } 27 | headers = { 28 | "accept": "application/json, text/plain, */*", 29 | "accept-encoding": "gzip, deflate, br", 30 | "accept-language": "zh-CN,zh;q=0.9,en;q=0.8", 31 | "cache-control": "no-cache", 32 | "origin": "https://www.ushknews.com", 33 | "pragma": "no-cache", 34 | "referer": "https://www.ushknews.com/", 35 | "sec-ch-ua": '"Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"', 36 | "sec-ch-ua-mobile": "?0", 37 | "sec-ch-ua-platform": '"Windows"', 38 | "sec-fetch-dest": "empty", 39 | "sec-fetch-mode": "cors", 40 | "sec-fetch-site": "same-site", 41 | "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36", 42 | "x-app-id": "BNsiR9uq7yfW0LVz", 43 | "x-version": "1.0.0", 44 | } 45 | r = requests.get(url, params=params, headers=headers) 46 | json_data = r.json() 47 | temp_df = pd.DataFrame(json_data["data"]["list"]) 48 | temp_df.columns = [ 49 | "_", 50 | "_", 51 | "评级", 52 | "_", 53 | "最新目标价", 54 | "先前目标价", 55 | "机构名称", 56 | "日期", 57 | "_", 58 | "个股名称", 59 | "_", 60 | "_", 61 | ] 62 | temp_df = temp_df[ 63 | [ 64 | "日期", 65 | "个股名称", 66 | "评级", 67 | "先前目标价", 68 | "最新目标价", 69 | "机构名称", 70 | ] 71 | ] 72 | temp_df["日期"] = pd.to_datetime(temp_df["日期"]).dt.date 73 | temp_df["先前目标价"] = pd.to_numeric(temp_df["先前目标价"], errors="coerce") 74 | temp_df["最新目标价"] = pd.to_numeric(temp_df["最新目标价"], errors="coerce") 75 | return temp_df 76 | 77 | 78 | if __name__ == "__main__": 79 | stock_price_js_df = stock_price_js(symbol="us") 80 | print(stock_price_js_df) 81 | 82 | stock_price_js_df = stock_price_js(symbol="hk") 83 | print(stock_price_js_df) 84 | -------------------------------------------------------------------------------- /akshare/stock_fundamental/stock_zygc.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2025/5/6 14:30 5 | Desc: 主营构成 6 | https://emweb.securities.eastmoney.com/PC_HSF10/BusinessAnalysis/Index?type=web&code=SH688041# 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def stock_zygc_em(symbol: str = "SH688041") -> pd.DataFrame: 14 | """ 15 | 东方财富网-个股-主营构成 16 | https://emweb.securities.eastmoney.com/PC_HSF10/BusinessAnalysis/Index?type=web&code=SH688041# 17 | :param symbol: 带市场标识的股票代码 18 | :type symbol: str 19 | :return: 主营构成 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = "https://emweb.securities.eastmoney.com/PC_HSF10/BusinessAnalysis/PageAjax" 23 | params = {"code": symbol} 24 | r = requests.get(url, params=params) 25 | data_json = r.json() 26 | temp_df = pd.DataFrame(data_json["zygcfx"]) 27 | temp_df.rename( 28 | columns={ 29 | "SECUCODE": "-", 30 | "SECURITY_CODE": "股票代码", 31 | "REPORT_DATE": "报告日期", 32 | "MAINOP_TYPE": "分类类型", 33 | "ITEM_NAME": "主营构成", 34 | "MAIN_BUSINESS_INCOME": "主营收入", 35 | "MBI_RATIO": "收入比例", 36 | "MAIN_BUSINESS_COST": "主营成本", 37 | "MBC_RATIO": "成本比例", 38 | "MAIN_BUSINESS_RPOFIT": "主营利润", 39 | "MBR_RATIO": "利润比例", 40 | "GROSS_RPOFIT_RATIO": "毛利率", 41 | "RANK": "-", 42 | }, 43 | inplace=True, 44 | ) 45 | temp_df = temp_df[ 46 | [ 47 | "股票代码", 48 | "报告日期", 49 | "分类类型", 50 | "主营构成", 51 | "主营收入", 52 | "收入比例", 53 | "主营成本", 54 | "成本比例", 55 | "主营利润", 56 | "利润比例", 57 | "毛利率", 58 | ] 59 | ] 60 | temp_df["报告日期"] = pd.to_datetime(temp_df["报告日期"], errors="coerce").dt.date 61 | temp_df["分类类型"] = temp_df["分类类型"].map( 62 | {"2": "按产品分类", "3": "按地区分类"} 63 | ) 64 | temp_df["主营收入"] = pd.to_numeric(temp_df["主营收入"], errors="coerce") 65 | temp_df["收入比例"] = pd.to_numeric(temp_df["收入比例"], errors="coerce") 66 | temp_df["主营成本"] = pd.to_numeric(temp_df["主营成本"], errors="coerce") 67 | temp_df["成本比例"] = pd.to_numeric(temp_df["成本比例"], errors="coerce") 68 | temp_df["主营利润"] = pd.to_numeric(temp_df["主营利润"], errors="coerce") 69 | temp_df["利润比例"] = pd.to_numeric(temp_df["利润比例"], errors="coerce") 70 | temp_df["毛利率"] = pd.to_numeric(temp_df["毛利率"], errors="coerce") 71 | return temp_df 72 | 73 | 74 | if __name__ == "__main__": 75 | stock_zygc_em_df = stock_zygc_em(symbol="SH688041") 76 | print(stock_zygc_em_df) 77 | -------------------------------------------------------------------------------- /akshare/index/index_global_sina.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/3/7 17:00 5 | Desc: 新浪财经-行情中心-环球市场 6 | https://finance.sina.com.cn/stock/globalindex/quotes/UKX 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | from akshare.index.cons import index_global_sina_symbol_map 13 | 14 | 15 | def index_global_name_table() -> pd.DataFrame: 16 | """ 17 | 新浪财经-行情中心-环球市场-名称代码映射表 18 | https://finance.sina.com.cn/stock/globalindex/quotes/UKX 19 | :return: 名称代码映射表 20 | :rtype: pandas.DataFrame 21 | """ 22 | temp_df = pd.DataFrame.from_dict( 23 | index_global_sina_symbol_map, orient="index", columns=["代码"] 24 | ) 25 | temp_df.index.name = "指数名称" 26 | temp_df.reset_index(inplace=True) 27 | return temp_df 28 | 29 | 30 | def index_global_hist_sina(symbol: str = "OMX") -> pd.DataFrame: 31 | """ 32 | 新浪财经-行情中心-环球市场-历史行情 33 | https://finance.sina.com.cn/stock/globalindex/quotes/UKX 34 | :param symbol: 指数名称;可以通过 ak.index_global_name_table() 获取 35 | :type symbol: str 36 | :return: 环球市场历史行情 37 | :rtype: pandas.DataFrame 38 | """ 39 | url = "https://gi.finance.sina.com.cn/hq/daily" 40 | params = { 41 | "symbol": index_global_sina_symbol_map[symbol], 42 | "num": "10000", 43 | } 44 | r = requests.get(url=url, params=params) 45 | data_json = r.json() 46 | temp_df = pd.DataFrame(data_json["result"]["data"]) 47 | temp_df.rename( 48 | columns={ 49 | "d": "date", 50 | "o": "open", 51 | "h": "high", 52 | "l": "low", 53 | "c": "close", 54 | "v": "volume", 55 | }, 56 | inplace=True, 57 | ) 58 | temp_df = temp_df[ 59 | [ 60 | "date", 61 | "open", 62 | "high", 63 | "low", 64 | "close", 65 | "volume", 66 | ] 67 | ] 68 | temp_df["date"] = pd.to_datetime(temp_df["date"], errors="coerce").dt.date 69 | temp_df["open"] = pd.to_numeric(temp_df["open"], errors="coerce") 70 | temp_df["high"] = pd.to_numeric(temp_df["high"], errors="coerce") 71 | temp_df["low"] = pd.to_numeric(temp_df["low"], errors="coerce") 72 | temp_df["close"] = pd.to_numeric(temp_df["close"], errors="coerce") 73 | temp_df["volume"] = pd.to_numeric(temp_df["volume"], errors="coerce") 74 | return temp_df 75 | 76 | 77 | if __name__ == "__main__": 78 | index_global_name_table_df = index_global_name_table() 79 | print(index_global_name_table_df) 80 | 81 | index_global_hist_sina_df = index_global_hist_sina(symbol="瑞士股票指数") 82 | print(index_global_hist_sina_df) 83 | -------------------------------------------------------------------------------- /akshare/option/option_risk_indicator_sse.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2025/9/8 16:20 5 | Desc: 上海证券交易所-产品-股票期权-期权风险指标 6 | """ 7 | 8 | import pandas as pd 9 | import requests 10 | 11 | 12 | def option_risk_indicator_sse(date: str = "20240626") -> pd.DataFrame: 13 | """ 14 | 上海证券交易所-产品-股票期权-期权风险指标 15 | http://www.sse.com.cn/assortment/options/risk/ 16 | :param date: 日期; 20150209 开始 17 | :type date: str 18 | :return: 期权风险指标 19 | :rtype: pandas.DataFrame 20 | """ 21 | url = "http://query.sse.com.cn/commonQuery.do" 22 | params = { 23 | "isPagination": "false", 24 | "trade_date": date, 25 | "sqlId": "SSE_ZQPZ_YSP_GGQQZSXT_YSHQ_QQFXZB_DATE_L", 26 | "contractSymbol": "", 27 | } 28 | headers = { 29 | "Accept": "*/*", 30 | "Accept-Encoding": "gzip, deflate", 31 | "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", 32 | "Cache-Control": "no-cache", 33 | "Connection": "keep-alive", 34 | "Host": "query.sse.com.cn", 35 | "Pragma": "no-cache", 36 | "Referer": "http://www.sse.com.cn/", 37 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " 38 | "Chrome/101.0.4951.67 Safari/537.36", 39 | } 40 | r = requests.get(url, params=params, headers=headers) 41 | data_json = r.json() 42 | temp_df = pd.DataFrame(data_json["result"]) 43 | temp_df = temp_df[ 44 | [ 45 | "TRADE_DATE", 46 | "SECURITY_ID", 47 | "CONTRACT_ID", 48 | "CONTRACT_SYMBOL", 49 | "DELTA_VALUE", 50 | "THETA_VALUE", 51 | "GAMMA_VALUE", 52 | "VEGA_VALUE", 53 | "RHO_VALUE", 54 | "IMPLC_VOLATLTY", 55 | ] 56 | ] 57 | temp_df["TRADE_DATE"] = pd.to_datetime( 58 | temp_df["TRADE_DATE"], errors="coerce" 59 | ).dt.date 60 | temp_df["DELTA_VALUE"] = pd.to_numeric(temp_df["DELTA_VALUE"], errors="coerce") 61 | temp_df["THETA_VALUE"] = pd.to_numeric(temp_df["THETA_VALUE"], errors="coerce") 62 | temp_df["GAMMA_VALUE"] = pd.to_numeric(temp_df["GAMMA_VALUE"], errors="coerce") 63 | temp_df["VEGA_VALUE"] = pd.to_numeric(temp_df["VEGA_VALUE"], errors="coerce") 64 | temp_df["RHO_VALUE"] = pd.to_numeric(temp_df["RHO_VALUE"], errors="coerce") 65 | temp_df["IMPLC_VOLATLTY"] = pd.to_numeric( 66 | temp_df["IMPLC_VOLATLTY"], errors="coerce" 67 | ) 68 | return temp_df 69 | 70 | 71 | if __name__ == "__main__": 72 | option_risk_indicator_sse_df = option_risk_indicator_sse(date="20240626") 73 | print(option_risk_indicator_sse_df) 74 | -------------------------------------------------------------------------------- /akshare/option/option_risk_analysis_em.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2025/3/13 21:50 5 | Desc: 东方财富网-数据中心-特色数据-期权风险分析 6 | https://data.eastmoney.com/other/riskanal.html 7 | """ 8 | 9 | import pandas as pd 10 | 11 | from akshare.utils.func import fetch_paginated_data 12 | 13 | 14 | def option_risk_analysis_em() -> pd.DataFrame: 15 | """ 16 | 东方财富网-数据中心-特色数据-期权风险分析 17 | https://data.eastmoney.com/other/riskanal.html 18 | :return: 期权风险分析 19 | :rtype: pandas.DataFrame 20 | """ 21 | url = "https://push2.eastmoney.com/api/qt/clist/get" 22 | params = { 23 | "fid": "f12", 24 | "po": "1", 25 | "pz": "100", 26 | "pn": "1", 27 | "np": "1", 28 | "fltt": "2", 29 | "invt": "2", 30 | "ut": "b2884a393a59ad64002292a3e90d46a5", 31 | "fields": "f1,f2,f3,f12,f13,f14,f302,f303,f325,f326,f327,f329,f328,f301,f152,f154", 32 | "fs": "m:10", 33 | } 34 | temp_df = fetch_paginated_data(url, params) 35 | temp_df.columns = [ 36 | "-", 37 | "-", 38 | "最新价", 39 | "涨跌幅", 40 | "期权代码", 41 | "-", 42 | "期权名称", 43 | "-", 44 | "-", 45 | "到期日", 46 | "杠杆比率", 47 | "实际杠杆比率", 48 | "Delta", 49 | "Gamma", 50 | "Vega", 51 | "Theta", 52 | "Rho", 53 | ] 54 | temp_df = temp_df[ 55 | [ 56 | "期权代码", 57 | "期权名称", 58 | "最新价", 59 | "涨跌幅", 60 | "杠杆比率", 61 | "实际杠杆比率", 62 | "Delta", 63 | "Gamma", 64 | "Vega", 65 | "Rho", 66 | "Theta", 67 | "到期日", 68 | ] 69 | ] 70 | temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce") 71 | temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce") 72 | temp_df["杠杆比率"] = pd.to_numeric(temp_df["杠杆比率"], errors="coerce") 73 | temp_df["实际杠杆比率"] = pd.to_numeric(temp_df["实际杠杆比率"], errors="coerce") 74 | temp_df["Delta"] = pd.to_numeric(temp_df["Delta"], errors="coerce") 75 | temp_df["Gamma"] = pd.to_numeric(temp_df["Gamma"], errors="coerce") 76 | temp_df["Vega"] = pd.to_numeric(temp_df["Vega"], errors="coerce") 77 | temp_df["Rho"] = pd.to_numeric(temp_df["Rho"], errors="coerce") 78 | temp_df["Theta"] = pd.to_numeric(temp_df["Theta"], errors="coerce") 79 | temp_df["到期日"] = pd.to_datetime( 80 | temp_df["到期日"], format="%Y%m%d", errors="coerce" 81 | ).dt.date 82 | return temp_df 83 | 84 | 85 | if __name__ == "__main__": 86 | option_risk_analysis_em_df = option_risk_analysis_em() 87 | print(option_risk_analysis_em_df) 88 | -------------------------------------------------------------------------------- /akshare/stock/stock_info_em.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2025/2/15 22:00 5 | Desc: 东方财富网-个股-股票信息 6 | https://quote.eastmoney.com/concept/sh603777.html?from=classic 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def stock_individual_info_em( 14 | symbol: str = "603777", timeout: float = None 15 | ) -> pd.DataFrame: 16 | """ 17 | 东方财富-个股-股票信息 18 | https://quote.eastmoney.com/concept/sh603777.html?from=classic 19 | :param symbol: 股票代码 20 | :type symbol: str 21 | :param timeout: choice of None or a positive float number 22 | :type timeout: float 23 | :return: 股票信息 24 | :rtype: pandas.DataFrame 25 | """ 26 | url = "https://push2.eastmoney.com/api/qt/stock/get" 27 | market_code = 1 if symbol.startswith("6") else 0 28 | params = { 29 | "fltt": "2", 30 | "invt": "2", 31 | "fields": "f120,f121,f122,f174,f175,f59,f163,f43,f57,f58,f169,f170,f46,f44,f51,f168,f47," 32 | "f164,f116,f60,f45,f52,f50,f48,f167,f117,f71,f161,f49,f530,f135,f136,f137,f138," 33 | "f139,f141,f142,f144,f145,f147,f148,f140,f143,f146,f149,f55,f62,f162,f92,f173,f104," 34 | "f105,f84,f85,f183,f184,f185,f186,f187,f188,f189,f190,f191,f192,f107,f111,f86,f177,f78," 35 | "f110,f262,f263,f264,f267,f268,f255,f256,f257,f258,f127,f199,f128,f198,f259,f260,f261," 36 | "f171,f277,f278,f279,f288,f152,f250,f251,f252,f253,f254,f269,f270,f271,f272,f273,f274," 37 | "f275,f276,f265,f266,f289,f290,f286,f285,f292,f293,f294,f295,f43", 38 | "secid": f"{market_code}.{symbol}", 39 | } 40 | r = requests.get(url, params=params, timeout=timeout) 41 | data_json = r.json() 42 | temp_df = pd.DataFrame(data_json) 43 | temp_df.reset_index(inplace=True) 44 | del temp_df["rc"] 45 | del temp_df["rt"] 46 | del temp_df["svr"] 47 | del temp_df["lt"] 48 | del temp_df["full"] 49 | code_name_map = { 50 | "f57": "股票代码", 51 | "f58": "股票简称", 52 | "f84": "总股本", 53 | "f85": "流通股", 54 | "f127": "行业", 55 | "f116": "总市值", 56 | "f117": "流通市值", 57 | "f189": "上市时间", 58 | "f43": "最新", 59 | } 60 | temp_df["index"] = temp_df["index"].map(code_name_map) 61 | temp_df = temp_df[pd.notna(temp_df["index"])] 62 | if "dlmkts" in temp_df.columns: 63 | del temp_df["dlmkts"] 64 | temp_df.columns = [ 65 | "item", 66 | "value", 67 | ] 68 | temp_df.reset_index(inplace=True, drop=True) 69 | return temp_df 70 | 71 | 72 | if __name__ == "__main__": 73 | stock_individual_info_em_df = stock_individual_info_em(symbol="000002") 74 | print(stock_individual_info_em_df) 75 | -------------------------------------------------------------------------------- /akshare/futures/futures_inventory_em.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | Date: 2025/3/5 17:30 5 | Desc: 东方财富网-数据中心-期货库存数据 6 | https://data.eastmoney.com/ifdata/kcsj.html 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | from akshare.futures.cons import futures_inventory_em_symbol_dict 12 | 13 | 14 | def futures_inventory_em(symbol: str = "a") -> pd.DataFrame: 15 | """ 16 | 东方财富网-数据中心-期货库存数据 17 | https://data.eastmoney.com/ifdata/kcsj.html 18 | :param symbol: 支持品种代码和中文名称,中文名称参见:https://data.eastmoney.com/ifdata/kcsj.html 19 | :type symbol: str 20 | :return: 指定品种的库存数据 21 | :rtype: pandas.DataFrame 22 | """ 23 | url = "https://datacenter-web.eastmoney.com/api/data/v1/get" 24 | params = { 25 | "reportName": "RPT_FUTU_POSITIONCODE", 26 | "columns": "TRADE_MARKET_CODE,TRADE_CODE,TRADE_TYPE", 27 | "filter": '(IS_MAINCODE="1")', 28 | "pageNumber": "1", 29 | "pageSize": "500", 30 | "source": "WEB", 31 | "client": "WEB", 32 | } 33 | r = requests.get(url, params=params) 34 | data_json = r.json() 35 | temp_df = pd.DataFrame(data_json["result"]["data"]) 36 | symbol_dict = dict(zip(temp_df["TRADE_TYPE"], temp_df["TRADE_CODE"])) 37 | if symbol in symbol_dict.keys(): 38 | product_id = symbol_dict[symbol] 39 | elif symbol in futures_inventory_em_symbol_dict.keys(): # 如果输入的是代码 40 | product_id = futures_inventory_em_symbol_dict[symbol] 41 | else: 42 | raise ValueError(f"请输入正确的 symbol, 可选项为: {symbol_dict}") 43 | params = { 44 | "reportName": "RPT_FUTU_STOCKDATA", 45 | "columns": "SECURITY_CODE,TRADE_DATE,ON_WARRANT_NUM,ADDCHANGE", 46 | "filter": f"""(SECURITY_CODE="{product_id}")(TRADE_DATE>='2020-10-28')""", 47 | "pageNumber": "1", 48 | "pageSize": "500", 49 | "sortTypes": "-1", 50 | "sortColumns": "TRADE_DATE", 51 | "source": "WEB", 52 | "client": "WEB", 53 | } 54 | r = requests.get(url, params=params) 55 | data_json = r.json() 56 | temp_df = pd.DataFrame(data_json["result"]["data"]) 57 | temp_df.columns = ["-", "日期", "库存", "增减"] 58 | temp_df = temp_df[["日期", "库存", "增减"]] 59 | temp_df.sort_values(["日期"], inplace=True) 60 | temp_df.reset_index(inplace=True, drop=True) 61 | temp_df["库存"] = pd.to_numeric(temp_df["库存"], errors="coerce") 62 | temp_df["增减"] = pd.to_numeric(temp_df["增减"], errors="coerce") 63 | temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date 64 | return temp_df 65 | 66 | 67 | if __name__ == "__main__": 68 | futures_inventory_em_df = futures_inventory_em(symbol="a") 69 | print(futures_inventory_em_df) 70 | -------------------------------------------------------------------------------- /akshare/stock_feature/stock_hsgt_min_em.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # !/usr/bin/env python 3 | """ 4 | Date: 2024/2/5 18:00 5 | Desc: 东方财富网-数据中心-沪深港通-市场概括 6 | https://data.eastmoney.com/hsgt/hsgtDetail/scgk.html 7 | """ 8 | 9 | import pandas as pd 10 | import requests 11 | 12 | 13 | def stock_hsgt_fund_min_em(symbol: str = "北向资金") -> pd.DataFrame: 14 | """ 15 | 东方财富-数据中心-沪深港通-市场概括-分时数据 16 | https://data.eastmoney.com/hsgt/hsgtDetail/scgk.html 17 | :param symbol: 北向资金; choice of {"北向资金", "南向资金"} 18 | :type symbol: str 19 | :return: 沪深港通持股-分时数据 20 | :rtype: pandas.DataFrame 21 | """ 22 | url = "https://push2.eastmoney.com/api/qt/kamtbs.rtmin/get" 23 | params = { 24 | "fields1": "f1,f2,f3,f4", 25 | "fields2": "f51,f54,f52,f58,f53,f62,f56,f57,f60,f61", 26 | "ut": "b2884a393a59ad64002292a3e90d46a5", 27 | "_": "1707125786160", 28 | } 29 | r = requests.get(url, params=params) 30 | data_json = r.json() 31 | 32 | if symbol == "南向资金": 33 | n2s_str_list = data_json["data"]["n2s"] 34 | temp_df = pd.DataFrame([item.split(",") for item in n2s_str_list]) 35 | temp_df["date"] = data_json["data"]["n2sDate"] 36 | temp_df = temp_df.iloc[:, [0, 1, 3, 5, -1]] 37 | temp_df.columns = ["时间", "港股通(沪)", "港股通(深)", "南向资金", "日期"] 38 | temp_df = temp_df[["日期", "时间", "港股通(沪)", "港股通(深)", "南向资金"]] 39 | temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date 40 | temp_df["港股通(沪)"] = pd.to_numeric(temp_df["港股通(沪)"], errors="coerce") 41 | temp_df["港股通(深)"] = pd.to_numeric(temp_df["港股通(深)"], errors="coerce") 42 | temp_df["南向资金"] = pd.to_numeric(temp_df["南向资金"], errors="coerce") 43 | return temp_df 44 | else: 45 | s2n_str_list = data_json["data"]["s2n"] 46 | temp_df = pd.DataFrame([item.split(",") for item in s2n_str_list]) 47 | temp_df["date"] = data_json["data"]["s2nDate"] 48 | temp_df = temp_df.iloc[:, [0, 1, 3, 5, -1]] 49 | temp_df.columns = ["时间", "沪股通", "深股通", "北向资金", "日期"] 50 | temp_df = temp_df[["日期", "时间", "沪股通", "深股通", "北向资金"]] 51 | temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date 52 | temp_df["沪股通"] = pd.to_numeric(temp_df["沪股通"], errors="coerce") 53 | temp_df["深股通"] = pd.to_numeric(temp_df["深股通"], errors="coerce") 54 | temp_df["北向资金"] = pd.to_numeric(temp_df["北向资金"], errors="coerce") 55 | return temp_df 56 | 57 | 58 | if __name__ == "__main__": 59 | stock_hsgt_fund_min_em_df = stock_hsgt_fund_min_em(symbol="北向资金") 60 | print(stock_hsgt_fund_min_em_df) 61 | 62 | stock_hsgt_fund_min_em_df = stock_hsgt_fund_min_em(symbol="南向资金") 63 | print(stock_hsgt_fund_min_em_df) 64 | --------------------------------------------------------------------------------