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

量化交易吧 /  数理科学 帖子:3353808 新帖:59

杂七杂八的小方法

爱汇小王子发表于:5 月 10 日 05:25回复(1)

发现大家刚开始不太会实现某种方法,其实平时多使用平台完全可以自己解决,但为了尽量避免让大家走弯路.在这里对一些问题进行有限整理,针对大家经常性问到的方法实现。

其实很多问题可以通过社区搜索和共享函数库解决的,这里并不是单纯为大家提供代码,而是选取一些比较有借鉴性的方法供大家参考,重要的不是代码,而是实现代码过程中的思路以及路径,因为方法有千千万万种,需要举一而反三。

今后会持续选取一些比较有代表性的代码进行添加,您也可以将一些初学时碰到的常见问题在下方留言反馈或分享。


收录列表

获得向前推第T个交易日日期
获取向后推X个交易日的交易日列表
市场每日统计(上涨,下跌,涨停,跌停户数等)
HHV,LLV:过去N日的最高/最低价的时间序列
MACD(多股票,多周期)
国内sma算法(与talib不一致)
剔除上市不满一年的次新股
分时走势图的黄线(均价线)
日内每x分钟运行
时间段内运行/时间点运行
根据大盘指数跌幅进行止损【回测专用】
缠论K线包含关系处理
设置pandas的最大显示行数,列数
将array数据格式转为dataframe
多个dataframe的合并 (数据拼接) 获取多份报表
panel数据可视化(转dataframe)
剔除过去N天停牌超过X日的股票
移动窗口(rolling)和 拓展窗口(expanding)
简单的ema计算
量比
DatetimeIndex 转 strindex (解决绘图非交易时间自动补全) 以及绘图正常显示问题
解决中文显示
查询股息率(近12个月)
期货合约每点价位
查询申万行情( 包含行业pe/pb)
中证指数pe/股息率
获取所有商品指数,主力合约,品种代号等
字典转dataframe/panel
数据库/pandas的模糊查询
研究中进行性能分析
区间换手率

VPT量能指标  
ADF 平稳性检验(有点小问题,修改方法):

from  statsmodels.tsa.stattools import adfuller   
import pandas as pd   
for key,value in enumerate(dftest[4]):

https://www.joinquant.com/algorithm/apishare/get?apiId=1113
和行情软件(同花顺、大智慧、通达信等)一致的KDJ和RSI以及MACD算法

抛物线转向(Stop And Reverse)(注意更改大小写,如Date>date)
s = psar(get_bars('600741.XSHG',count=10,fields=['date','close', 'high', 'low']));     pd.DataFrame(s)

有效前沿计算:https://www.joinquant.com/post/14766
Tradestat 策略常用的一个小工具,非常漂亮的持仓收益日志显示 

获得向前推第T个交易日日期¶

利用get_trade_days和context对象中的current_dt等获取上上一个交易日等,在此给出示例 使用前: from jqdata import * 当前交易日: now_ = context.current_dt.strftime("%Y-%m-%d") 上上一个交易日: the_day = get_the_day(now,2)

有关时间处理的demo请看这里:

from jqdata import *def get_the_day(date,T):'''输入,当前日期  向前推T天个交易日      比如date为9月13,前几天无节假日,传入T=1,返回上一个交易日的日期'''return get_trade_days(end_date=date,count=T+1)[0]get_the_day('2018-09-13',2)
datetime.date(2018, 9, 11)

获取向后推X个交易日的交易日列表¶

import jqdataimport datetimedate = datetime.date(2018,10,1)def get_future_trade_days(date,count):if count>5: all_data = jqdata.get_trade_days(start_date=date,end_date=date+datetime.timedelta(days=count*2))else:all_data = jqdata.get_trade_days(start_date=date,end_date=date+datetime.timedelta(days=count+10))return all_data[:count]date = datetime.date(2018,10,8)get_future_trade_days(date,2)
array([datetime.date(2018, 10, 8), datetime.date(2018, 10, 9)], dtype=object)

市场每日统计(上涨,下跌,涨停,跌停户数等)¶

def Market_statistics(check_date,filter_st=True):'''check_date: 统计日期,      filter_st: 是否过滤st'''info_data = get_all_securities(date=check_date)all_list = info_data.index.tolist()st_df  =  get_extras('is_st', all_list,end_date=check_date, df=True, count=1).Tst_list = st_df[st_df.iloc[:,0]].index.tolist()print ('st股票有%s只'%len(st_list))print ('未退市的有%s只'%len(all_list))all_data = get_price(all_list,end_date=check_date,count=2,fields=['paused','close','high_limit','low_limit'])paused_data = all_data.paused.iloc[-1]paused_list = paused_data[paused_data==1].index.tolist()print ('停牌%s只'%len(paused_list))new_data = all_data.drop(paused_list,axis=2)if filter_st ==True:filter_list = list(set(st_list)-set(paused_list))new_data = new_data.drop(filter_list,axis=2)pct_data = new_data.close.pct_change().iloc[1]print ('当日新上市股票:%s'%pct_data[np.isnan(pct_data)].index.tolist())print ('上涨%s只(不含当日上市)'%len(pct_data[pct_data>=0]))print ('下跌%s只'%len(pct_data[pct_data<0]))limit_up_data = new_data.iloc[:,-1,:][new_data.iloc[:,-1,:].close==new_data.iloc[:,-1,:].high_limit]print ('涨停%s只'%len(limit_up_data))limit_down_data = new_data.iloc[:,-1,:][new_data.iloc[:,-1,:].close==new_data.iloc[:,-1,:].low_limit]print ('跌停%s只'%len(limit_down_data))now_time = datetime.datetime.now()Market_statistics(now_time,True)  #彩蛋:2008-04-24,2008-09-19大盘涨停# 2015-07-08年千股停牌 ,15年停牌股票较多# 2016年开年,熔断机制*,千股跌停
st股票有89只
未退市的有3551只
停牌84只
当日新上市股票:[]
上涨524只(不含当日上市)
下跌2863只
涨停16只
跌停20只

