请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  量化平台 帖子:3352754 新帖:29

【有用功】Query的简单教程及TTM/同比/环比算法

只求稳定发表于:7 月 1 日 12:49回复(1)

对于数据的查询过滤,一般通过filter函数进行实现,filter可以对多个条件进行过滤,中间用,隔开。
比如查询某只股票某一个时间段,满足特定值的数据,可以用到 in_ ,and_,> , < , == ,!=等符号进行基本的查询


涉及到使用数据库操作的数据有:

  • get_fundamentals  (股票单季度财务数据)

  • finance           (股票数据,基金数据等)

  • opt               (期权数据)

  • macro             (宏观数据)

  • jy                (聚源数据)

基本的查询方式¶

  • query()  填写需要查询的对象,可以是整张表,也可以是表中的多个字段或计算出的结果

  • filter 填写过滤条件,多个过滤条件可以用逗号隔开,或者用and,or这样的语法

  • order_by  填写排序条件

    • .desc()  降序排列

    • .asc()   升序排列

  • limit   限制返回的个数

  • order_by  分组统计

# 查询 000001 2015 - 2017 年的整张合并利润表,且满足 net_profit(净利润) < 0 的条件from jqdata import financeq = query(finance.STK_INCOME_STATEMENT).filter(finance.STK_INCOME_STATEMENT.code=='000783.XSHE',              #选定股票  000783.XSHEfinance.STK_INCOME_STATEMENT.end_date > '2005-01-01',          #指定查询时间段大于2005年1月1日finance.STK_INCOME_STATEMENT.end_date < '2018-01-01',          #指定查询时间段小于2018年1月1日finance.STK_INCOME_STATEMENT.net_profit <0,                    #指定查询到的数据中net_profit为负finance.STK_INCOME_STATEMENT.report_type == 0,                 #指定报告期类型为本期).order_by(finance.STK_INCOME_STATEMENT.end_date.desc()  ).limit(5)   #根据end_date降序排序,并返回前5条数据 finance.run_query(q)

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


idcompany_idcompany_namecodea_codeb_codeh_codepub_datestart_dateend_date...commission_incomeinterest_expensecommission_expenserefunded_premiumsnet_pay_insurance_claimswithdraw_insurance_contract_reservepolicy_dividend_payoutreinsurance_costnon_current_asset_disposedother_earnings
0257078430000783长江证券股份有限公司000783.XSHE000783NoneNone2007-10-222007-01-012007-09-30...NoneNoneNoneNoneNoneNoneNoneNoneNoneNone
1257070430000783长江证券股份有限公司000783.XSHE000783NoneNone2006-10-252006-01-012006-09-30...NoneNoneNoneNoneNoneNoneNoneNoneNoneNone
2257068430000783长江证券股份有限公司000783.XSHE000783NoneNone2006-08-172006-01-012006-06-30...NoneNoneNoneNoneNoneNoneNoneNoneNoneNone
3257066430000783长江证券股份有限公司000783.XSHE000783NoneNone2006-04-292006-01-012006-03-31...NoneNoneNoneNoneNoneNoneNoneNoneNoneNone
4257064430000783长江证券股份有限公司000783.XSHE000783NoneNone2006-04-292005-01-012005-12-31...NoneNoneNoneNoneNoneNoneNoneNoneNoneNone

5 rows × 60 columns

get_fundamentals 获取某个/多个季度/年度的数据(指定参数statDate)¶

# 查询平安银行2014年3-6月份的单季度报表q = query(  income.statDate,  income.code,  income.basic_eps,  cash_flow.goods_sale_and_service_render_cash
  ).filter(  income.code == '000001.XSHE',
  )ret = get_fundamentals(q, statDate='2014q2')ret

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


statDatecodebasic_epsgoods_sale_and_service_render_cash
02014-06-30000001.XSHE0.35NaN
# 查询平安银行2014年的年报q = query(  income.statDate,  income.code,  income.basic_eps,  cash_flow.goods_sale_and_service_render_cash
  ).filter(  income.code == '000001.XSHE',
  )ret = get_fundamentals(q, statDate='2014')ret

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


statDatecodebasic_epsgoods_sale_and_service_render_cash
02014-12-31000001.XSHE1.73NaN
# 查询平安银行2014年四个季度的季报, 放到数组中并拼接为dataframeq = query(  income.statDate,  income.code,  income.basic_eps,  balance.cash_equivalents,  cash_flow.goods_sale_and_service_render_cash
  ).filter(  income.code == '000001.XSHE',
  )rets = [get_fundamentals(q, statDate='2014q'+str(i)) for i in range(1, 5)]import pandas as pdpd.concat(rets)

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


statDatecodebasic_epscash_equivalentsgoods_sale_and_service_render_cash
02014-03-31000001.XSHE0.532.581100e+11NaN
02014-06-30000001.XSHE0.352.596040e+11NaN
02014-09-30000001.XSHE0.492.773250e+11NaN
02014-12-31000001.XSHE0.363.062980e+11NaN

