目录
每月/每周的 (倒数) 第N个交易日
计算拥挤率
计算价格相关性
统计历史上N只乌鸦出现的次数
日内走势编码
计算RSI
def get_before_after_trade_days(date, count, is_before=True):
"""
date :查询日期
count : 前后追朔的数量
is_before : True , 前count个交易日 ; False ,后count个交易日
返回 : 基于date的日期, 向前或者向后count个交易日的日期 ,一个datetime.date 对象
"""
from jqdata import get_trade_days
import pandas as pd
all_date = pd.Series(get_all_trade_days())
if isinstance(date,str):
all_date = all_date.astype(str)
if isinstance(date,datetime.datetime):
date = date.date()
if is_before :
return all_date[all_date< date].tail(count).values[0]
else :
return all_date[all_date>date].head(count).values[-1]
date = "2019-10-20"#datetime.date(2019,10,20)
count = 10
is_before = False
get_before_after_trade_days(date, count, is_before)
import pandas as pd
from jqdata import *
def get_trade_day_bar(unit='W' , n=1 ,start_date=None,end_date=None,count=None):
"""
unit : 频率 , "W"代表周 或者 "M"代表月
n : 第几个交易日 , 每月第一个交易日: n=1 , 每月最后一个交易日 : n= -1 ,每月倒数第三个交易日 : n= -3 , 如果不足abs(n)个交易日,则返回符合条件的最近的一个交易日
start_date : 开始时间
end_date : 结束时间
count : 返回数据条数 , 指定start_date及count时返回start_date向后count条数据 , 指定end_date及count时返回end_date向前count条数据
返回的数据会在 get_all_trade_days 以内
返回 : 一个dataframe ,具体列含义见源码, date列就是需要获取的交易日了(datetime格式)
"""
df = pd.DataFrame(pd.to_datetime(get_all_trade_days()),columns=['date'])
week_stamp = 24*60*60*7
day_stamp = 24*60*60
df['timestamp'] = df.date.apply(lambda x: x.timestamp() - day_stamp*3 ) #基于1970-01-01偏移三天
df['mkweek'] = df.timestamp // week_stamp # 1970-01-01 至今的第几周, 直接取每年的第几周再换年时会有问题
df['weekday'] = (df.timestamp % week_stamp)/day_stamp #周几
df['monthday'] = df.date.apply(lambda x : x.day) #日
df['month'] = df.date.apply(lambda x : x.month) #月
df['year'] = df.date.apply(lambda x : x.year) #年
if unit == "W":
group_list = ['mkweek']
elif unit =="M":
group_list = ["year","month"]
else :
raise ValueError ('只支持M参数为 "M"或"W" ')
if not isinstance(n , int):
raise ValueError ('n 参数应该是一个int')
elif n >0 :
res = df.groupby(group_list,as_index=False).head(n).groupby(group_list,as_index=False).last()
elif n< 0:
res = df.groupby(group_list,as_index=False).tail(-n).groupby(group_list,as_index=False).first()
else :
raise ValueError ('n 参数错误 : n={}'.format(n))
if start_date and end_date and count:
raise ValueError ('start_date ,end_date ,count 必须三选二')
elif start_date and count :
return res[res.date>=start_date].head(count)
elif end_date and count :
return res[res.date<= end_date].tail(count)
elif start_date and end_date:
return res[(res.date<= end_date) & (res.date>=start_date)]
elif not start_date and not end_date and not count:
return res
else:
raise ValueError ('start_date ,end_date ,count 必须三选二')
res = get_trade_day_bar("W",1,count=10,start_date='2015-09-15')
res
def crowd(date):
stocks=list(get_all_securities(date=date).index)
h = get_price(stocks, end_date=date, frequency='1d',fields='money',count=1, panel=False).pivot(index='code',columns='time',values='money')
s2 = h.dropna().sort_values(by=h.columns[0],ascending=False)
crowd5=((100 * s2.iloc[:len(s2)//20].sum()) / s2.sum()).iloc[0]
crowd10=((100 * s2.iloc[:len(s2)//10].sum()) / s2.sum()).iloc[0]
return crowd5,crowd10
def Relate(data_list1,data_list2,diff=0,timeperiod=10):
# datalist 价格列表
# diff ==1 计算价差的相关性
if len(data_list1)!=len(data_list2):
return 0
else:
days=len(data_list1)
a1=np.array(data_list1)
a2=np.array(data_list2)
#价格相关性
if diff==0:
relate=[np.nan]*(timeperiod-1)
for i in range(timeperiod,days+1):
relate.append(np.corrcoef(a1[i-timeperiod:i]/a1[i-timeperiod],a2[i-timeperiod:i]/a2[i-timeperiod])[0,1])
#价差相关性
if diff==1:
dif1=(a1[1:]-a1[:-1])/a1[:-1]
dif2=(a2[1:]-a2[:-1])/a2[:-1]
relate=[np.nan]*timeperiod
for i in range(timeperiod,days):
relate.append(np.corrcoef(dif1[i-timeperiod:i],dif2[i-timeperiod:i])[0,1])
return relate
def count_N_crow(index,today,days,N=3): #N只乌鸦
#index 代码
#查询日期
#days 查询天数
if N<2:
return 0
else:
results=pd.DataFrame(columns=['date','1day','5day'])
count=0
prices= get_price(index,end_date=today, count=days,frequency='1d',fields=['close','open'])
dates=prices.index
for i in range (len(dates)-N):
nc=0
while(ncprices.iloc[i+nc+1,0]:
nc +=1
else:
break
if nc==N-1:
no=0
while(no
def inday_trade_tend(stock,field,date):
#stock 代码
#field 域
scores=[]
daily=get_price(stock,end_date=date,count=2, frequency='1d',skip_paused=True , fields=[field],fq='pre')
minutes=get_price(stock,end_date=date,count=240, frequency='1m', fields=[field],fq='pre')
if field=='volume':
pre=daily.iloc[0,0]/240
else:
pre=daily.iloc[0,0]
means=[]
score=0
means.append(mean(minutes.iloc[0:61,0]))
means.append(mean(minutes.iloc[61:121,0]))
means.append(mean(minutes.iloc[121:181,0]))
means.append(mean(minutes.iloc[181:,0]))
for i in range(0,4):
if means[i]<=pre*0.93:
score=score+0*6**i
elif means[i]>pre*0.93 and means[i]<=pre*0.97:
score=score+1*6**i
elif means[i]>pre*0.97 and means[i]<=pre:
score=score+2*6**i
elif means[i]>pre and means[i]<=pre*1.03:
score=score+3*6**i
elif means[i]>pre*1.03 and means[i]<=pre*1.07:
score=score+4*6**i
elif means[i]>pre*1.07:
score=score+5*6**i
scores.append(score)
return scores
def RSI(stock,start_date,end_date,timeperiod=6):
#日期换算,由于RSI累计时间越长越准确,因此从计算周期前150天开始算
date_s1 = datetime.datetime.strptime(start_date,'%Y-%m-%d')
date_s2 =date_s1 - datetime.timedelta(days = 150)
return_days=len(get_trade_days(start_date=start_date,end_date=end_date))
daily_price=get_price(stock, start_date=date_s2,end_date=end_date, frequency='1d', fields=['close'], skip_paused=False, fq='pre')
dates=daily_price.index
days=len(dates)#此处的日期包含了计算周期+150天
close=np.array(daily_price['close'])
diff=list(close[1:days]-close[0:days-1])
diff.insert(0, 0)
A=0
B=0
rsi=[0]*(timeperiod+1)
aA=[0]*(timeperiod+1)
aB=[0]*(timeperiod+1)
for i in range (1,timeperiod):
if diff[i]>=0:
A=A+diff[i]
else:
B=B+diff[i]
rsi[-1]=A/(A-B)*100 #计算得到第一个RSI
aA[-1]=A/timeperiod
aB[-1]=B/timeperiod
#后面的RSI都根据第一天依次计算
for i in range(timeperiod+1,days):
if diff[i]>=0:
aA.append((aA[-1]*(timeperiod-1)+ diff[i])/timeperiod)
aB.append(aB[-1]*(timeperiod-1)/timeperiod)
else:
aA.append(aA[-1]*(timeperiod-1)/timeperiod)
aB.append((aB[-1]*(timeperiod-1)+ diff[i])/timeperiod)
rsi.append(aA[-1]/(aA[-1]-aB[-1])*100)
print(return_days)
return rsi[-return_days:]
#2-1 过滤停牌股票
def filter_paused_stock(stock_list):
current_data = get_current_data()
return [stock for stock in stock_list if not current_data[stock].paused]
#2-2 过滤ST及其他具有退市标签的股票
def filter_st_stock(stock_list):
current_data = get_current_data()
return [stock for stock in stock_list
if not current_data[stock].is_st
and 'ST' not in current_data[stock].name
and '*' not in current_data[stock].name
and '退' not in current_data[stock].name]
#2-3 过滤科创北交股票
def filter_kcbj_stock(stock_list):
for stock in stock_list[:]:
if stock[0] == '4' or stock[0] == '8' or stock[:2] == '68':
stock_list.remove(stock)
return stock_list
#2-4 过滤涨停的股票
def filter_limitup_stock(context, stock_list):
last_prices = history(1, unit='1m', field='close', security_list=stock_list)
current_data = get_current_data()
return [stock for stock in stock_list if stock in context.portfolio.positions.keys()
or last_prices[stock][-1] < current_data[stock].high_limit]
#2-5 过滤跌停的股票
def filter_limitdown_stock(context, stock_list):
last_prices = history(1, unit='1m', field='close', security_list=stock_list)
current_data = get_current_data()
return [stock for stock in stock_list if stock in context.portfolio.positions.keys()
or last_prices[stock][-1] > current_data[stock].low_limit]
#2-6 过滤次新股
def filter_new_stock(context,stock_list):
yesterday = context.previous_date
return [stock for stock in stock_list if not yesterday - get_security_info(stock).start_date < datetime.timedelta(days=375)]