HHV,LLV:过去N日的最高/最低价的时间序列¶

import pandas as pddef HHV(srcuritys,windows,end_date=None,count=20,fq='pre'):'''传入,股票列表,时间窗口,查询日期(包含当天,返回的数量,复权方式'''df =  get_price(srcuritys,end_date=end_date,count=count+windows-1,fq=fq,fields='high')return pd.rolling_max(df.high,windows).dropna()###########################################################def LLV(srcuritys,windows,end_date=None,count=20,fq='pre'):'''传入,股票列表,时间窗口,查询日期(包含当天,返回的数量,复权方式'''df =  get_price(srcuritys,end_date=end_date,count=count+windows-1,fq=fq,fields='low')return pd.rolling_min(df.low,windows).dropna()# HHV(['600741.XSHG','600507.XSHG'],10,'2018-09-04')LLV(['600741.XSHG','600507.XSHG'],10,'2018-09-04')

600741.XSHG600507.XSHG
2018-08-0820.2011.48
2018-08-0920.1311.48
2018-08-1020.1311.48
2018-08-1320.1311.48
2018-08-1420.1311.48
2018-08-1520.1311.48
2018-08-1619.9611.45
2018-08-1719.8611.45
2018-08-2019.2011.02
2018-08-2119.2011.02
2018-08-2219.2011.02
2018-08-2319.2011.02
2018-08-2419.2011.02
2018-08-2719.2011.02
2018-08-2819.2011.02
2018-08-2919.2011.02
2018-08-3019.2011.02
2018-08-3119.2011.02
2018-09-0319.5010.92
2018-09-0419.8010.92

MACD(多股票,多周期)¶

获取各周期MACD # stock: 股票代码 # period: history支持的周期

import numpy as npimport talib# MACDdef MACD(security_list,period='1d', fastperiod=12, slowperiod=26, signalperiod=9):# 修复传入为单只股票的情况if isinstance(security_list, str):security_list = [security_list]# 计算 MACDsecurity_data = history(slowperiod*3, period, 'close' , security_list, df=False, skip_paused=True)macd_DIF = {}; macd_DEA = {}; macd_HIST = {}for stock in security_list:nan_count = list(np.isnan(security_data[stock])).count(True)if nan_count == len(security_data[stock]):log.info("股票 %s 输入数据全是 NaN,该股票可能已退市或刚上市,返回 NaN 值数据。" %stock)macd_DIF[stock] = array([np.nan])macd_DEA[stock] = array([np.nan])macd_HIST[stock]= array([np.nan])else:macd_DIF[stock], macd_DEA[stock], macd = talib.MACDEXT(security_data[stock], fastperiod=fastperiod, fastmatype=1, slowperiod=slowperiod, slowmatype=1, signalperiod=signalperiod, signalmatype=1)macd_HIST[stock] = macd * 2return macd_DIF, macd_DEA, macd_HISTmacd_DIF, macd_DEA, macd_HIST = MACD(['600741.XSHG','600507.XSHG'],period='5m')

国内sma算法(与talib不一致)¶

def SMA(security_list, timeperiod=5) :# 修复传入为单只股票的情况if isinstance(security_list, str):security_list = [security_list]# 计算 SMAsecurity_data = history(timeperiod*2, '1d', 'close' , security_list, df=False, skip_paused=True)sma = {}for stock in security_list:close = np.nan_to_num(security_data[stock])sma[stock] = reduce(lambda x, y: ((timeperiod - 1) * x + y) / timeperiod, close)return sma

剔除上市不满一年的次新股¶

剔除上市不满一年的次新股(count设置为365天,注意不是交易日,而是自然日)

import datetimedef get_filter_timedelta_stocks(stock_list, date=None,count=365):if isinstance(date,str):date = datetime.datetime.strptime(date, "%Y-%m-%d").date()if isinstance(date,datetime.datetime):date=date.date()the_day = date-datetime.timedelta(days=count)new_list=[s for  s in stock_list if get_security_info(s).start_date <the_day]return new_listget_filter_timedelta_stocks(['600741.XSHG'], date='2018-01-01')a =datetime.datetime.now()get_filter_timedelta_stocks(['600741.XSHG'], date=a)
['600741.XSHG']