in_  判断某个字段的值是否在列表之中(一般用于查询多个标的)¶

stocks = ['000001.XSHE','600741.XSHG','600507.XSHG']q = query(balance.code,balance.pubDate,balance.statDate,    # 指定返回的字段只包括code,pubDate,statDate,total_assets及total_sheet_owner_equities  balance.total_assets,balance.total_sheet_owner_equities).filter( balance.code.in_(stocks)   #指定查询到的数据只包括code在 stocks中的数据)get_fundamentals(q,date='2018-01-05')    #查询单季度数据中在2018-01-05之前发布的数据,没有未来函数

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


codepubDatestatDatetotal_assetstotal_sheet_owner_equities
0000001.XSHE2017-10-212017-09-303.137481e+123.137481e+12
1600507.XSHG2017-10-242017-09-301.041599e+101.041599e+10
2600741.XSHG2017-10-272017-09-301.153612e+111.153612e+11

distinct 去重,用于查看数据库中某个字段都存在哪些值¶

#  查看十大流通股东中都有哪些类别from jqdata import financeq = query( finance.STK_SHAREHOLDER_FLOATING_TOP10.shareholder_class_id.distinct(),  #提取ID不同的数据finance.STK_SHAREHOLDER_FLOATING_TOP10.shareholder_class, ).order_by(finance.STK_SHAREHOLDER_FLOATING_TOP10.change_reason_id)  df = finance.run_query(q)df.tail()

anon_1shareholder_class
23307012银行
24307024银行和上市公司
25307025信托投资管理公司和上市公司
26307024上市公司和银行
27307027银行和QFII

~ 反向查询符号¶

q = query( finance.STK_SHAREHOLDER_FLOATING_TOP10.shareholder_class_id.distinct(),finance.STK_SHAREHOLDER_FLOATING_TOP10.shareholder_class, ).filter(~finance.STK_SHAREHOLDER_FLOATING_TOP10.shareholder_class_id.in_(['307007','307001']),#等同于notin_)finance.run_query(q)

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


anon_1shareholder_class
0307002券商
1307003证券投资基金
2307004社保基金
3307005企业年金
4307006保险公司
5307008基金管理公司
6307009信托投资管理公司
7307011上市公司
8307012银行
9307013风险投资
10307014保险投资组合
11307015券商资产管理计划
12307016信托资产管理计划
13307017基金资产管理计划
14307018资产管理公司资产管理计划
15307019国有资产经营公司
16307020期货资产管理计划
17307021地方国资委
18307022券商和上市公司
19307023保险公司和上市公司
20307024银行和上市公司
21307024上市公司和银行
22307025信托投资管理公司和上市公司
23307027银行和QFII
24307099其他机构

运算和命名(label)¶

# label的作用是命名获得数据的标签,一般用于直接运算后的重命名q = query(indicator.code.label('股票代码'),indicator.operating_profit.label('get_operating_profit'), (income.total_operating_revenue - income.total_operating_cost).label('my_operating_profit') ).filter(indicator.code=='600507.XSHG')get_fundamentals(q)

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


股票代码get_operating_profitmy_operating_profit
0600507.XSHG1.329762e+091.329762e+09

or_ 或查询¶

from sqlalchemy.sql.expression import or_df = get_fundamentals(query(  valuation.code,valuation.market_cap,valuation.pe_ratio  ).filter(  or_(valuation.market_cap < 10,valuation.pe_ratio > 1000)))  # 查询当天总市值小于1000亿或pe大于10亿的所有股票df.tail()

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


codemarket_cappe_ratio
23300336.XSHE32.81362772.8604
24600127.XSHG30.16381195.8562
25600462.XSHG8.3803-3.0123
26601008.XSHG46.69993504.9221
27603718.XSHG87.90601225.4053

contains/like/ilike  数据库中的字符串模糊匹配¶

  • %  百分号通配符: 表示任何字符出现任意次数(可以是0次).

  • _  下划线通配符:表示只能匹配单个字符,不能多也不能少,就是一个字符.

from jqdata import finance# 获取000001.XSHG每一年的年报   df = finance.run_query(query(finance.FINANCE_INCOME_STATEMENT   ).filter(finance.FINANCE_INCOME_STATEMENT.code.in_(['000001.XSHE']),#                 finance.FINANCE_INCOME_STATEMENT.end_date.like('%-12-31%'),    #sqlalchemy的版本,数据库的构建等问题可能导致查询报错,可以换以下两种方法尝试#               finance.FINANCE_INCOME_STATEMENT.end_date.contains('12-31') ,      finance.FINANCE_INCOME_STATEMENT.end_date.ilike('_____12-31'),finance.FINANCE_INCOME_STATEMENT.report_type==0   ))df.tail()

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


idcompany_idcompany_namecodea_codeb_codeh_codepub_datestart_dateend_datereport_datereport_typesource_idsourceoperating_revenueinterest_net_revenueinterest_incomeinterest_expensecommission_net_incomecommission_incomecommission_expenseagent_security_incomesell_security_incomemanage_incomepremiums_earnedassurance_incomepremiums_incomepremiums_expenseprepare_moneyinvestment_incomeinvest_income_associatesfair_value_variable_incomeexchange_incomeother_incomeoperation_expenserefunded_premiumscompensate_losscompensation_backinsurance_reserveinsurance_reserve_backpolicy_dividend_payoutreinsurance_costoperating_tax_surchargescommission_expense2operation_manage_feeseparate_feeasset_impairment_lossother_costoperating_profitsubsidy_incomenon_operating_revenuenon_operating_expenseother_items_influenced_profittotal_profitincome_tax_expenseother_influence_net_profitnet_profitnp_parent_company_ownersminority_profitepsbasic_epsdiluted_epsother_composite_incometotal_composite_incomeci_parent_company_ownersci_minority_owners
212543430000001平安银行股份有限公司000001.XSHE000001NoneNone2015-03-132014-01-012014-12-312014-12-310321003定期报告7.340700e+105.304600e+101.192020e+116.615600e+101.737800e+101.970600e+102.328000e+09NoneNaNNoneNoneNoneNoneNoneNone3.168000e+0928000000.0-10000000.0-388000000.0213000000.04.716100e+10NaNNoneNoneNoneNoneNoneNone5.482000e+09None2.666800e+10None1.501100e+100.000000e+002.624600e+10None40000000.092000000.0NaN2.619400e+106.392000e+09None1.980200e+101.980200e+10NaNNone1.731.73586000000.02.038800e+10NaNNaN
222551430000001平安银行股份有限公司000001.XSHE000001NoneNone2016-03-102015-01-012015-12-312015-12-310321003定期报告9.616300e+106.609900e+101.316490e+116.555000e+102.644500e+102.918500e+102.740000e+09NoneNaNNoneNoneNoneNoneNoneNone3.924000e+0928000000.0107000000.0-573000000.0161000000.06.726800e+10NaNNoneNoneNoneNoneNoneNone6.671000e+09None3.011200e+10None3.048500e+100.000000e+002.889500e+10None40000000.089000000.0NaN2.884600e+106.981000e+09None2.186500e+102.186500e+10NaNNone1.561.56NaN2.259900e+10NaNNaN
232559430000001平安银行股份有限公司000001.XSHE000001NoneNone2017-03-172016-01-012016-12-312016-12-310321003定期报告1.077150e+117.641100e+101.311190e+115.470800e+102.785900e+103.130900e+103.450000e+09NoneNaNNoneNoneNoneNoneNoneNone2.368000e+09-141000000.049000000.0882000000.0146000000.07.793600e+10NaNNoneNoneNoneNoneNoneNone3.445000e+09None2.797300e+10None4.651800e+100.000000e+002.977900e+10None221000000.065000000.0NaN2.993500e+107.336000e+09None2.259900e+102.259900e+10NaNNone1.321.32308000000.02.290700e+102.290700e+10NaN
242564430000001平安银行股份有限公司000001.XSHE000001NoneNone2018-03-152017-01-012017-12-312017-12-310321003定期报告1.057860e+117.400900e+101.480680e+117.405900e+103.067400e+103.572500e+105.051000e+09NoneNaNNoneNoneNoneNoneNoneNone6.320000e+08NaN-61000000.0166000000.0186000000.07.556300e+10NaNNoneNoneNoneNoneNoneNone1.022000e+09None3.161600e+10None4.292500e+10NaN3.022300e+10None38000000.0104000000.0NaN3.015700e+106.968000e+09None2.318900e+102.318900e+10NaNNone1.301.30281000000.02.347000e+102.347000e+10NaN
254931430000001平安银行股份有限公司000001.XSHE000001NoneNone2019-03-072018-01-012018-12-312018-12-310321003定期报告1.167160e+117.474500e+101.628880e+118.814300e+103.129700e+103.936200e+108.065000e+09NoneNaNNoneNoneNoneNoneNoneNone9.186000e+09NaN892000000.0209000000.0170000000.08.441100e+10NaNNoneNoneNoneNoneNoneNone1.149000e+09None3.539100e+10NoneNaN4.787100e+103.230500e+10None28000000.0102000000.0NaN3.223100e+107.413000e+09None2.481800e+102.481800e+10NaNNone1.391.39912000000.02.573000e+102.573000e+10NaN

简化计算的方法(sqlalchemy.sql.func)  和  group_by¶

func中的函数可以完成常用的一些计算,配合group_by完成简单的统计
下边以简单计算股票池/全市场每天的的等权重pe,pb为例
(当然,这个计算中一些细节并没有考虑到,实际还是以官方数据为准,可以通过聚源数据获取,具体下边会有演示)

from sqlalchemy.sql import funcfrom jqdata import financestocks = get_index_stocks('000016.XSHG')q = query(valuation.day,#           func.count('*'),       # 信息条数(也就是股票数量)  (func.count()/func.sum(1/valuation.pe_ratio)).label('*g_pe'),  # 等权重pe  (func.count()/func.sum(1/valuation.pb_ratio)).label('*g_pb'),  # 等权重pb ).group_by(valuation.day   ).filter(valuation.pe_ratio>0,   #排除亏损的valuation.pb_ratio>0,   valuation.day>'2009-12-01',  #设置一个时间valuation.code.in_(stocks)   #设置股票池,注释即为全市场)df = finance.run_query(q)df.set_index('day',inplace=True)df.tail()

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


*g_pe*g_pb
day

2019-01-1610.0814091.295044
2019-01-1710.0362751.289927
2019-01-1810.2012091.309428
2019-01-2110.2621071.314957
2019-01-2210.2621071.314957

更多关于query的可导入函数,可以使用以下方法查看,配合官网文档使用:

import sqlalchemy
dir(sqlalchemy.sql.expression)

其他常用数据获取方式整理¶

获取旧的申万指数列表和新的申万指数列表(14年有过改动)¶

from jqdata import *def get_sw_quote(day=None):'''获取指定日期的申万指数列表'''day = get_trade_days(end_date=day,count=1)[-1]df = jy.run_query(query( jy.QT_SYWGIndexQuote.InnerCode.distinct().label('InnerCode')).filter(jy.QT_SYWGIndexQuote.TradingDay==day,))code_df = jy.run_query(query( jy.SecuMain.SecuCode,jy.SecuMain.ChiName).filter(jy.SecuMain.InnerCode.in_(df.InnerCode)))return code_dfdf = get_sw_quote('2013-02-05')df.tail()

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


SecuCodeChiName
466852041申银万国指数-专业连锁
467852051申银万国指数-一般物业经营
468852052申银万国指数-专业市场
469852225申银万国指数-软件开发
470852226申银万国指数-IT服务

查询申万行情( 包含行业pe/pb)¶

from jqdata import jyfrom jqdata import *import pandas as pd#注意申万指数在2014年有一次大改,聚源使用的是为改变之前的代码,官网包含更改前和更改后的代码,如果遇到找不到的标的可以根据需求自行查找#如801124 >>801121食品加工IIdef get_sw_quote(code,end_date=None,count=None,start_date=None):'''获取申万指数行情,返回panel结构'''if isinstance(code,str):code=[code]days = get_trade_days(start_date,end_date,count)code_df = jy.run_query(query( jy.SecuMain.InnerCode,jy.SecuMain.SecuCode,jy.SecuMain.ChiName).filter(jy.SecuMain.SecuCode.in_(code)))df = jy.run_query(query( jy.QT_SYWGIndexQuote).filter(jy.QT_SYWGIndexQuote.InnerCode.in_(code_df.InnerCode),jy.QT_SYWGIndexQuote.TradingDay.in_(days),))df2  = pd.merge(code_df, df, on='InnerCode').set_index(['TradingDay','SecuCode'])df2.drop(['InnerCode','ID','UpdateTime','JSID'],axis=1,inplace=True)return df2.to_panel()code = get_industries(name='sw_l2').index[:5]df = get_sw_quote(code,end_date='2018-01-01',count=10)df.to_frame(False).tail()
/opt/conda/envs/python2new/lib/python2.7/site-packages/ipykernel_launcher.py:23: DeprecationWarning: 
Panel is deprecated and will be removed in a future version.
The recommended way to represent these types of 3-dimensional data are with a MultiIndex on a DataFrame, via the Panel.to_frame() method
Alternatively, you can use the xarray package http://xarray.pydata.org/en/stable/.
Pandas provides a `.to_xarray()` method to help automate this conversion.

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }



ChiNamePrevClosePriceOpenPriceHighPriceLowPriceClosePriceTurnoverVolumeTurnoverValueTurnoverDealsChangePCTRightLevelIndexPEIndexPBTotalMarketValueAShareTotalMV
TradingDaySecuCode














2017-12-29801011申银万国指数-林业1800.0921795.4801845.601784.411802.7982853232.03.554701e+07None0.00154777.373.132036129.01121708.0
801012申银万国指数-农产品加工2551.7762546.6002573.802515.612556.51293670965.01.234257e+09None0.0019435.583.1214529320.07936090.0
801013申银万国指数-农业综合2269.6102260.5302278.202254.302272.4809084945.04.234125e+07None0.00134125.712.92867493.0464852.0
801014申银万国指数-饲料3644.5203646.5683709.263610.053685.350133928157.01.452713e+09None0.0112423.782.7121027565.08124732.0
801015申银万国指数-渔业1540.1781535.7481566.711528.661555.76034618204.03.012524e+08None0.0101443.952.525217722.02511131.0

查询中证行情( 包含指数市值/市盈率/股息率以及红利等指数)¶

def get_zz_quote(code,end_date=None,count=None,start_date=None):'''获取中证指数行情,包含市值,市盈率,股息率,返回panel结构'''if isinstance(code,str):code=[code]code.sort()code = [x[:6] for x in code]days = get_trade_days(start_date,end_date,count)code_df = jy.run_query(query( jy.SecuMain.InnerCode,jy.SecuMain.SecuCode,jy.SecuMain.ChiName).filter(jy.SecuMain.SecuCode.in_(code)).order_by(jy.SecuMain.SecuCode))df = jy.run_query(query( jy.QT_CSIIndexQuote).filter(jy.QT_CSIIndexQuote.IndexCode.in_(code_df.InnerCode),jy.QT_CSIIndexQuote.TradingDay.in_(days),))df2  = pd.merge(code_df, df, left_on='InnerCode',right_on='IndexCode').set_index(['TradingDay','SecuCode'])df2.drop(['InnerCode','IndexCode','ID','UpdateTime','JSID','OpenInterest','SettleValue','IndexCSIType'],axis=1,inplace=True)return df2.to_panel()panel = get_zz_quote(['000016.XSHG','000001.XSHG'],end_date='2019-01-21',count=10)panel.ClosePrice.tail()
/opt/conda/envs/python2new/lib/python2.7/site-packages/ipykernel_launcher.py:19: DeprecationWarning: 
Panel is deprecated and will be removed in a future version.
The recommended way to represent these types of 3-dimensional data are with a MultiIndex on a DataFrame, via the Panel.to_frame() method
Alternatively, you can use the xarray package http://xarray.pydata.org/en/stable/.
Pandas provides a `.to_xarray()` method to help automate this conversion.

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }

SecuCode000001000016
TradingDay

2019-01-152570.34492378.3696
2019-01-162570.42212381.2178
2019-01-172559.63702371.3481
2019-01-182596.00562417.3630
2019-01-212610.50942432.4870

查询股息率(近12个月)¶

from jqdata import *def DividendRatio(security_list,end_date,count=1):'''查询股息率(日更新)    输入:股票池,截止日期,获取数量    输出:panel结构,单位:1'''trade_days = get_trade_days(end_date=end_date,count = count)security_list.sort()secu_list = [x[:6] for x in security_list]code_df = jy.run_query(query( jy.SecuMain.InnerCode,jy.SecuMain.SecuCode,#     jy.SecuMain.ChiName,jy.SecuMain.CompanyCode).filter(jy.SecuMain.SecuCode.in_(secu_list),jy.SecuMain.SecuCategory==1).order_by(jy.SecuMain.SecuCode))code_df['code'] = security_listdf = jy.run_query(query(#         jy.LC_DIndicesForValuation    #得到整表jy.LC_DIndicesForValuation.InnerCode,jy.LC_DIndicesForValuation.TradingDay, jy.LC_DIndicesForValuation.DividendRatio,).filter(jy.LC_DIndicesForValuation.InnerCode.in_(code_df.InnerCode),jy.LC_DIndicesForValuation.TradingDay.in_(trade_days)))f_df = df.merge(code_df,on='InnerCode').set_index(['TradingDay','code']).drop(['InnerCode','SecuCode'],axis=1)panel = f_df.to_panel()return panelsecuritys =get_index_stocks('399015.XSHE')[:10]date='2018-01-01'DividendRatio(securitys,date,count=5)
/opt/conda/envs/python2new/lib/python2.7/site-packages/ipykernel_launcher.py:24: DeprecationWarning: 
Panel is deprecated and will be removed in a future version.
The recommended way to represent these types of 3-dimensional data are with a MultiIndex on a DataFrame, via the Panel.to_frame() method
Alternatively, you can use the xarray package http://xarray.pydata.org/en/stable/.
Pandas provides a `.to_xarray()` method to help automate this conversion.
<class 'pandas.core.panel.Panel'>
Dimensions: 1 (items) x 5 (major_axis) x 10 (minor_axis)
Items axis: DividendRatio to DividendRatio
Major_axis axis: 2017-12-25 00:00:00 to 2017-12-29 00:00:00
Minor_axis axis: 000007.XSHE to 000049.XSHE

获取期货合约的基本信息(合约乘数、商品报价的计数单位、最小变动单位)¶

# lru缓存可以不要,加上后查询相同的合约可以避免重复数据库请求from fastcache import clru_cache as lru_cache@lru_cache(maxsize=128)def future_basic_info(future):from jqdata import jyfrom numpy import nanimport reif "9999" in future or "8888" in future:match = re.match(r"(?P<underlying_symbol>[A-Z]{1,})", future)if not match:raise ValueError("未知期货标的:{}".format(future))else:future = get_dominant_future(match.groupdict()["underlying_symbol"])q = query(jy.Fut_ContractMain).filter(jy.Fut_ContractMain.ContractCode == future.split(".")[0])result = jy.run_query(query_object=q).to_dict("record")if result:result = result.pop()min_point = re.match("(?P<value>^[0-9]+([.]{1}[0-9]+){0,1})", result["LittlestChangeUnit"]).groupdict(nan)["value"]return {"ContractUnit": result["CMValue"],   "PriceScale": float(str(min_point)[:-1] + "1") if float(min_point) < 1 else 1,   "MinPoint": float(min_point)}else:return {"ContractUnit": nan,"PriceScale": nan,"MinPoint": nan}future_basic_info('IF1801.CCFX')
{'ContractUnit': 300, 'MinPoint': 0.2, 'PriceScale': 0.1}

多个dataframe的合并 (数据拼接) 获取多份财务报表¶

#获取多年的季度度数据import pandas as pddef get_more_state_fund(q_object,year_list):df_list = []for year in year_list:rets = [get_fundamentals(q, statDate=str(year)+'q'+str(i)) for i in range(1, 5)]df = pd.concat(rets).set_index('statDate')  #个人习惯df_list.append(df)df_ = pd.concat(df_list,keys=year_list,axis=0) #axis=1或axis=0,依据个人习惯return df_q = query(indicator.code,  indicator.statDate,indicator.roe,indicator.inc_return,indicator.pubDate,
  ).filter(  income.code.in_(['000001.XSHE','600507.XSHG']))df = get_more_state_fund(q,['2017','2018'])# df.loc[('2014',slice(None))]df

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }



coderoeinc_returnpubDate

statDate



20172017-03-31000001.XSHE3.03193.03092017-04-22
2017-03-31600507.XSHG10.202410.09972017-04-22
2017-06-30000001.XSHE3.02493.00582017-08-11
2017-06-30600507.XSHG14.092914.21332017-08-19
2017-09-30000001.XSHE3.07243.08132017-10-21
2017-09-30600507.XSHG24.286623.92432017-10-24
2017-12-31000001.XSHE1.83391.83202018-03-15
2017-12-31600507.XSHG22.919119.81842018-02-09
20182018-03-31000001.XSHE2.96112.94312018-04-20
2018-03-31600507.XSHG13.634513.60672018-04-21
2018-06-30000001.XSHE3.00003.00002018-08-16
2018-06-30600507.XSHG19.990019.72002018-08-18
2018-09-30000001.XSHE3.06003.03002018-10-24
2018-09-30600507.XSHG21.240021.17002018-10-25
2018-12-31000001.XSHE1.84001.83002019-03-07
2018-12-31600507.XSHG10.410010.23002019-02-22
#h获取多个年度财务数据import pandas as pdstock_list=['000001.XSHE','000527.XSHE','600970.XSHG','600875.XSHG','600880.XSHG']years = range(2005,2018)df_list=[]for year in years:df_year= get_fundamentals(query( indicator.code, indicator.inc_return,indicator.roe   ).filter( indicator.code.in_(stock_list)   ),statDate=year).set_index('code')df_list.append(df_year)name = [str(x) for x in range(2005,2017)]df=pd.concat(df_list,axis=1,keys=name)df

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


200520062007200820092010201120122013201420152016












inc_returnroeinc_returnroeinc_returnroeinc_returnroeinc_returnroeinc_returnroeinc_returnroeinc_returnroeinc_returnroeinc_returnroeinc_returnroeinc_returnroe
000001.XSHE6.87346.386821.284922.602526.770827.20574.24354.176126.794227.288722.762023.280919.058119.244116.931616.953715.406415.472416.328016.295914.978314.953012.432112.4283
000527.XSHE13.349013.330015.766716.390826.317929.823024.726422.368126.261926.631427.138328.705219.361622.878416.238316.5337NaNNaNNaNNaNNaNNaNNaNNaN
600875.XSHG34.141834.031422.720157.133116.266647.253156.74906.702030.238228.697224.809626.099223.266624.606013.733214.864913.427614.08036.24366.86541.48522.0616-8.9718-8.0745
600880.XSHG18.174018.563421.319812.354819.854320.219918.975519.920320.902822.668120.953721.725416.532321.366213.173113.225811.446311.78528.00767.90880.77652.0698-0.71191.6685
600970.XSHG15.808817.516314.840430.903025.128128.233643.416430.684648.438447.129749.058052.502339.261239.874716.346517.0652-0.57512.02482.23353.40418.911912.20164.36957.6902

     需要注意的:  finance,jy,opt,macro有一次性获取数据不超过3000条的限制(主要是为了提速,jqdatasdk上限是4000条,官网后续也会增加到4000条,get_fundamentals的限制为10000条),

   所以当获取的数据超过这个限制时,需要对股票池或者时间段进行分割,多次获取,也可以通过offset。

利用offset多次查询以跳过限制¶

from jqdata import financefrom sqlalchemy.sql import funcimport pandas as pdimport mathsum_count = finance.run_query(query(func.count('*')   ).filter(finance.CCTV_NEWS.day<'2012-01-01')).iloc[0,0]  #先查询总共有多少条数据print ('总共有{}条数据,需要获取{}次'.format(sum_count,int(math.ceil(sum_count/3000.0))))l = []for i in range(0,14909,3000): #以3000为步长循环offset的参数q = query(finance.CCTV_NEWS).filter(finance.CCTV_NEWS.day<'2012-01-01'   ).order_by(finance.CCTV_NEWS.day  #可以先按照一定规律排序 ).offset(i)   #自第i条数据之后进行获取df=finance.run_query(q)l.append(df)df = pd.concat(l).reset_index()  #数据拼接print(df.shape)df.tail()
总共有14909条数据,需要获取5次
(14909, 5)

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


indexiddaytitlecontent
149042904147152011-12-31国内联播快讯“十二五”期间工业领域重点行业淘汰落后产能目标任务日前下达,与“十一五”相比,新增了铜冶...
149052905147022011-12-31胡锦涛主席发表2012年新年贺词2012年新年来临之际,国家主席胡锦涛通过中国国际广播电台、中央人民广播电台和中央电视台...
149062906147062011-12-31胡锦涛签署第五十二号、五十三号主席令本台消息,国家主席胡锦涛31号在北京签署了第五十二号和第五十三号主席令。\n  第五...
149072907147042011-12-31胡锦涛致电祝贺金正恩担任朝鲜人民军最高司令官本台消息,12月31日,中华人民共和国中央军事委员会主席胡锦涛致电祝贺金正恩担任朝鲜...
149082908147172011-12-31金正恩成为朝鲜人民军最高司令官据朝中社今天报道,朝鲜劳动党中央政治局会议30号在平壤召开会议宣布,根据已故最高领导人金...

获取前N季度的财务数据¶

相关说明: https://www.joinquant.com/help/api/help?name=factor#如何理解dependencies中的财务因子
一般获取的前N季度数据可以直接在因子分析中直接处理了,如果有特殊需求,可以使用下边的方法获得一个panel(不推荐,推荐直接在factor类中直接计算获取计算完成后的dataframe)

from jqfactor import Factor, calc_factorsimport pandas as pddef get_more_data(data_name,securities,start_date,end_date):class get_N_data(Factor):name = 'more_data'max_window = 1dependencies = data_namedef calc(self, data):all_data = pd.concat(data.values())all_data.index = data_nameall_data =  pd.Series(all_data.to_dict())return all_datadata1 = calc_factors(securities, [get_N_data()], start_date=start_date, end_date=end_date)all_data = pd.Panel(data1['more_data'].to_dict()) return all_data   #处理成panel结构data_name = ['net_profit','net_profit_1','net_profit_2','net_profit_3']securities = ['600741.XSHG','000001.XSHG']get_more_data(data_name,securities,start_date='2019-01-01',end_date='2019-02-01')
/opt/conda/envs/python2new/lib/python2.7/site-packages/ipykernel_launcher.py:25: DeprecationWarning: 
Panel is deprecated and will be removed in a future version.
The recommended way to represent these types of 3-dimensional data are with a MultiIndex on a DataFrame, via the Panel.to_frame() method
Alternatively, you can use the xarray package http://xarray.pydata.org/en/stable/.
Pandas provides a `.to_xarray()` method to help automate this conversion.
<class 'pandas.core.panel.Panel'>
Dimensions: 2 (items) x 4 (major_axis) x 23 (minor_axis)
Items axis: 000001.XSHG to 600741.XSHG
Major_axis axis: net_profit to net_profit_3
Minor_axis axis: 2019-01-02 00:00:00 to 2019-02-01 00:00:00

计算TTM数据¶

各种指标算法多式多样,我们提供的财务数据中最主要的还是单季度和报告期的财务指标,具体算法以及含义在文档中有详细说明 https://www.joinquant.com/help/api/help?name=Stock#获取单季度年度财务数据
关于两者的区别可以参看这篇帖子理解:
https://www.joinquant.com/view/community/detail/fcb3baa6f926259*caac3bce7c12b1c?type=2

TTM数据有些在聚宽因子库中可以直接获取(对于一些TTM的算法以及口径有多种方式,所以各平台可能存在不一致)
https://www.joinquant.com/help/api/help?name=factor_values
没有提供的可以借助因子分析进行计算
https://www.joinquant.com/help/api/help?name=factor#示例-计算TTM数据
https://www.joinquant.com/help/api/help?name=factor#在研究与回测中计算因子
下边以计算/获取营业收入TTM及ROE TTM为例:

# 使用因子分析进行计算from jqfactor import Factor, calc_factors# 计算营业收入TTMclass OR_TTM(Factor):# 设置因子名称name = 'operating_revenue_ttm'# 设置获取数据的时间窗口长度max_window = 1# 设置依赖的数据,即前四季度的营业收入dependencies = ['operating_revenue','operating_revenue_1','operating_revenue_2','operating_revenue_3']# 计算因子的函数, 需要返回一个 pandas.Series, index 是股票代码,value 是因子值def calc(self, data):# 计算 ttm , 为前四季度相加ttm = data['operating_revenue'] + data['operating_revenue_1'] + data['operating_revenue_2'] + data['operating_revenue_3']# 将 ttm 转换成 seriesreturn ttm.mean()securities = ['000001.XSHE','600000.XSHG']# 计算因子值data1 = calc_factors(securities, [OR_TTM()], start_date='2019-01-01', end_date='2019-06-01', 
                                       use_real_price=False, skip_paused=False)data1['operating_revenue_ttm'].tail()

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


