
Jqdatasdk
- 112 installs
- 169 repo stars
- Updated June 29, 2026
- lzwme/finance-quant-skills
Helps with ai & agent building tasks.
About
jqdatasdk is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- jqdatasdk
- AI & Agent Building
- AI-coding skill
Jqdatasdk by the numbers
- 112 all-time installs (skills.sh)
- +6 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #4,006 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/lzwme/finance-quant-skills --skill jqdatasdkAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 112 |
|---|---|
| repo stars | ★ 169 |
| Last updated | June 29, 2026 |
| Repository | lzwme/finance-quant-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
jqdatasdk 聚宽数据获取
任务目标
- 本 Skill 用于:通过聚宽数据接口获取A股市场数据、财务指标和因子数据
- 能力包含:实时行情、历史K线、财务数据、指标数据、股票信息、因子数据
- 触发条件:用户提及聚宽、jqdata、jqdatasdk或需要获取A股数据、财务信息、因子数据时
前置准备
- 依赖说明:安装 jqdatasdk 库(已包含在 dependency 中)
- 凭证配置:需配置聚宽账号 Token(环境变量: JQDATA_TOKEN)或登录用户名及密码(环境变量: JQDATA_USERNAME、JQDATA_PASSWORD)
- 账号申请:访问 https://www.joinquant.com/ 注册账号并获取 API Token(详见 references/jqdatasdk_quickstart.md)
操作步骤
- 标准流程:
1. 确定数据需求 — 智能体理解用户意图(行情/K线/财务/因子等) 2. 调用对应脚本 — 根据数据类型选择脚本 3. 解析结果 — 智能体分析返回的 JSON 格式数据
- 脚本调用映射:
- 行情/K线/实时数据 →
python scripts/market_data.py --type price --code 000001.XSHE --start 2024-01-01 --end 2024-01-31 - 财务数据/指标/估值 →
python scripts/financial_data.py --type fundamentals --code 000001.XSHE --statDate 2024 - 股票列表/信息 →
python scripts/stock_info.py --type all_securities --security_type stock - 因子数据 →
python scripts/factor_data.py --code 000001.XSHE --factor valuation --start 2024-01-01 --end 2024-01-31 - 可选分支:
- 当需要多只股票数据:使用 --code 参数逗号分隔
- 当需要指定频率:使用 --frequency 参数(1min/5min/15min/30min/60min/120min/daily/weekly/monthly)
- 当需要调整价格类型:使用 --fq_ref_date 参数或直接指定复权类型
使用示例
- 示例1:获取股票日K线数据
- 场景/输入:用户说"查看平安银行最近一个月的K线数据"
- 预期产出:返回日期、开盘价、最高价、最低价、收盘价、成交量等OHLCV数据
- 关键要点:调用
python scripts/market_data.py --type price --code 000001.XSHE --start 2024-03-01 --end 2024-03-31 --frequency daily - 示例2:查询财务指标
- 场景/输入:用户说"获取招商银行2023年的财务指标"
- 预期产出:返回PE、PB、ROE、营业收入、净利润等财务指标
- 关键要点:调用
python scripts/financial_data.py --type indicators --code 600036.XSHG --statDate 2023 - 示例3:获取因子数据
- 场景/输入:用户说"查询贵州茅台的估值因子"
- 预期产出:返回市盈率、市净率、市值等估值因子数据
- 关键要点:调用
python scripts/factor_data.py --code 600519.XSHG --factor valuation --start 2024-01-01 --end 2024-03-31
快速参考
常用代码示例
import jqdatasdk as jq
import pandas as pd
# 认证(需先设置环境变量 JQDATA_TOKEN 或 JQDATA_USERNAME/JQDATA_PASSWORD)
jq.auth(os.environ.get('JQDATA_USERNAME', ''), os.environ.get('JQDATA_PASSWORD', ''))
# 或使用 Token: jq.auth(token='your_token')
# 获取日K线数据
df = jq.get_price('000001.XSHE', start_date='2024-01-01', end_date='2024-12-31',
frequency='daily', fields=['open', 'high', 'low', 'close', 'volume'])
# 获取财务数据
q = jq.query(jq.valuation).filter(jq.valuation.code == '000001.XSHE')
fundamentals = jq.get_fundamentals(q, date='2024-01-01')资源索引
- 脚本:
- scripts/market_data.py (用途与参数:获取行情/K线/实时数据,支持 --type/--code/--start/--end/--frequency/--count)
- scripts/financial_data.py (用途与参数:获取财务/指标/估值数据,支持 --type/--code/--statDate/--columns)
- scripts/stock_info.py (用途与参数:获取股票列表/信息,支持 --type/--security_type/--code)
- scripts/factor_data.py (用途与参数:获取因子数据,支持 --code/--factor/--start/--end)
- 参考:
- references/jqdatasdk_quickstart.md (何时读取:首次配置或认证失败时)
- references/api.md (何时读取:需要使用聚宽 Python API、查看详细API参数说明时)
注意事项
- 脚本执行需配置聚宽账号 Token 或登录用户名及密码,首次使用需先完成凭证配置
- 聚宽股票代码格式:上海市场为
XXXXXX.XSHG,深圳市场为XXXXXX.XSHE - 部分数据(如财务数据)可能有延迟,建议在交易日9:30-15:00之外获取
- 脚本返回 JSON 格式数据,智能体负责解析并转换为用户友好的展示
- 调用频率有限制,避免短时间内大量请求(详见聚宽官方文档)
- 首次使用建议先读取 jqdatasdk_quickstart.md 完成认证配置
jqdatasdk API 参考文档
本文档提供 jqdatasdk 所有 API 的详细说明和参数定义。
目录
1. 认证与配置 2. 行情数据 3. 财务数据 4. 标的信息 5. 行业与概念 6. 资金流向 7. 融资融券 8. 期货数据 9. 因子数据 10. Alpha因子 11. 其他接口 12. 错误处理
---
认证与配置
jq.auth()
账号密码认证。
jq.auth(username, password, host=None, port=None)参数:
username(str): 聚宽账号用户名password(str): 聚宽账号密码host(str, optional): 服务器地址,默认 Noneport(int, optional): 服务器端口,默认 None
示例:
jq.auth('your_username', 'your_password')jq.auth_by_token()
使用 Token 认证。
jq.auth_by_token(token, host=None, port=None)参数:
token(str): 聚宽 Tokenhost(str, optional): 服务器地址port(int, optional): 服务器端口
示例:
jq.auth_by_token('your_token')jq.logout()
退出登录。
jq.logout()jq.is_auth()
检查认证状态。
jq.is_auth() -> bool返回: bool - 是否已认证
jq.set_params()
设置请求参数。
jq.set_params(**params)参数:
request_timeout(int): 请求超时时间(秒),默认300request_attempt_count(int): 请求重试次数,默认3request_username(str): 请求用户名request_password(str): 请求密码request_host(str): 请求服务器地址request_port(int): 请求服务器端口enable_auth_prompt(bool): 是否输出登录提示,默认True
---
行情数据
get_price()
获取一支或多支证券的行情数据(K线)。
get_price(security, start_date=None, end_date=None, frequency='daily',
fields=None, skip_paused=False, fq='pre', count=None,
panel=True, fill_paused=True, round=True)参数:
security(str/list): 证券代码或代码列表,格式为XXXXXX.XSHG(上海)或XXXXXX.XSHE(深圳)start_date(str/datetime, optional): 开始日期,格式YYYY-MM-DDend_date(str/datetime, optional): 结束日期,默认 '2015-12-31'frequency(str): 时间频率- 分钟线:
1min,5min,15min,30min,60min,120min - 日线:
daily(默认) - 周线:
weekly - 月线:
monthly fields(list, optional): 返回字段列表open: 开盘价close: 收盘价high: 最高价low: 最低价volume: 成交量money: 成交额skip_paused(bool): 是否跳过停牌日期,默认 Falsefq(str): 复权类型,'pre'前复权,'post'后复权, None不复权count(int, optional): 返回数据条数,与 start_date 二选一panel(bool): 是否返回 panel 对象,默认 Truefill_paused(bool): 停牌时是否用收盘价填充,默认 Trueround(bool): 是否四舍五入,默认 True
返回: DataFrame 或 Panel
示例:
# 获取单只股票日线数据
df = jq.get_price('000001.XSHE', start_date='2024-01-01', end_date='2024-12-31')
# 获取多只股票分钟数据
df = jq.get_price(['000001.XSHE', '600519.XSHG'],
start_date='2024-01-01', frequency='5m')
# 指定字段
df = jq.get_price('000001.XSHE',
start_date='2024-01-01',
end_date='2024-01-31',
frequency='daily',
fields=['open', 'close', 'high', 'low', 'volume'])get_bars()
获取历史K线数据。
get_bars(security, count=None, unit="1d",
fields=("date", "open", "high", "low", "close"),
include_now=False, end_dt=None, fq_ref_date=None, df=True,
start_dt=None, skip_paused=True)参数:
security(str/list): 证券代码count(int): 返回数据条数unit(str): 时间单位,支持'1m','5m','15m','30m','60m','120m','1d','1w','1M'fields(tuple/list): 返回字段include_now(bool): 是否包含当前barend_dt(str/datetime, optional): 截止时间fq_ref_date(str/datetime, optional): 复权基准日期df(bool): 是否返回 DataFramestart_dt(str/datetime, optional): 开始时间skip_paused(bool): 是否跳过停牌
get_ticks()
获取 Tick 逐笔数据。
get_ticks(security, start_dt=None, end_dt=None, count=None,
fields=None, skip=True, df=True)参数:
security(str): 股票或期货代码start_dt(str/datetime, optional): 开始时间,格式YYYY-MM-DD HH:MM:SSend_dt(str/datetime, optional): 截止时间count(int, optional): 数据条数fields(list, optional): 字段列表skip(bool): 是否过滤无成交tickdf(bool): 是否返回 DataFrame
返回: DataFrame,包含:
time: 时间price: 价格volume: 成交量amount: 成交额direction: 买卖方向
示例:
ticks = jq.get_ticks(security='000001.XSHE',
start_dt='2024-01-01 09:30:00',
end_dt='2024-01-01 15:00:00')get_current_tick()
获取最新Tick数据。
get_current_tick(security) -> DataFrame参数:
security(str/list): 证券代码
get_current_data()
获取实时数据快照。
参数: 无
返回: dict,键为证券代码,值为包含实时数据的对象
last_price: 最新价time: 时间day_open: 日开盘价day_high: 日最高价day_low: 日最低价volume: 成交量money: 成交额
示例:
data = jq.get_current_data()
if '000001.XSHE' in data:
print(data['000001.XSHE'].last_price)get_order_book()
获取委托数据(买卖五档)。
get_order_book(security, start_dt, end_dt)参数:
security(str): 证券代码start_dt(str): 开始日期时间end_dt(str): 结束日期时间
返回: list,包含买卖五档委托数据
示例:
orders = jq.get_order_book(security='000001.XSHE',
start_dt='2024-01-01 09:30:00',
end_dt='2024-01-01 09:35:00')get_extras()
获取额外数据。
get_extras(info, security_list, start_date=None, end_date=None, df=True, count=None)参数:
info(str): 数据类型'is_st': 是否ST'acc_net_value': 累计净值'unit_net_value': 单位净值'futures_sett_price': 期货结算价'futures_positions': 期货持仓security_list(list): 证券列表start_date(str/datetime, optional): 开始日期end_date(str/datetime, optional): 结束日期df(bool): 是否返回 DataFramecount(int, optional): 数据条数
---
财务数据
get_fundamentals()
查询财务数据。
get_fundamentals(query_object, date=None, statDate=None) -> DataFrame参数:
query_object(Query): SQLAlchemy Query 对象date(str/datetime, optional): 查询日期statDate(str, optional): 财报统计季度,如'2024q1'
返回: DataFrame
示例:
from jqdatasdk import finance
q = jq.query(
finance.indicator.code,
finance.indicator.pub_date,
finance.indicator.eps,
finance.indicator.net_profits,
finance.indicator.roe
).filter(
finance.indicator.code == '000001.XSHE'
)
df = jq.get_fundamentals(q, date='2024-12-31')get_fundamentals_continuously()
连续查询财务数据。
get_fundamentals_continuously(query_object, end_date=None, count=1, panel=True)参数:
query_object(Query): SQLAlchemy Query 对象end_date(str/datetime, optional): 截止日期count(int): 查询的日期数量panel(bool): 是否返回 Panel
finance.run_query()
通过 ORM 执行财务数据查询。
财务数据表:
1. 资产负债表 (finance.STK_BALANCE_SHEET)
code: 股票代码statDate: 报告期total_assets: 总资产total_liability: 总负债total_owner_equities: 股东权益
2. 利润表 (finance.STK_INCOME_STATEMENT)
code: 股票代码statDate: 报告期total_operating_revenue: 营业总收入operating_cost: 营业成本net_profit: 净利润
3. 现金流量表 (finance.STK_CASH_FLOW_STATEMENT)
code: 股票代码statDate: 报告期net_operate_cash_flow: 经营活动现金流net_invest_cash_flow: 投资活动现金流
4. 指标数据 (finance.indicator)
code: 股票代码statDate: 报告期roe: 净资产收益率inc_return: 投资回报率inc_revenue_year_on_year: 营业收入同比增长率net_profit_growth_rate: 净利润增长率roe_yearly: 年化净资产收益率
5. 估值数据 (finance.valuation)
code: 股票代码day: 日期market_cap: 总市值circulating_market_cap: 流通市值pe_ratio: 市盈率pb_ratio: 市净率ps_ratio: 市销率pcf_ratio: 市现率turnover_ratio: 换手率
查询示例:
from jqdatasdk import finance, query
# 查询资产负债表
q = query(finance.STK_BALANCE_SHEET.code,
finance.STK_BALANCE_SHEET.statDate,
finance.STK_BALANCE_SHEET.total_assets)
q = q.filter(finance.STK_BALANCE_SHEET.code == '000001.XSHE')
q = q.filter(finance.STK_BALANCE_SHEET.statDate == '2023')
df = finance.run_query(q)
# 查询指标数据
q = query(finance.indicator.code,
finance.indicator.statDate,
finance.indicator.roe,
finance.indicator.pe_ratio)
q = q.filter(finance.indicator.code.in_(['000001.XSHE', '600000.XSHG']))
df = finance.run_query(q)
# 查询估值数据
q = query(finance.valuation.code,
finance.valuation.day,
finance.valuation.market_cap,
finance.valuation.pe_ratio,
finance.valuation.pb_ratio)
q = q.filter(finance.valuation.code == '000001.XSHE')
q = q.filter(finance.valuation.day >= '2024-01-01')
df = finance.run_query(q)get_valuation()
获取市值数据。
get_valuation(security_list, start_date=None, end_date=None, fields=None, count=None)参数:
security_list(str/list): 证券代码列表start_date(str/datetime, optional): 开始日期end_date(str/datetime, optional): 结束日期fields(list, optional): 返回字段count(int, optional): 数据条数
可用字段:
code- 股票代码day- 日期pe_ratio- 市盈率(PE, TTM)turnover_ratio- 换手率(%)pb_ratio- 市净率(PB)ps_ratio- 市销率(PS, TTM)pcf_ratio- 市现率(PCF)capitalization- 总股本(万股)market_cap- 总市值(亿元)circulating_cap- 流通股本(万股)circulating_market_cap- 流通市值(亿元)
get_history_fundamentals()
获取历史财报数据。
get_history_fundamentals(security, fields, watch_date=None, stat_date=None,
count=1, interval='1q', stat_by_year=False)参数:
security(str/list): 股票代码fields(list): 要查询的字段列表watch_date(str/datetime, optional): 观察日期stat_date(str, optional): 统计日期,如'2024q1'count(int): 查询的历史报告期数量interval(str): 间隔,'1q'或'1y'stat_by_year(bool): 是否返回年度数据
---
标的信息
get_all_securities()
获取所有证券信息。
get_all_securities(types=[], date=None) -> DataFrame参数:
types(list, optional): 证券类型过滤'stock': 股票'fund': 基金'index': 指数'futures': 期货'etf': ETF'lof': LOF'bond': 债券date(str/datetime, optional): 查询日期
示例:
# 获取所有股票
stocks = jq.get_all_securities(['stock'])
# 获取所有基金
funds = jq.get_all_securities(['fund'])
# 获取所有指数
indices = jq.get_all_securities(['index'])get_security_info()
获取证券详细信息。
get_security_info(code, date=None) -> Security参数:
code(str): 证券代码date(str/datetime, optional): 查询日期
返回: object,包含:
code: 证券代码display_name: 显示名称name: 简称start_date: 上市日期end_date: 退市日期(如有)type: 类型parent: 母证券(适用于基金等)
示例:
info = jq.get_security_info('000001.XSHE')
print(info.display_name)
print(info.start_date)get_index_stocks()
获取指数成分股。
get_index_stocks(index_symbol, date=today()) -> list参数:
index_symbol(str): 指数代码'000300.XSHG': 沪深300'000905.XSHG': 中证500'000852.XSHG': 中证1000date(str/datetime, optional): 查询日期
示例:
hs300_stocks = jq.get_index_stocks('000300.XSHG')
zz500_stocks = jq.get_index_stocks('000905.XSHG')
zz1000_stocks = jq.get_index_stocks('000852.XSHG')---
行业与概念
get_industries()
获取行业列表。
get_industries(name='zjw', date=None) -> DataFrame参数:
name(str): 行业分类代码'zjw': 聚宽一级行业'sw_l1': 申万一级行业'sw_l2': 申万二级行业date(str/datetime, optional): 查询日期
get_industry_stocks()
获取行业股票列表。
get_industry_stocks(industry_code, date=today()) -> list参数:
industry_code(str): 行业代码date(str/datetime, optional): 查询日期
get_concepts()
获取概念板块列表。
get_concepts() -> DataFrameget_concept_stocks()
获取概念板块股票列表。
get_concept_stocks(concept_code, date=today()) -> list参数:
concept_code(str): 概念板块代码date(str/datetime, optional): 查询日期
get_concept()
获取股票所属概念。
get_concept(security, date) -> dictget_industry()
获取股票所属行业。
get_industry(security, date=None, df=False)---
资金流向
get_money_flow()
获取资金流向数据。
get_money_flow(security_list, start_date=None, end_date=None,
fields=None, count=None) -> DataFrame参数:
security_list(str/list): 证券代码start_date(str/datetime, optional): 开始日期end_date(str/datetime, optional): 结束日期fields(list, optional): 返回字段count(int, optional): 数据条数
可用字段:
date- 日期sec_code- 股票代码net_amount_main- 主力净流入net_pct_main- 主力净流入占比net_amount_xl- 超大单净流入net_amount_l- 大单净流入net_amount_m- 中单净流入net_amount_s- 小单净流入
get_money_flow_pro()
获取专业资金流向数据。
get_money_flow_pro(security_list, start_date=None, end_date=None,
frequency='daily', fields=None, count=None, data_type='money')参数:
frequency(str):'daily'或'minutes'data_type(str):'money','volume', 或'deal'
---
融资融券
get_mtss()
获取融资融券数据。
get_mtss(security_list, start_date=None, end_date=None, fields=None, count=None)get_margincash_stocks()
获取可融资标的列表。
get_margincash_stocks(date=None) -> listget_marginsec_stocks()
获取可融券标的列表。
get_marginsec_stocks(date=None) -> list---
期货数据
get_future_contracts()
获取期货合约列表。
get_future_contracts(underlying_symbol, date=None) -> list参数:
underlying_symbol(str): 期货品种,如'IF','IC','IH','AG','AU'date(str/datetime, optional): 查询日期
get_dominant_future()
获取主力合约。
get_dominant_future(underlying_symbol=None, date=None, end_date=None)get_order_future_bar()
获取连续合约行情。
get_order_future_bar(symbol, future_type, start_dt, end_dt,
unit='1d', fields=None, include_now=True)参数:
symbol(str): 品种代码future_type(str): 合约类型,'0'当月,'1'次月,'0q'当季,'1q'次季
---
因子数据
因子分类
聚宽提供多种类型的因子数据:
1. 估值因子
- 市值(market_cap, circulating_market_cap)
- 估值比率(pe_ratio, pb_ratio, ps_ratio, pcf_ratio)
2. 技术因子
- 均线(MA)
- 动量(Momentum)
- 波动率(Volatility)
- 振幅(Amplitude)
3. 成长因子
- 营业收入增长率(inc_revenue_year_on_year)
- 净利润增长率(net_profit_growth_rate)
- ROE增长率(roe_yearly)
4. 情绪因子
- 换手率(turnover_ratio)
- 量比
5. 规模因子
- 总市值
- 流通市值
get_factor_values()
获取因子数据。
get_factor_values(securities, factors, start_date=None, end_date=None, count=None)参数:
securities(str/list): 证券代码factors(list): 因子名称列表start_date(str/datetime, optional): 开始日期end_date(str/datetime, optional): 结束日期count(int, optional): 数据条数
返回: dict,key为因子名,value为DataFrame
get_all_factors()
获取所有可用因子。
get_all_factors() -> DataFrameget_factor_kanban_values()
获取因子面板数据。
get_factor_kanban_values(universe=None, bt_cycle=None, category=None, model='long_only', **kwargs)参数:
universe(str): 股票池,'hs300','zz500','zz800','zz1000','zzqz'bt_cycle(str): 周期,'month_3','year_1','year_3','year_10'category(str): 分类,'basics','quality','emotion','growth','risk','technical','momentum'model(str):'long_only'或'long_short'
get_factor_style_returns()
获取风格因子暴露收益率。
get_factor_style_returns(factors=None, start_date=None, end_date=None,
count=None, universe=None, industry='sw_l1')get_factor_stats()
获取因子历史收益统计。
get_factor_stats(factor_names=None, universe_type='hs300',
start_date=None, end_date=None, count=None,
skip_paused=False, commision_fee=0.0)因子数据获取示例
from jqdatasdk import finance, query
# 获取估值因子
q = query(finance.valuation.code,
finance.valuation.day,
finance.valuation.market_cap,
finance.valuation.pe_ratio,
finance.valuation.pb_ratio)
q = q.filter(finance.valuation.code == '000001.XSHE')
q = q.filter(finance.valuation.day >= '2024-01-01')
df = finance.run_query(q)
# 获取成长因子
q = query(finance.indicator.code,
finance.indicator.statDate,
finance.indicator.inc_revenue_year_on_year,
finance.indicator.roe)
q = q.filter(finance.indicator.code == '000001.XSHE')
df = finance.run_query(q)自定义因子计算
对于聚宽未直接提供的因子,可以通过基础数据计算:
import pandas as pd
import jqdatasdk as jq
# 获取价格数据
df = jq.get_price('000001.XSHE',
start_date='2024-01-01',
end_date='2024-03-31',
frequency='daily')
# 计算动量因子
df = df.reset_index()
df['momentum_20'] = df['close'].pct_change(20) * 100
df['momentum_60'] = df['close'].pct_change(60) * 100
# 计算波动率因子
df['volatility_20'] = df['close'].pct_change().rolling(window=20).std() * 100
# 计算RSI指标
def calculate_rsi(series, period=14):
delta = series.diff()
gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
rs = gain / loss
rsi = 100 - (100 / (1 + rs))
return rsi
df['rsi_14'] = calculate_rsi(df['close'])---
Alpha因子
get_all_alpha_101()
获取 Alpha101 因子。
get_all_alpha_101(date, code=None, alpha=None) -> DataFrameget_all_alpha_191()
获取 Alpha191 因子。
get_all_alpha_191(date, code=None, alpha=None) -> DataFrame---
其他接口
get_trade_days()
获取交易日列表。
get_trade_days(start_date=None, end_date=None, count=None) -> ndarray示例:
trade_days = jq.get_trade_days(start_date='2024-01-01', end_date='2024-12-31')get_all_trade_days()
获取所有交易日。
get_all_trade_days() -> ndarrayget_billboard_list()
获取龙虎榜数据。
get_billboard_list(stock_list=None, start_date=None, end_date=None, count=None)get_locked_shares()
获取限售股解禁数据。
get_locked_shares(stock_list=None, start_date=None, end_date=None, forward_count=None)get_table_info()
查询数据表字段信息。
get_table_info(table) -> DataFrame参数:
table(str/ORM): 表名或 ORM 对象
get_preopen_infos()
获取盘前交易信息。
get_preopen_infos(security, fields=("paused", "factor", "high_limit", "low_limit"))get_query_count()
查询剩余请求条数。
get_query_count(field=None)参数:
field(str, optional):'total'或'spare'
示例:
count_info = jq.get_query_count()
print(f"已用: {count_info['spare']}")
print(f"总计: {count_info['total']}")
print(f"剩余: {count_info['total'] - count_info['spare']}")---
财务表字段参考
finance.indicator (财务指标表)
| 字段 | 说明 |
|---|---|
| code | 股票代码 |
| pub_date | 发布日期 |
| end_date | 报告期结束日期 |
| eps | 每股收益 |
| eps_yoy | 每股收益同比(%) |
| bvps | 每股净资产 |
| roe | 净资产收益率(%) |
| roe_yoy | 净资产收益率同比(%) |
| net_profits | 净利润(万元) |
| net_profits_yoy | 净利润同比(%) |
| revenue | 营业收入(万元) |
| revenue_yoy | 营业收入同比(%) |
| total_assets | 总资产(万元) |
| total_liab | 总负债(万元) |
| gross_profit | 毛利率(%) |
| net_profit_margin | 净利率(%) |
finance.balance (资产负债表)
| 字段 | 说明 |
|---|---|
| code | 股票代码 |
| end_date | 报告期结束日期 |
| total_assets | 资产总计 |
| total_liab | 负债合计 |
| total_hldr_eqy_excl_min_int_shares | 归属于母公司股东权益 |
| total_hldr_eqy | 股东权益合计 |
finance.income (利润表)
| 字段 | 说明 |
|---|---|
| code | 股票代码 |
| end_date | 报告期结束日期 |
| total_revenue | 营业收入 |
| oper_cost | 营业成本 |
| total_operate_income | 营业利润 |
| net_profit | 净利润 |
finance.cash_flow (现金流量表)
| 字段 | 说明 |
|---|---|
| code | 股票代码 |
| end_date | 报告期结束日期 |
| oper_cash_flow | 经营活动产生的现金流量净额 |
| invest_cash_flow | 投资活动产生的现金流量净额 |
| fin_cash_flow | 筹资活动产生的现金流量净额 |
---
错误处理
常见错误
| 错误类型 | 说明 | 解决方法 |
|---|---|---|
| AuthError | 认证失败 | 检查 Token 或账号密码是否正确 |
| QueryCountExceeded | 调用次数超限 | 查看剩余次数,减少请求 |
| InvalidSecurity | 证券代码无效 | 检查代码格式(如 000001.XSHE) |
| NoData | 无数据 | 检查日期范围和代码 |
错误处理示例
from jqdatasdk import AuthError
try:
jq.auth('你的Token', '你的Token')
df = jq.get_price('000001.XSHE',
start_date='2024-01-01',
end_date='2024-01-31')
except AuthError:
print("认证失败,请检查 Token")
except Exception as e:
print(f"错误: {e}")jqdatasdk 快速开始
目录
概览
jqdatasdk 是聚宽提供的 Python 数据接口,用于获取 A 股、基金、期货等金融数据。它支持实时行情、历史数据、财务数据、因子数据等多种数据类型。
核心特点:
- 官方支持,数据质量高
- 覆盖 A 股、基金、期货等全品种
- 提供财务数据、因子数据等深度数据
- 支持实时行情和历史数据
安装与配置
1. 安装 Python 依赖
pip install jqdatasdk>=1.9.0 pandas>=1.3.02. 注册聚宽账号
访问 https://www.joinquant.com/ 注册账号。
3. 获取 API Token
1. 登录聚宽官网 2. 进入"个人中心"或"设置" 3. 找到"API Token"或"聚宽数据接口"选项 4. 点击"复制"获取你的 Token
注意: Token 相当于账号密码,请妥善保管,不要泄露给他人。
认证配置
使用 Skill 凭证配置
本 Skill 已集成凭证管理功能,首次使用时会提示配置环境变量 JQDATA_TOKEN 凭证。
配置步骤: 1. 当智能体调用脚本时,如果检测到未配置凭证,会弹出凭证配置窗口 2. 将你从聚宽官网复制的 Token 粘贴到输入框 3. 凭证配置完成后,脚本会自动读取并使用
手动认证方式
如果在本地测试,可以使用以下方式:
import jqdatasdk as jq
# 使用账号密码认证
jq.auth('你的用户名', '你的密码')
# 或者使用 Token 认证(推荐)
jq.auth('你的Token', '你的Token')
# 检查是否认证成功
print(jq.get_query_count())认证状态检查
# 查看剩余调用次数
count_info = jq.get_query_count()
print(f"剩余查询次数: {count_info['total'] - count_info['spare']}")
print(f"当日总查询次数: {count_info['total']}")基础用法
1. 获取股票列表
import jqdatasdk as jq
jq.auth('你的Token', '你的Token')
# 获取所有股票
stocks = jq.get_all_securities(['stock'])
print(stocks.head())
# 获取所有基金
funds = jq.get_all_securities(['fund'])
print(funds.head())
# 获取所有指数
indices = jq.get_all_securities(['index'])
print(indices.head())2. 获取价格数据
# 获取单只股票日线数据
df = jq.get_price('000001.XSHE',
start_date='2024-01-01',
end_date='2024-01-31',
frequency='daily')
print(df)
# 获取多只股票日线数据
codes = ['000001.XSHE', '600000.XSHG', '300001.XSHE']
df = jq.get_price(codes,
start_date='2024-01-01',
end_date='2024-01-31',
frequency='daily')
print(df)
# 获取分钟线数据
df = jq.get_price('000001.XSHE',
start_date='2024-01-01',
end_date='2024-01-02',
frequency='1min')
print(df)支持的频率:
- 分钟线:1min, 5min, 15min, 30min, 60min, 120min
- 日线:daily
- 周线:weekly
- 月线:monthly
3. 获取财务数据
# 查询财务数据
from jqdatasdk import finance
query = finance.query(finance.STK_BALANCE_SHEET.code,
finance.STK_BALANCE_SHEET.statDate,
finance.STK_BALANCE_SHEET.total_assets)
query = query.filter(finance.STK_BALANCE_SHEET.code == '000001.XSHE')
query = query.filter(finance.STK_BALANCE_SHEET.statDate == '2023')
df = finance.run_query(query)
print(df)
# 查询指标数据
query = finance.query(finance.indicator.code,
finance.indicator.statDate,
finance.indicator.roe,
finance.indicator.pe_ratio)
query = query.filter(finance.indicator.code == '000001.XSHE')
df = finance.run_query(query)
print(df)
# 查询估值数据
query = finance.query(finance.valuation.code,
finance.valuation.day,
finance.valuation.market_cap,
finance.valuation.pe_ratio)
query = query.filter(finance.valuation.code == '000001.XSHE')
df = finance.run_query(query)
print(df)4. 获取实时数据
# 获取实时数据
data = jq.get_current_data()
print(data)
# 获取指定股票实时数据
if '000001.XSHE' in data:
print(f"最新价: {data['000001.XSHE'].last_price}")
print(f"成交量: {data['000001.XSHE'].volume}")5. 获取 Tick 数据
# 获取 Tick 数据
ticks = jq.get_ticks(security='000001.XSHE',
start_dt='2024-01-01',
end_dt='2024-01-01')
for tick in ticks:
print(f"{tick.time} 价格:{tick.price} 成交量:{tick.volume}")常见问题
Q1: 认证失败怎么办?
可能原因: 1. Token 输入错误 2. 账号未开通聚宽数据服务 3. Token 已过期
解决方法:
- 检查 Token 是否正确复制
- 登录聚宽官网确认账号状态
- 重新生成 Token
Q2: 调用次数限制?
聚宽对不同类型的账号有不同的调用限制:
- 免费账号:每日约 100 万次调用
- 付费账号:更高的调用限制
查看剩余次数:
count_info = jq.get_query_count()
print(count_info)Q3: 数据为空或错误?
检查项: 1. 股票代码格式是否正确(XXXXXX.XSHG 或 XXXXXX.XSHE) 2. 日期范围是否合理 3. 是否在交易时间内(实时数据) 4. 数据是否有延迟
Q4: 支持哪些市场?
- ✅ A 股(上海、深圳)
- ✅ 基金
- ✅ 指数
- ✅ 期货
- ✅ 期权(部分)
Q5: 如何获取最新数据?
实时数据:
data = jq.get_current_data()最新收盘价:
df = jq.get_price('000001.XSHE', end_date=None, count=1)Q6: 复权价格如何获取?
# 前复权(默认)
df = jq.get_price('000001.XSHE',
start_date='2024-01-01',
end_date='2024-01-31',
fq_ref_date='2024-01-31')
# 后复权
df = jq.get_price('000001.XSHE',
start_date='2024-01-01',
end_date='2024-01-31',
fq_ref_date='2024-01-01')
# 不复权
df = jq.get_price('000001.XSHE',
start_date='2024-01-01',
end_date='2024-01-31',
fq_ref_date=None)Q7: 如何提高数据获取效率?
- 使用批量接口一次获取多只股票
- 合理设置日期范围,避免一次性获取过多数据
- 使用本地缓存减少重复请求
- 优先使用日线数据,分钟线数据获取较慢
Q8: 数据延迟说明?
- 实时行情:接近实时(毫秒级延迟)
- 日线数据:T+1(交易日收盘后可用)
- 财务数据:根据财报发布时间延迟
- 指标数据:T+1 或更长时间
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
聚宽数据SDK认证模块
支持用户名密码和Token两种认证方式
支持自定义 host 和 port
"""
import json
import sys
import os
def auth_jq():
"""
认证并返回已认证的 jqdatasdk 模块
环境变量优先级:
1. JQDATA_USERNAME + JQDATA_PASSWORD (用户名密码方式)
2. JQDATA_TOKEN (Token方式)
可选环境变量:
- JQDATA_HOST: 自定义服务器地址
- JQDATA_PORT: 自定义端口
Returns:
module: 已认证的 jqdatasdk 模块
Exits:
如果认证失败,输出JSON错误信息并退出
"""
try:
import jqdatasdk as jq
except ImportError:
print(json.dumps({
'status': 'error',
'message': 'jqdatasdk 库未安装,请先安装: pip install jqdatasdk'
}, ensure_ascii=False))
sys.exit(1)
# 获取可选的 host 和 port 配置
host = os.getenv('JQDATA_HOST') or None
port = os.getenv('JQDATA_PORT') or None
if port:
try:
port = int(port)
except ValueError:
print(json.dumps({
'status': 'error',
'message': f'JQDATA_PORT 必须是有效的端口号: {port}'
}, ensure_ascii=False))
sys.exit(1)
# 优先使用用户名密码方式
username = os.getenv('JQDATA_USERNAME')
password = os.getenv('JQDATA_PASSWORD')
if username and password:
try:
jq.auth(username, password, host=host, port=port)
return jq
except Exception as e:
print(json.dumps({
'status': 'error',
'message': f'聚宽认证失败(用户名密码方式): {str(e)}'
}, ensure_ascii=False))
sys.exit(1)
# 回退到Token方式,使用正确的 auth_by_token 方法
token = os.getenv('JQDATA_TOKEN')
if token:
try:
jq.auth_by_token(token, host=host, port=port)
return jq
except Exception as e:
print(json.dumps({
'status': 'error',
'message': f'聚宽认证失败(Token方式): {str(e)}'
}, ensure_ascii=False))
sys.exit(1)
# 两种认证方式都未配置
print(json.dumps({
'status': 'error',
'message': '缺少聚宽认证凭证,请配置以下任一方式: \n1. JQDATA_USERNAME + JQDATA_PASSWORD (推荐)\n2. JQDATA_TOKEN'
}, ensure_ascii=False))
sys.exit(1)
if __name__ == '__main__':
# 测试认证
jq = auth_jq()
print(json.dumps({
'status': 'success',
'message': '聚宽认证成功'
}, ensure_ascii=False))
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
因子数据获取脚本
支持获取估值因子、情绪因子、技术因子、成长因子等
"""
import argparse
import json
import sys
import os
from datetime import datetime, timedelta
# 添加脚本目录到 Python 路径,支持独立运行
script_dir = os.path.dirname(os.path.abspath(__file__))
if script_dir not in sys.path:
sys.path.insert(0, script_dir)
# 导入认证模块
from auth import auth_jq
def main():
parser = argparse.ArgumentParser(description='获取聚宽因子数据')
parser.add_argument('--code', required=True, help='股票代码,格式: 000001.XSHE 或 600000.XSHG,多个用逗号分隔')
parser.add_argument('--factor', required=True,
choices=['valuation', 'turnover', 'basic', 'technical', 'growth', 'momentum', 'size'],
help='因子类型: valuation-估值, turnover-换手率, basic-基础, technical-技术, growth-成长, momentum-动量, size-规模')
parser.add_argument('--start', help='开始日期,格式YYYY-MM-DD,如 2024-01-01')
parser.add_argument('--end', help='结束日期,格式YYYY-MM-DD,如 2024-12-31')
args = parser.parse_args()
try:
# 使用统一认证模块进行认证
jq = auth_jq()
# 设置默认日期范围
if not args.start:
args.start = (datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d')
if not args.end:
args.end = datetime.now().strftime('%Y-%m-%d')
codes = args.code.split(',')
result = {
'status': 'success',
'factor_type': args.factor,
'code': args.code,
'start_date': args.start,
'end_date': args.end,
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
if args.factor == 'valuation':
# 估值因子
query = jq.query(jq.valuation.code,
jq.valuation.day,
jq.valuation.market_cap,
jq.valuation.circulating_market_cap,
jq.valuation.pe_ratio,
jq.valuation.pb_ratio,
jq.valuation.pcf_ratio,
jq.valuation.ps_ratio,
jq.valuation.turnover_ratio)
query = query.filter(jq.valuation.code.in_(codes))
query = query.filter(jq.valuation.day >= args.start)
query = query.filter(jq.valuation.day <= args.end)
df = jq.finance.run_query(query)
if df is not None and not df.empty:
result['data'] = df.to_dict('records')
result['count'] = len(df)
else:
result['data'] = []
result['count'] = 0
elif args.factor == 'turnover':
# 换手率因子
query = jq.query(jq.valuation.code,
jq.valuation.day,
jq.valuation.turnover_ratio,
jq.valuation.circulating_market_cap)
query = query.filter(jq.valuation.code.in_(codes))
query = query.filter(jq.valuation.day >= args.start)
query = query.filter(jq.valuation.day <= args.end)
df = jq.finance.run_query(query)
if df is not None and not df.empty:
result['data'] = df.to_dict('records')
result['count'] = len(df)
else:
result['data'] = []
result['count'] = 0
elif args.factor == 'basic':
# 基础因子
query = jq.query(jq.valuation.code,
jq.valuation.day,
jq.valuation.market_cap,
jq.valuation.circulating_market_cap,
jq.valuation.pe_ratio,
jq.valuation.pb_ratio)
query = query.filter(jq.valuation.code.in_(codes))
query = query.filter(jq.valuation.day >= args.start)
query = query.filter(jq.valuation.day <= args.end)
df = jq.finance.run_query(query)
if df is not None and not df.empty:
result['data'] = df.to_dict('records')
result['count'] = len(df)
else:
result['data'] = []
result['count'] = 0
elif args.factor == 'technical':
# 技术因子(通过价格数据计算)
prices = jq.get_price(
security=codes,
start_date=args.start,
end_date=args.end,
frequency='daily',
fields=['open', 'close', 'high', 'low', 'volume', 'money']
)
if prices is not None and not prices.empty:
# 计算简单技术指标
import pandas as pd
df = prices.reset_index()
# 按代码分组计算
result_list = []
for code in codes:
code_df = df[df['code'] == code].copy()
if not code_df.empty:
code_df = code_df.sort_values('time')
# 计算5日、20日移动平均
code_df['ma5'] = code_df['close'].rolling(window=5).mean()
code_df['ma20'] = code_df['close'].rolling(window=20).mean()
# 计算振幅
code_df['amplitude'] = (code_df['high'] - code_df['low']) / code_df['close'] * 100
# 计算涨跌幅
code_df['change_pct'] = code_df['close'].pct_change() * 100
result_list.extend(code_df.to_dict('records'))
result['data'] = result_list
result['count'] = len(result_list)
else:
result['data'] = []
result['count'] = 0
elif args.factor == 'growth':
# 成长因子(需要财务数据)
query = jq.query(jq.indicator.code,
jq.indicator.statDate,
jq.indicator.inc_return,
jq.indicator.inc_revenue_year_on_year,
jq.indicator.roe)
query = query.filter(jq.indicator.code.in_(codes))
if args.start:
query = query.filter(jq.indicator.statDate >= args.start.replace('-', ''))
if args.end:
query = query.filter(jq.indicator.statDate <= args.end.replace('-', ''))
df = jq.finance.run_query(query)
if df is not None and not df.empty:
result['data'] = df.to_dict('records')
result['count'] = len(df)
else:
result['data'] = []
result['count'] = 0
elif args.factor == 'momentum':
# 动量因子(通过价格数据计算)
prices = jq.get_price(
security=codes,
start_date=args.start,
end_date=args.end,
frequency='daily',
fields=['close', 'volume']
)
if prices is not None and not prices.empty:
import pandas as pd
df = prices.reset_index()
result_list = []
for code in codes:
code_df = df[df['code'] == code].copy()
if not code_df.empty:
code_df = code_df.sort_values('time')
# 计算5日、20日、60日收益率
code_df['return_5d'] = code_df['close'].pct_change(5) * 100
code_df['return_20d'] = code_df['close'].pct_change(20) * 100
code_df['return_60d'] = code_df['close'].pct_change(60) * 100
# 计算波动率
code_df['volatility'] = code_df['close'].pct_change().rolling(window=20).std() * 100
result_list.extend(code_df.to_dict('records'))
result['data'] = result_list
result['count'] = len(result_list)
else:
result['data'] = []
result['count'] = 0
elif args.factor == 'size':
# 规模因子
query = jq.query(jq.valuation.code,
jq.valuation.day,
jq.valuation.market_cap,
jq.valuation.circulating_market_cap)
query = query.filter(jq.valuation.code.in_(codes))
query = query.filter(jq.valuation.day >= args.start)
query = query.filter(jq.valuation.day <= args.end)
df = jq.finance.run_query(query)
if df is not None and not df.empty:
result['data'] = df.to_dict('records')
result['count'] = len(df)
else:
result['data'] = []
result['count'] = 0
print(json.dumps(result, ensure_ascii=False, indent=2))
except ImportError:
print(json.dumps({
'status': 'error',
'message': 'jqdatasdk 库未安装,请先安装: pip install jqdatasdk'
}, ensure_ascii=False))
sys.exit(1)
except Exception as e:
print(json.dumps({
'status': 'error',
'message': str(e),
'error_type': type(e).__name__
}, ensure_ascii=False))
sys.exit(1)
if __name__ == '__main__':
main()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
财务数据获取脚本
支持获取财务数据、指标数据、估值数据
"""
import argparse
import json
import sys
import os
from datetime import datetime
# 添加脚本目录到 Python 路径,支持独立运行
script_dir = os.path.dirname(os.path.abspath(__file__))
if script_dir not in sys.path:
sys.path.insert(0, script_dir)
# 导入认证模块
from auth import auth_jq
def main():
parser = argparse.ArgumentParser(description='获取聚宽财务数据')
parser.add_argument('--type', required=True, choices=['fundamentals', 'indicators', 'valuation'],
help='数据类型: fundamentals-财务数据, indicators-指标数据, valuation-估值数据')
parser.add_argument('--code', required=True, help='股票代码,格式: 000001.XSHE 或 600000.XSHG,多个用逗号分隔')
parser.add_argument('--statDate', help='报告期,格式YYYY或YYYY-MM-DD,如 2024 或 2024-03-31')
parser.add_argument('--columns', help='字段列表,逗号分隔,如 pe_ratio, pb_ratio')
args = parser.parse_args()
try:
# 使用统一认证模块进行认证
jq = auth_jq()
result = {
'status': 'success',
'data_type': args.type,
'code': args.code,
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
codes = args.code.split(',')
if args.type == 'fundamentals':
# 财务数据
query = jq.query(jq.finance.STK_BALANCE_SHEET)
if args.statDate:
query = query.filter(jq.finance.STK_BALANCE_SHEET.statDate == args.statDate)
query = query.filter(jq.finance.STK_BALANCE_SHEET.code.in_(codes))
if args.columns:
columns = args.columns.split(',')
query = query.filter(*[getattr(jq.finance.STK_BALANCE_SHEET, col) != None for col in columns])
df = jq.finance.run_query(query)
if df is not None and not df.empty:
result['data'] = df.to_dict('records')
result['count'] = len(df)
else:
result['data'] = []
result['count'] = 0
elif args.type == 'indicators':
# 指标数据
query = jq.query(jq.indicator)
if args.statDate:
query = query.filter(jq.indicator.statDate == args.statDate)
query = query.filter(jq.indicator.code.in_(codes))
df = jq.finance.run_query(query)
if df is not None and not df.empty:
result['data'] = df.to_dict('records')
result['count'] = len(df)
else:
result['data'] = []
result['count'] = 0
elif args.type == 'valuation':
# 估值数据
query = jq.query(jq.valuation)
if args.statDate:
query = query.filter(jq.valuation.day == args.statDate)
else:
# 获取最新估值数据
query = query.order_by(jq.valuation.day.desc())
query = query.filter(jq.valuation.code.in_(codes))
if args.columns:
selected_columns = ['code', 'day'] + args.columns.split(',')
df = jq.finance.run_query(query)
if df is not None and not df.empty:
df = df[selected_columns]
else:
df = jq.finance.run_query(query)
if df is not None and not df.empty:
result['data'] = df.to_dict('records')
result['count'] = len(df)
else:
result['data'] = []
result['count'] = 0
print(json.dumps(result, ensure_ascii=False, indent=2))
except ImportError:
print(json.dumps({
'status': 'error',
'message': 'jqdatasdk 库未安装,请先安装: pip install jqdatasdk'
}, ensure_ascii=False))
sys.exit(1)
except Exception as e:
print(json.dumps({
'status': 'error',
'message': str(e),
'error_type': type(e).__name__
}, ensure_ascii=False))
sys.exit(1)
if __name__ == '__main__':
main()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
行情数据获取脚本
支持获取价格、K线、实时数据、Tick数据
"""
import argparse
import json
import sys
import os
from datetime import datetime, timedelta
# 添加脚本目录到 Python 路径,支持独立运行
script_dir = os.path.dirname(os.path.abspath(__file__))
if script_dir not in sys.path:
sys.path.insert(0, script_dir)
# 导入认证模块
from auth import auth_jq
def main():
parser = argparse.ArgumentParser(description='获取聚宽A股行情数据')
parser.add_argument('--type', required=True, choices=['price', 'current', 'ticks', 'order', 'future_ticks'],
help='数据类型: price-价格/K线, current-实时数据, ticks-Tick, order-委托, future_ticks-期货Tick')
parser.add_argument('--code', required=True, help='股票代码,格式: 000001.XSHE 或 600000.XSHG')
parser.add_argument('--start', help='开始日期,格式YYYY-MM-DD,如 2024-01-01')
parser.add_argument('--end', help='结束日期,格式YYYY-MM-DD,如 2024-01-31')
parser.add_argument('--frequency', default='daily',
choices=['1min', '5min', '15min', '30min', '60min', '120min', 'daily', 'weekly', 'monthly'],
help='数据频率,默认daily')
parser.add_argument('--count', type=int, default=100, help='获取数量,默认100')
parser.add_argument('--fields', help='字段列表,逗号分隔,如 open,close,high,low,volume')
args = parser.parse_args()
try:
# 使用统一认证模块进行认证
jq = auth_jq()
result = {
'status': 'success',
'data_type': args.type,
'code': args.code,
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
if args.type == 'price':
if not args.start:
args.end = datetime.now().strftime('%Y-%m-%d')
args.start = (datetime.now() - timedelta(days=args.count)).strftime('%Y-%m-%d')
# 默认字段
default_fields = ['open', 'close', 'high', 'low', 'volume', 'money']
fields = args.fields.split(',') if args.fields else default_fields
data = jq.get_price(
security=args.code,
start_date=args.start,
end_date=args.end,
frequency=args.frequency,
fields=fields
)
if data is not None and not data.empty:
result['data'] = data.reset_index().to_dict('records')
result['count'] = len(data)
else:
result['data'] = []
result['count'] = 0
elif args.type == 'current':
if ',' in args.code:
codes = args.code.split(',')
data = jq.get_current_data()
result['data'] = []
if isinstance(data, dict):
for code in codes:
if code in data:
result['data'].append({
'code': code,
'last_price': data[code].last_price,
'time': data[code].time.strftime('%Y-%m-%d %H:%M:%S') if hasattr(data[code].time, 'strftime') else str(data[code].time),
'day_open': data[code].day_open,
'day_high': data[code].day_high,
'day_low': data[code].day_low,
'volume': data[code].volume,
'money': data[code].money
})
result['count'] = len(result['data'])
else:
data = jq.get_current_data()
if isinstance(data, dict) and args.code in data:
result['data'] = {
'code': args.code,
'last_price': data[args.code].last_price,
'time': data[args.code].time.strftime('%Y-%m-%d %H:%M:%S') if hasattr(data[args.code].time, 'strftime') else str(data[args.code].time),
'day_open': data[args.code].day_open,
'day_high': data[args.code].day_high,
'day_low': data[args.code].day_low,
'volume': data[args.code].volume,
'money': data[args.code].money
}
else:
result['error'] = f'未获取到股票 {args.code} 的实时数据'
elif args.type == 'ticks':
if not args.start:
args.end = datetime.now().strftime('%Y-%m-%d')
args.start = args.end
data = jq.get_ticks(
security=args.code,
start_dt=args.start,
end_dt=args.end
)
tick_data = []
if data:
for tick in data:
tick_data.append({
'time': tick.time.strftime('%Y-%m-%d %H:%M:%S') if hasattr(tick.time, 'strftime') else str(tick.time),
'price': tick.price,
'volume': tick.volume,
'amount': tick.amount,
'direction': tick.direction if hasattr(tick, 'direction') else ''
})
result['ticks'] = tick_data
result['count'] = len(tick_data)
elif args.type == 'order':
if not args.start:
args.end = datetime.now().strftime('%Y-%m-%d')
args.start = args.end
data = jq.get_order_book(
security=args.code,
start_dt=args.start,
end_dt=args.end
)
order_data = []
if data:
for order in data:
order_data.append({
'time': order.time.strftime('%Y-%m-%d %H:%M:%S') if hasattr(order.time, 'strftime') else str(order.time),
'b_p_1': getattr(order, 'b_p_1', 0),
'b_v_1': getattr(order, 'b_v_1', 0),
'a_p_1': getattr(order, 'a_p_1', 0),
'a_v_1': getattr(order, 'a_v_1', 0),
'b_p_2': getattr(order, 'b_p_2', 0),
'b_v_2': getattr(order, 'b_v_2', 0),
'a_p_2': getattr(order, 'a_p_2', 0),
'a_v_2': getattr(order, 'a_v_2', 0),
'b_p_3': getattr(order, 'b_p_3', 0),
'b_v_3': getattr(order, 'b_v_3', 0),
'a_p_3': getattr(order, 'a_p_3', 0),
'a_v_3': getattr(order, 'a_v_3', 0)
})
result['orders'] = order_data
result['count'] = len(order_data)
elif args.type == 'future_ticks':
if not args.start:
args.end = datetime.now().strftime('%Y-%m-%d')
args.start = args.end
data = jq.get_future_ticks(
security=args.code,
start_dt=args.start,
end_dt=args.end
)
tick_data = []
if data:
for tick in data:
tick_data.append({
'time': tick.time.strftime('%Y-%m-%d %H:%M:%S') if hasattr(tick.time, 'strftime') else str(tick.time),
'price': tick.price,
'volume': tick.volume,
'amount': tick.amount
})
result['ticks'] = tick_data
result['count'] = len(tick_data)
print(json.dumps(result, ensure_ascii=False, indent=2))
except ImportError:
print(json.dumps({
'status': 'error',
'message': 'jqdatasdk 库未安装,请先安装: pip install jqdatasdk'
}, ensure_ascii=False))
sys.exit(1)
except Exception as e:
print(json.dumps({
'status': 'error',
'message': str(e),
'error_type': type(e).__name__
}, ensure_ascii=False))
sys.exit(1)
if __name__ == '__main__':
main()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
股票信息获取脚本
支持获取股票列表、股票信息、基金列表等
"""
import argparse
import json
import sys
import os
from datetime import datetime
# 添加脚本目录到 Python 路径,支持独立运行
script_dir = os.path.dirname(os.path.abspath(__file__))
if script_dir not in sys.path:
sys.path.insert(0, script_dir)
# 导入认证模块
from auth import auth_jq
def main():
parser = argparse.ArgumentParser(description='获取聚宽股票信息')
parser.add_argument('--type', required=True, choices=['all_securities', 'get_security_info', 'trade_days'],
help='类型: all_securities-获取证券列表, get_security_info-获取证券信息, trade_days-获取交易日')
parser.add_argument('--security_type', default='stock',
choices=['stock', 'fund', 'index', 'etf', 'futures', 'all'],
help='证券类型,默认stock')
parser.add_argument('--code', help='证券代码,格式: 000001.XSHE 或 600000.XSHG')
parser.add_argument('--start', help='开始日期,格式YYYY-MM-DD,如 2024-01-01')
parser.add_argument('--end', help='结束日期,格式YYYY-MM-DD,如 2024-12-31')
args = parser.parse_args()
try:
# 使用统一认证模块进行认证
jq = auth_jq()
result = {
'status': 'success',
'data_type': args.type,
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
if args.type == 'all_securities':
# 获取证券列表
if args.security_type == 'all':
securities = jq.get_all_securities()
else:
securities = jq.get_all_securities(types=[args.security_type])
if securities is not None and not securities.empty:
result['data'] = securities.reset_index().to_dict('records')
result['count'] = len(securities)
else:
result['data'] = []
result['count'] = 0
elif args.type == 'get_security_info':
if not args.code:
result['error'] = '请提供 --code 参数'
else:
info = jq.get_security_info(args.code)
if info:
result['data'] = {
'code': info.code,
'display_name': info.display_name,
'name': info.name,
'start_date': info.start_date.strftime('%Y-%m-%d') if hasattr(info.start_date, 'strftime') else str(info.start_date),
'end_date': info.end_date.strftime('%Y-%m-%d') if info.end_date and hasattr(info.end_date, 'strftime') else str(info.end_date) if info.end_date else None,
'type': info.type,
'parent': info.parent
}
else:
result['error'] = f'未找到证券 {args.code} 的信息'
elif args.type == 'trade_days':
if not args.start or not args.end:
result['error'] = '请提供 --start 和 --end 参数'
else:
trade_days = jq.get_trade_days(start_date=args.start, end_date=args.end)
result['trade_days'] = [day.strftime('%Y-%m-%d') for day in trade_days] if trade_days else []
result['count'] = len(result['trade_days']) if result['trade_days'] else 0
print(json.dumps(result, ensure_ascii=False, indent=2))
except ImportError:
print(json.dumps({
'status': 'error',
'message': 'jqdatasdk 库未安装,请先安装: pip install jqdatasdk'
}, ensure_ascii=False))
sys.exit(1)
except Exception as e:
print(json.dumps({
'status': 'error',
'message': str(e),
'error_type': type(e).__name__
}, ensure_ascii=False))
sys.exit(1)
if __name__ == '__main__':
main()