分时走势图的黄线(均价线)¶

def get_yellow_line(code,date,w=1):'''输入:股票 , 查询日期 ,每点价值(股票为1,如IF为300)'''p_date = date-datetime.timedelta(days=1)df = get_price(code,end_date=str(date)[:10]+' 15:10:00',start_date=str(p_date)+' 15:10:00',   frequency='1m',fields=['volume','money'])cum = df.iloc[:,-2:].cumsum()return cum['money']/cum['volume']/w
code='IF1812.CCFX'date = datetime.date(2018,12,5)*g = get_yellow_line(code,date,300)data = get_price(code,end_date='2018-12-06',count=240 ,frequency='1m',fields='close')data['*g']=*gindex = data.indexpydate_array = index.to_pydatetime()date_only_array = np.vectorize(lambda s: s.strftime('%Y-%m-%d %H:%M:%S'))(pydate_array ) #将datetimeindex转为strdata.index = date_only_arraydata.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x7fa6c81dd950>

日内每x分钟运行¶

每隔x分钟运行一次,用于日内交易,在初始化函数中执行run_time并定义需要定时的函数run_min,*研究可以查看策略截图

def initialize(context):run_time(30)#每30分钟运行一次def run_time(x):datas = get_price('000300.XSHG',count=240,frequency='1m').index.tolist()[:-1]#剔除15:00times = [str(t)[-8:] for t in datas]times.insert(0,'09:30:00')for t in times[::x]:run_daily(run_min, t)def run_min(context):'''需要运行的函数或代码放在这里'''print 'run'


时间段内运行/时间点运行¶

#策略选择分钟频率,在handle_data(或其他定时运行函数)的开始加上下述判断:def handle_data(context, data):now_time = context.current_dt.strftime('%H:%M:%S')'''在10:00:00以后每分钟执行'''if now_time<='10:00:00':  #return# '''在10:00以后,11:30之前每分钟执行'''# if now_time<='10:00:00' or now_time>='11:30:00': #     return# '''在10:00时执行一次'''# if now_time !='10:00:00':#     returnprint '执行'

根据大盘指数跌幅进行止损【回测专用】¶

# 根据大盘指数跌幅进行止损def index_stoploss_diefu(index, context, n=10, zs=0.03):'''    当大盘N日内跌幅超过zs,则清仓止损    '''if len(context.portfolio.positions)>0:hist = attribute_history(index, n, '1d', 'close',df=False)if ((1-float(hist['close'][-1]/hist['close'][0])) >= zs):log.info('大盘触及止损线,清仓!')for stock in context.portfolio.positions.keys():order_target_value(stock, 0)

缠论K线包含关系处理¶

输入:股票历史数据的dataframe,含有‘high’,‘low’的股票历史数据,聚宽的获取价格的接口得出的数据就OK 输出:增加了label_k,label_high,label_low列信息的股票历史数据dataframe 进行K线的包含关系处理,再原dataframe数据表中增加label列进行是否有效的标记,增加两列记录合并K线后的最值 其中,label_k的值为1时是上升K线,为-1时是下降K线,为0时,是包含关系的K线

def label_k_func(df):#进行K线的包含关系处理,再原dataframe数据表中增加label列进行是否有效的标记,增加两列记录合并K线后的最值h=df['high'].valuesl=df['low'].valuesdf['t']=pd.Series(range(len(df)),index=df.index)t=df['t'].valueslabel=[1]h_jizhi,l_jizhi=h[0],l[0]high_new=[h[0]]low_new=[l[0]]#标记K线的有效性,上升K线为1,下降为-1,无效为0for i in t[1:]:#缠论上升K线的定义if h[i]>h_jizhi and l[i]>l_jizhi:label.append(1)h_jizhi=max(h[i],h[i-1])l_jizhi=max(l[i],l[i-1])#缠论下降K线的定义elif h[i]<h_jizhi and l[i]<l_jizhi:label.append(-1)h_jizhi=min(h[i],h[i-1])l_jizhi=min(l[i],l[i-1])#包涵K线的处理else:label.append(0)#下面的内容主要是进行极值的更新for j in label[::-1]:if j != 0:a=jbreakif a==1:h_jizhi=max(h[i],h_jizhi)l_jizhi=max(l[i],l_jizhi)else:h_jizhi=min(h[i],h_jizhi)l_jizhi=min(l[i],l_jizhi)high_new.append(h_jizhi)low_new.append(l_jizhi)#把结果添加到dfdf['label_k']=pd.Series(label,index=df.index)df['high_k']=pd.Series(high_new,index=df.index)df['low_k']=pd.Series(low_new,index=df.index)return df

设置pandas的最大显示行数,列数¶

import pandas as pd# 设定最大显示行数、列数为10000pd.set_option('display.max_rows', 10000)pd.set_option('display.max_columns', 10000)pd.set_option('display.width', 10000)

将array数据格式转为dataframe¶