000001.XSHE600000.XSHG
2019-05-271.211660e+111.819970e+11
2019-05-281.211660e+111.819970e+11
2019-05-291.211660e+111.819970e+11
2019-05-301.211660e+111.819970e+11
2019-05-311.211660e+111.819970e+11
# 通过聚宽因子库直接获取from jqfactor import get_factor_valuesdata2 = get_factor_values(securities,factors='operating_revenue_ttm',start_date='2019-01-01', end_date='2019-06-01')data2['operating_revenue_ttm'].tail()

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }

code000001.XSHE600000.XSHG
2019-05-271.211660e+111.819970e+11
2019-05-281.211660e+111.819970e+11
2019-05-291.211660e+111.819970e+11
2019-05-301.211660e+111.819970e+11
2019-05-311.211660e+111.819970e+11
# 使用因子分析进行计算roefrom jqfactor import Factor, calc_factors# 计算营业收入TTM# roe_ttm = np_parent_company_owners_ttm/equities_parent_company_owners(最近一期)  wind算法class ROE_TTM(Factor):# 设置因子名称name = 'roe_ttm'# 设置获取数据的时间窗口长度max_window = 1# 设置依赖的数据dependencies = ['np_parent_company_owners',   'equities_parent_company_owners','np_parent_company_owners_1', #'np_parent_company_owners_ttm''np_parent_company_owners_2', 'np_parent_company_owners_3',] # 计算因子的函数, 需要返回一个 pandas.Series, index 是股票代码,value 是因子值def calc(self, data):# 计算 ttm ttm_1 = (data['np_parent_company_owners'] + data['np_parent_company_owners_1'] + data['np_parent_company_owners_2'] + data['np_parent_company_owners_3'])#         ttm_1 = (data['np_parent_company_owners_ttm']  #ttm1 = 归属于母公司股东的净利润TTM,和上边代码结果一致,这里也可以直接从聚宽因子库获取数据ttm_2 = data['equities_parent_company_owners']return (ttm_1/ttm_2).mean()securities = ['000001.XSHE','600000.XSHG','000002.XSHE']# 计算因子值data1 = calc_factors(securities, [ROE_TTM()], start_date='2019-01-01', end_date='2019-06-01', 
                                       use_real_price=False, skip_paused=False)data1['roe_ttm'].tail()

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