import pandas as pdar = get_ticks('000001.XSHE',end_dt='2018-10-08 09:31:00',count=20)df = pd.DataFrame(ar)l = df['time'].values.tolist()s = ['%.2f'%(x) for x in l]t = [o[:4]+'-'+o[4:6]+'-'+o[6:8]+' '+o[8:10]+':'+o[10:12]+':'+o[12:] for o in s]df.time = pd.to_datetime(t)df =df.set_index('time')df

currenthighlowvolumemoney
time




2018-10-08 09:25:0310.7010.710.703677939353530
2018-10-08 09:30:0310.6910.710.696194466226210
2018-10-08 09:30:0610.6910.710.697303678079410
2018-10-08 09:30:0910.6810.710.687504180222162
2018-10-08 09:30:1210.6810.710.688101486585682
2018-10-08 09:30:1510.6810.710.688252488198194
2018-10-08 09:30:1810.6710.710.678597091865930
2018-10-08 09:30:2110.6710.710.678668892631786
2018-10-08 09:30:2410.6710.710.678751193509818
2018-10-08 09:30:2710.6810.710.678985196006810
2018-10-08 09:30:3010.6610.710.669214898457394
2018-10-08 09:30:3310.6710.710.669295499317674
2018-10-08 09:30:3610.6710.710.6697921104614946
2018-10-08 09:30:3910.6610.710.66100357107211642
2018-10-08 09:30:4210.6510.710.65105101112264002
2018-10-08 09:30:4510.6510.710.65109210116640018
2018-10-08 09:30:4810.6510.710.65112644120296442
2018-10-08 09:30:5110.6610.710.65118232126247330
2018-10-08 09:30:5410.6510.710.65120726128905386
2018-10-08 09:30:5710.6510.710.65121949130208594
ar = get_bars('600741.XSHG',end_dt='2018-09-14 14:50:00',count=5,fields=['date','close','open'],  unit='30m',include_now=True)pd.DataFrame(ar).set_index('date')

closeopen
date

2018-09-14 11:30:0020.3520.36
2018-09-14 13:30:0020.3820.34
2018-09-14 14:00:0020.4120.38
2018-09-14 14:30:0020.3720.41
2018-09-14 14:50:0020.3520.40

多个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


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.00182.99912018-08-16
2018-06-30600507.XSHG19.985619.72032018-08-18
#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

20052006200720082009...20122013201420152016










inc_returnroeinc_returnroeinc_returnroeinc_returnroeinc_returnroe...inc_returnroeinc_returnroeinc_returnroeinc_returnroeinc_returnroe
000001.XSHE6.87346.386821.284922.602526.770827.20574.24354.176126.794227.2887...16.931616.953715.406415.472416.328016.295914.978314.953012.432112.4283
000527.XSHE13.349013.330015.766716.390826.317929.823024.726422.368126.261926.6314...16.238316.5337NaNNaNNaNNaNNaNNaNNaNNaN
600875.XSHG34.141834.031422.720157.133116.266647.253156.74906.702030.238228.6972...13.733214.864913.427614.08036.24366.86541.48522.0616-8.9718-8.0745
600880.XSHG18.174018.563421.319812.354819.854320.219918.975519.920320.902822.6681...13.173113.225811.446311.78528.00767.90880.77652.0698-0.71191.6685
600970.XSHG15.808817.516314.840430.903025.128128.233643.416430.684648.438447.1297...16.346517.0652-0.57512.02482.23353.40418.911912.20164.36957.6902

5 rows × 24 columns

panel数据可视化(转dataframe)¶

panel = get_price(['600741.XSHG','600507.XSHG'],count=10)df = panel.to_frame()df#df转panel用 to_frame  具体参数自行百度


closehighlowmoneyopenvolume
majorminor





2015-12-18600741.XSHG14.5714.7114.4724989451214.6417143017
600507.XSHG5.405.465.281192990165.3422172918
2015-12-21600741.XSHG15.0015.0614.4556106265614.4737628777
600507.XSHG5.445.485.341205790725.4422289871
2015-12-22600741.XSHG15.0515.1214.8235648192015.0123841678
600507.XSHG5.555.555.371163080715.4421159089
2015-12-23600741.XSHG15.0515.4815.0152601356815.0734589435
600507.XSHG5.525.565.401072556325.5519548463
2015-12-24600741.XSHG15.1615.2514.7233607955215.1222449441
600507.XSHG5.415.525.33558604805.4610315692
2015-12-25600741.XSHG15.1815.3015.0019829269315.1913086915
600507.XSHG5.515.535.34881824325.4016201856
2015-12-28600741.XSHG14.6915.3114.6632297829515.2321620409
600507.XSHG5.315.505.28950836815.4817572145
2015-12-29600741.XSHG14.7614.9814.6024076108614.7316316632
600507.XSHG5.345.345.18548721345.2810410516
2015-12-30600741.XSHG14.7714.9214.6224720772314.8116758734
600507.XSHG5.345.365.27419957595.347885443
2015-12-31600741.XSHG14.6014.8614.5818909987114.7412879952
600507.XSHG5.255.405.24724330625.3413627293

剔除过去N天停牌超过X日的股票¶

def set_stock(stock_list,end_date,N=63,X =0):'''默认剔除过去3个月有过停牌的股票'''datas = get_price(stock_list,end_date=end_date,fields=['paused'], skip_paused=False, fq='pre', count=N)f = datas.to_frame()g=f[f.iloc[:,0]==1].unstack()['paused']i =N-g.isnull().sum()t = i[i>X].index.tolist()   new_stock_list = list(set(stock_list) ^ set(t))return new_stock_liststocks = get_all_securities().index.tolist()set_stock(stocks,'2018-09-28')[:5]
['002233.XSHE', '603809.XSHG', '002897.XSHE', '002596.XSHE', '600387.XSHG']

移动窗口(rolling)和 拓展窗口(expanding)¶

注意这两个函数可以解决很多指标问题并简化代码减少重复计算,如MA等,还有rolling_apply等函数,可以适当了解一下¶

注意区分pandas版本,不同版本的用法及参数,目前0.23是兼容0.16的(官网研究默认环境和回测都是0.16,pacver版本为0.23):


rolling 是对窗口进行移动处理,窗口大小自定义,大小不变

expanding是对窗口进行拓展处理,窗口大小不断变大

import pandas as pdc_data = get_price(['600741.XSHG','600507.XSHG','000001.XSHE'],fields='high',end_date='2018-09-26',count=100).high
# 求序列的HHV5pd.rolling_max(c_data,window=5,min_periods=None, freq=None, center=False, how='max')[5:10] #pandas0.16用法 # c_data.rolling(window=5, min_periods=None, freq=None, center=False, win_type=None, on=None, #                axis=0, closed=None).max()  #pandas 0.23用法

600741.XSHG600507.XSHG000001.XSHE
2018-05-1524.0813.6211.06
2018-05-1624.0813.6211.06
2018-05-1724.0813.6211.06
2018-05-1824.0813.6211.06
2018-05-2124.3513.5611.02
#求序列过去一段时间所产生的历史最高价序列pd.expanding_max(c_data,min_periods=0, freq=None).head() #pandas0.16用法 # c_data.expanding(min_periods=1, freq=None).max()  #pandas 0.23用法

600741.XSHG600507.XSHG000001.XSHE
2018-05-0823.7913.6210.98
2018-05-0923.7913.6210.98
2018-05-1023.8413.6210.98
2018-05-1123.8413.6210.98
2018-05-1424.0113.6211.06
#求序列的 MA5 序列pd.rolling_mean(c_data,window=5,min_periods=None, freq=None, center=False, how='max')[-5:]

600741.XSHG600507.XSHG000001.XSHE
2018-09-1920.11410.6769.962
2018-09-2020.12610.72810.016
2018-09-2120.41210.81410.182
2018-09-2520.70610.91010.354
2018-09-2621.05410.95410.480

简单的ema计算¶

import pandas as pd#注意ema有用到回溯算法,所以出于指标精度方面考虑建议数据的长度至少为span的2-3倍,且前期数据可能不太准确,如需使用到更多ema数据#需要增加依赖数据的长度c_data = get_price(['600741.XSHG','600507.XSHG','000001.XSHE'],fields='close',end_date='2018-09-26',   fq=None,count=10*3).closepd.ewma(c_data,span=5)[-5:]

600741.XSHG600507.XSHG000001.XSHE
2018-09-1920.14072710.75282210.026004
2018-09-2020.12048410.78188210.094004
2018-09-2120.67699610.86792210.286005
2018-09-2520.90799910.89194810.374004
2018-09-2621.21200110.96129910.486003

量比¶

#计算结果与行情软件有稍许差异,对比数据没有问题 ,经过验证是由计算精度引起的(交易软件的成交量精度),实际上平台的结果是更准确的def get_v_ratio(security_list,time):'''计算某个时间点股票的量比,    输入:股票池/股票,时间(datetime)    返回:截至当天某一时间点的量比'''if isinstance(security_list,str):security_list = [security_list]d = {}time2= time-datetime.timedelta(days=1)start_time = datetime.datetime(time.year,time.month,time.day,9,30)for security in security_list:ma5 = get_price(security,end_date=time2,frequency='5d',skip_paused=True,fields='volume',count=1).volume/1200n_ma = get_price(security,end_date=time,start_date =start_time ,skip_paused=True,fields='volume',  frequency='1m').volume.mean()d[security]=float(n_ma/ma5)#     print start_time,timereturn dsecurity_list = ['600016.XSHG','601166.XSHG','000001.XSHE']time = datetime.datetime(2018,9,27,15,30)get_v_ratio(security_list,time)
{'000001.XSHE': 0.7405546291120892,
 '600016.XSHG': 0.8102664114217498,
 '601166.XSHG': 0.8697879043965755}
#使用新浪数据 000001.XSHE 在 2018年9月27日的数据计算的结果:round((88.04/240)/(594.38/1200),2)
0.74

DatetimeIndex 转 strindex (解决绘图非交易时间自动补全) 以及绘图正常显示问题¶

当用pandas绘图时,当index为datetimeindex时会自动根据横轴(index)进行补全,导致出现非交易时间而出现绘图跳空: 方法1:https://blog.csdn.net/tpoy0099/article/details/49511907 方法2:

import matplotlib.pyplot as plt# plt.rcParams['font.sans-serif']=['SimHei'] # 标签mpl.rcParams['font.family']='serif' #用来正常显示中文plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
df = get_price('600741.XSHG',end_date='2018-09-27 09:50:00',frequency='1m',count=50,fields='close')df.plot()print type(df.index)  #会出现问题的绘图方法:
<class 'pandas.tseries.index.DatetimeIndex'>

将index转为str类型:

import pandas as pdimport numpy as npdf = get_price('600741.XSHG',end_date='2018-09-27 09:50:00',frequency='1m',count=50,fields=['close','volume'],skip_paused=True)index = df.indexpydate_array = index.to_pydatetime()date_only_array = np.vectorize(lambda s: s.strftime('%Y-%m-%d %H:%M:%S'))(pydate_array ) #将datetimeindex转为strdf.index = date_only_arrayprint type(df.index)plt.axhline(21.8, color="black", linestyle="-") #绘制轴线df.volume.plot(secondary_y = True,kind='bar',legend=True) df.close.plot(figsize=(15,5),grid=True,rot =50,fontsize=10,title='正常显示',legend=True,  style='r') #通过多次绘制series和secondary_y绘制右刻度,grid显示网格,rot控制标签斜率,fontsize控制字体大小,style控制颜色,legend显示标注
<class 'pandas.core.index.Index'>
<matplotlib.axes._subplots.AxesSubplot at 0x7f04e42e2a50>

解决中文显示(只解决显示问题):¶

luanma = get_all_securities().display_name.values

其实这只是python2的显示问题,只能曲线救国,其实如果只是查看某个list的内容,建议转化成其他形式(如dataframe)而非list, 当然还可以直接切换到python3内核:

import pandas as pdpd.DataFrame(luanma).head()

0
0平安银行
1万科A
2国农科技
3世纪星源
4深振业A
print luanma  #输出显示乱码print type(luanma[0]) #检查为unicode类型print luanma[0] #单个用print输出正常right_str = str(luanma).replace('u\'','\'').decode("unicode-escape")  #可以用print输出,但类型变为unicode而非listprint type(right_str)print right_str
[u'\u5e73\u5b89\u94f6\u884c' u'\u4e07\u79d1A' u'\u56fd\u519c\u79d1\u6280'
 ..., u'\u7ee7\u5cf0\u80a1\u4efd' u'\u65b9\u76db\u5236\u836f'
 u'\u8bfb\u8005\u4f20\u5a92']
<type 'unicode'>
平安银行
<type 'unicode'>
['平安银行' '万科A' '国农科技'
 ..., '继峰股份' '方盛制药'
 '读者传媒']