000001.XSHE600000.XSHG000002.XSHE
2019-05-270.1022920.1188460.215792
2019-05-280.1022920.1188460.215792
2019-05-290.1022920.1188460.215792
2019-05-300.1022920.1188460.215792
2019-05-310.1022920.1188460.215792
# 通过聚宽因子库直接获取roe_ttmfrom jqfactor import get_factor_valuesdata2 = get_factor_values(securities,factors='roe_ttm',start_date='2019-01-01', end_date='2019-06-01')data2['roe_ttm'].tail()

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }

code000001.XSHE600000.XSHG000002.XSHE
2019-05-270.1022920.1188460.215792
2019-05-280.1022920.1188460.215792
2019-05-290.1022920.1188460.215792
2019-05-300.1022920.1188460.215792
2019-05-310.1022920.1188460.215792

计算同比/环比指标¶

import pandas as pdfrom jqfactor import Factor, calc_factorsdef get_growth_rate(security_list,field,start_date=None,end_date=None,type_ = 'q_to_q'):"""    field: 计算的指标名,填写财务数据中单季度指标名 ,如adjusted_profit 扣非净利润    type_: 计算类型q_to_q代表环比,y_to_y    """type_dict = {'y_to_y':field+'_4','q_to_q':field+'_1'}class Get_Annual(Factor):name = field+type_max_window = 1dependencies = [field, type_dict[type_]] def calc(self, data):df = pd.Panel(data).iloc[:,0]res = (df.iloc[:,0]-df.iloc[:,1])/df.iloc[:,1]extra_df = df[(df.iloc[:,1]<0)]res[extra_df.index] = res[extra_df.index]*-1   #上期为负的数据乘以-1,如果要表示亏损增长率可以用1去减res[extra_df.index]return resdata1 = calc_factors(security_list, [Get_Annual()], start_date=start_date,end_date=end_date, skip_paused=False)return data1[field+type_]type_ = 'q_to_q'security_list = ["000001.XSHE","600741.XSHG"]field = 'adjusted_profit'   # 计算扣费净利润环比增长率df = get_growth_rate(security_list,field,start_date='2015-01-01',end_date='2019-06-25',type_ = 'y_to_y')df.tail()

.dataframe thead tr:only-child th {        text-align: right;    }    .dataframe thead th {        text-align: left;    }    .dataframe tbody tr th {        vertical-align: top;    }


000001.XSHE600741.XSHG
2019-06-190.132265-0.151126
2019-06-200.132265-0.151126
2019-06-210.132265-0.151126
2019-06-240.132265-0.151126
2019-06-250.132265-0.151126
 

全部回复

0/140

量化课程

    移动端课程