查询股息率(近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')date='2018-01-01'DividendRatio(securitys,date)
<class 'pandas.core.panel.Panel'>
Dimensions: 1 (items) x 1 (major_axis) x 500 (minor_axis)
Items axis: DividendRatio to DividendRatio
Major_axis axis: 2017-12-29 00:00:00 to 2017-12-29 00:00:00
Minor_axis axis: 000007.XSHE to 300735.XSHE

期货合约每点价位¶

from jqdata import jy#期货合约每点价位 =   ContractMulti*PriceUnit 注意统一单位q = query(jy.Fut_FuturesContract ).filter(jy.Fut_FuturesContract.Exchange.in_([10,11,13,15,19,20]),#                  jy.Fut_FuturesContract.TradingCode=='JD' )jy.run_query(q).tail()

IDContractNameContractOptionExchangeTradingCodeContractTypeContractMultiPriceUnitLittlestChangeUnitChangePCTLim...FinalSettlementPriceDeliveryMethodContractIntroductionUpdateTimeJSIDContractInnerCodeNightTradingTimeContractStateDeliveryUnitDeliveryUnitValue
54471516344473玉米淀粉33213CS110吨/手元(人民币)/吨1元/吨上一交易日结算价的4%\r\n...
1交易品种\t玉米淀粉\r\n交易单位\t10吨/手\r\n报价单位\t元(人民币)/吨\r\...2018-08-02 14:32:525865355731222005826None1NoneNone
55551911961044原油31911SC11000桶/手元(人民币)/桶(交易报价为不含税价格)0.1元(人民币)/桶不超过上一交易日结算价±4%...
1交易品种  中质含*原油\r\n交易单位  1000桶/手\r\n报价单位  元(人民币)/...2018-08-02 14:32:52586535573123200859621:00-次日02:301NoneNone
56451415224875早籼稻41215RI120吨/手元(人民币)/吨1元/吨上一交易日结算价±4%及《郑州商品交易所期货交易风险控制管理办法》相关规定\r\n...
1交易品种\t早籼稻\r\n交易单位\t20吨/手\r\n报价单位\t元(人民币)/吨\r\n...2018-08-02 14:32:525865355731242005502None1NoneNone
57562352751053中证500指数497820IC4每点200元指数点0.2点上一个交易日结算价的±10%...股指期货交割结算价为最后交易日标的指数最后二小时的算术平均价。交易所有权根据市场情况对股指期...2合约标的 \t中证500指数 \r\n合约乘数 \t每点200元 \r\n报价单位 \t指数...2018-08-02 14:32:525865355731272006035None1NoneNone
58347714139750棕榈油34913P110吨/手元(人民币)/吨2元/吨上一交易日结算价的4% \r\n...
1交易品种\t棕榈油\r\n交易单位\t10吨/手\r\n报价单位\t元(人民币)/吨\r\n...2018-08-02 14:32:525865355731282000026前一自然日21∶00至前一自然日23∶30(周一夜盘交易时段为上周五的21∶00至上周五的2...1NoneNone

5 rows × 30 columns

查询申万行情( 包含行业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()


ChiNamePrevClosePriceOpenPriceHighPriceLowPriceClosePriceTurnoverVolumeTurnoverValueTurnoverDealsChangePCTRightLevelIndexPEIndexPBTotalMarketValueAShareTotalMV
TradingDaySecuCode














2017-12-29801011申银万国指数-林业1800.0921795.4801845.601784.411802.798285323235547011NaN0.00154777.373.1320361291121708
801012申银万国指数-农产品加工2551.7762546.6002573.802515.612556.512936709651234257297NaN0.0019435.583.12145293207936090
801013申银万国指数-农业综合2269.6102260.5302278.202254.302272.480908494542341246NaN0.00134125.712.92867493464852
801014申银万国指数-饲料3644.5203646.5683709.263610.053685.3501339281571452712964NaN0.0112423.782.71210275658124732
801015申银万国指数-渔业1540.1781535.7481566.711528.661555.76034618204301252413NaN0.0101443.952.5252177222511131

中证指数pe/股息率¶

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='2018-01-01',count=10)panel.ClosePrice.tail()
SecuCode000001000016
TradingDay

2017-12-253280.46102880.0968
2017-12-263306.12462894.3358
2017-12-273275.78282839.6346
2017-12-283296.38472859.0537
2017-12-293307.17212860.4363

获取所有商品指数,主力合约,品种代号等¶

df = get_all_securities(types=['futures'])                       #获取期货合约# dominant_and_idnex = df[df.end_date==datetime.date(2030,1,1)]  #商品指数和主力合约dominant_future = [d for d in df.index if '9999' in d]           #所有品种的主力合约index_future = [i for i in df.index if '8888' in i]              #所有品种的指数代码code_name = [c[:-9] for c in index_future]                       #获取各个品种代号,使用get_dominant_future时会用到

字典转dataframe/panel¶

#2层的嵌套字典可以转为dataframe,3层的嵌套字典可以转为panel方便后续的数据处理,下边以个股的所属行业数据为例from jqdata import *import pandas as pdstocks = get_index_stocks('000300.XSHG')industry_dict = get_industry(stocks)panel = pd.Panel(industry_dict)panel[:,'industry_code' ]

000001.XSHE000002.XSHE000060.XSHE000063.XSHE000069.XSHE000100.XSHE000157.XSHE000166.XSHE000333.XSHE000338.XSHE...601992.XSHG601997.XSHG601998.XSHG603160.XSHG603260.XSHG603288.XSHG603799.XSHG603833.XSHG603858.XSHG603993.XSHG
jq_l1HY007HY011HY002HY008HY004HY004HY003HY007HY004HY003...HY002HY007HY007HY008HY002HY005HY002HY004HY006HY002
jq_l2HY493HY509HY414HY516HY457HY446HY426HY501HY449HY426...HY410HY494HY493HY524HY405HY481HY414HY447HY572HY414
sw_l1801780801180801050801770801180801110801890801790801110801880...801230801780801780801080801050801120801050801140801150801050
sw_l2801192801181801055801102801181801112801074801193801111801093...801231801192801192801081801051801124801054801142801155801054
sw_l3851911851811850553851013851811851121850722851931851112850921...852311851911851911850811850523851242850544851432851521850544
zjwJ66K70C32C39K70C39C35J67C38C36...C30J66J66C39C26C14C32C21C27B09

6 rows × 300 columns

数据库/dataframe的模糊查询¶

在获取报告期数据时,因为有些报表是增量性质的,这个季度无法和上个季度进行对比,所以大多数是与上年进行同比,下面以获取中报数据为例:

from jqdata import finance# 获取000001.XSHG每一年的年报   df = finance.run_query(query(finance.FINANCE_INCOME_STATEMENT   ).filter(finance.FINANCE_INCOME_STATEMENT.code=='000001.XSHE',finance.FINANCE_INCOME_STATEMENT.end_date.like('%-06-30'),#或end_date.contains('12-31') ,end_date.like('_____12-31'),#                 finance.FINANCE_INCOME_STATEMENT.pub_date>='2015-01-01',finance.FINANCE_INCOME_STATEMENT.report_type==0   ))df.tail()

idcompany_idcompany_namecodea_codeb_codeh_codepub_datestart_dateend_date...net_profitnp_parent_company_ownersminority_profitepsbasic_epsdiluted_epsother_composite_incometotal_composite_incomeci_parent_company_ownersci_minority_owners
202539430000001平安银行股份有限公司000001.XSHE000001NoneNone2014-08-142014-01-012014-06-30...1.007200e+101.007200e+10NaNNaN0.880.883.100000e+081.038200e+10NaNNaN
212547430000001平安银行股份有限公司000001.XSHE000001NoneNone2015-08-142015-01-012015-06-30...1.158500e+101.158500e+10NaNNaN0.840.843.940000e+081.197900e+10NaNNaN
222555430000001平安银行股份有限公司000001.XSHE000001NoneNone2016-08-122016-01-012016-06-30...1.229200e+101.229200e+10NaNNaN0.720.721.440000e+081.243600e+101.243600e+10NaN
232562430000001平安银行股份有限公司000001.XSHE000001NoneNone2017-08-112017-01-012017-06-30...1.255400e+101.255400e+10NaNNaN0.680.683.160000e+081.287000e+101.287000e+10NaN
244321430000001平安银行股份有限公司000001.XSHE000001NoneNone2018-08-162018-01-012018-06-30...1.337250e+101.337250e+10NaNNaN0.730.734.557387e+081.382824e+101.382824e+10NaN

5 rows × 66 columns

df = get_all_securities()df[df.display_name.str.contains('证券',regex=False)] #挑选出display_name中含有'证券'字的行

display_namenamestart_dateend_datetype
000562.XSHE宏源证券HYZQ1994-02-022015-01-26stock
000686.XSHE东北证券DBZQ1997-02-272200-01-01stock
000728.XSHE国元证券GYZQ1997-06-162200-01-01stock
000750.XSHE国海证券GHZQ1997-07-092200-01-01stock
000776.XSHE广发证券GFZQ1997-06-112200-01-01stock
000783.XSHE长江证券CJZQ1997-07-312200-01-01stock
002500.XSHE山西证券SXZQ2010-11-152200-01-01stock
002673.XSHE西部证券XBZQ2012-05-032200-01-01stock
002736.XSHE国信证券GXZQ2014-12-292200-01-01stock
002926.XSHE华西证券HXZQ2018-02-052200-01-01stock
002939.XSHE长城证券CCZQ2018-10-262200-01-01stock
600030.XSHG中信证券ZXZQ2003-01-062200-01-01stock
600109.XSHG国金证券GJZQ1997-08-072200-01-01stock
600369.XSHG西南证券XNZQ2001-01-092200-01-01stock
600837.XSHG海通证券HTZQ1994-02-242200-01-01stock
600909.XSHG华安证券HAZQ2016-12-062200-01-01stock
600958.XSHG东方证券DFZQ2015-03-232200-01-01stock
600999.XSHG招商证券ZSZQ2009-11-172200-01-01stock
601108.XSHG财通证券CTZQ2017-10-242200-01-01stock
601162.XSHG天风证券TFZQ2018-10-192200-01-01stock
601198.XSHG东兴证券DXZQ2015-02-262200-01-01stock
601375.XSHG中原证券ZYZQ2017-01-032200-01-01stock
601377.XSHG兴业证券XYZQ2010-10-132200-01-01stock
601555.XSHG东吴证券DWZQ2011-12-122200-01-01stock
601688.XSHG华泰证券HTZQ2010-02-262200-01-01stock
601788.XSHG光大证券GDZQ2009-08-182200-01-01stock
601878.XSHG浙商证券ZSZQ2017-06-262200-01-01stock
601901.XSHG方正证券FZZQ2011-08-102200-01-01stock
601990.XSHG南京证券NJZQ2018-06-132200-01-01stock

研究中进行性能分析¶

from line_profiler import LineProfilerimport randomdef do_stuff(a,b):s = sum(1000)l = [numbers[i]/43 for i in range(len(numbers))]m = ['hello'+str(numbers[i]) for i in range(len(numbers))]numbers = [random.randint(1,100) for i in range(1000)]lp = LineProfiler()  lp_wrapper = lp(do_stuff)    #函数lp_wrapper(numbers,100)         #写入参数运行,如果没有参数括号中就无需内容lp.print_stats()            #显示
Timer unit: 1e-06 s

Total time: 0.002667 s
File: <ipython-input-60-cae2cba1719c>
Function: do_stuff at line 4

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     4                                           def do_stuff(a,b):
     5         1           89     89.0      3.3      s = sum(1000)
     6      1001         1309      1.3     49.1      l = [numbers[i]/43 for i in range(len(numbers))]
     7      1001         1269      1.3     47.6      m = ['hello'+str(numbers[i]) for i in range(len(numbers))]

区间换手率¶

from jqdata import *def shuttle_turnover_ratio(code_list,end_date,start_date=None,day=None):'''start_date和day 二选一 , 选取day参数时代表day个交易日的区间换手率'''if not day:day = len(get_trade_days(start_date,end_date))if isinstance(code_list,str):code_list=[code_list]q = query(valuation.turnover_ratio).filter(valuation.code.in_(code_list))return get_fundamentals_continuously(q,end_date=end_date,count=day).turnover_ratio.sum()shuttle_turnover_ratio(['600741.XSHG','000002.XSHE'],'2018-11-13','2018-10-01')
code
000002.XSHE    16.2519
600741.XSHG    10.6901
dtype: float64
 

全部回复

0/140

量化课程

    移动端课程