#encoding:gbk
import pandas as pd
import numpy as np
import statsmodels.formula as smFormula
import statsmodels.api as smApi
from operator import methodcaller
import talib as ta
import time
import datetime
def init(ContextInfo):
ContextInfo.index = ['000018.SH','000029.SH','399994.SZ']
ContextInfo.stype = 'index'
ContextInfo.accID = '410001026631'
# 定义全局参数值
ContextInfo.pastDay = 10 # 过去pastDay日参数
ContextInfo.topK = 10 # topK只股票
ContextInfo.factor_list = ['Valuation_and_Market_Cap.PE']
def handlebar(ContextInfo):
print('handlebar')
d = ContextInfo.barpos
realtime = ContextInfo.get_bar_timetag(d)
# 计算日期参数
curDate = timetag_to_datetime(realtime,'%Y%m%d')
print(curDate)
curDate = str(curDate)
tradedate = ContextInfo.get_trading_dates(stockcode = '000300.SH', start_date='', end_date = curDate ,count = ContextInfo.pastDay, period = '1d')
preDate = tradedate[0]
stocks = []
returnArr =[0]*len(ContextInfo.index)
stype = ContextInfo.stype
# 根据羊群效应选取股票
for i,eachIndex in enumerate(ContextInfo.index):
print(i,eachIndex)
returnArr = calHerdSign(ContextInfo, tradedate, eachIndex, stype, curDate, preDate)
print(returnArr)
# 避开羊群效应
if returnArr == 1:
continue
else:
oriStocks = get_stocks_list(ContextInfo, stype, eachIndex, curDate)
rpsStocks = calRPS(ContextInfo,oriStocks,curDate,preDate)
rpsStocks = list(rpsStocks[:ContextInfo.topK]['code'])
stocks += rpsStocks
data = ContextInfo.get_market_data(['close'],stock_code=stocks,skip_paused = True, period = '1d', dividend_type = 'front_ratio',count=60)
# 筛选股票:排除重复的,持股topK只
stocks = list(set(stocks))
numStocks = len(stocks)
if numStocks > ContextInfo.topK:
stocks = calRPS(ContextInfo,stocks, curDate, preDate)
stocks = list(stocks[:ContextInfo.topK]['code'])
else:
pass
numStocks = len(stocks)
# 根据候选池买卖股票
if numStocks > 0:
# 卖出操作
# 判断当前是否持有目前股票,若已持有股票在新的候选池里则继续持有,否则卖出
holdings = get_holdings(ContextInfo.accID,'STOCK')
for security in holdings:
if security in stocks:
continue
else:
order_target_percent(security, 0, 'COMPETE', ContextInfo, ContextInfo.accID)
# print("Selling %s" %(security))
# 买入操作
for security in stocks:
# 根据均线动量策略买卖股票
stdata = data[security]
stdata.dropna(how='any', axis = 0)
curPrice = stdata['close'][-1]
ma5 = ta.MA(stdata['close'], 5)[-1]
ma10 = ta.MA(stdata['close'], 10)[-1]
if curPrice > ma5 and ma5 > ma10:
# 买入该股票
# 获取股票基本信息:是否停牌、是否ST,持股头寸、股价等
pauseSign = ContextInfo.is_suspended_stock(security)
#stocksAmount = get_holdings(ContextInfo.accID,'STOCK')[security][0]
#stocksPrice = stdata['close'][-1]
cash = get_portfolio(ContextInfo.accID,'STOCK')
# 买入操作
if not pauseSign:
# 购买该股票,获得可购买的股票数量
#buyAmount = int((cash / ContextInfo.topK) / stocksPrice)
#order(security,buyAmount)
#order_shares(security, buyAmount, 'LATEST',stocksPrice,ContextInfo, ContextInfo.accID)
values = cash / ContextInfo.topK
order_value(security, values, ContextInfo, ContextInfo.accID)
#print("Buying %s" % (security))
else:
# 没有龙头股,清仓操作
for security in get_holdings(ContextInfo.accID,'STOCK'):
#order_target(security,0)
order_target_percent(security, 0, 'COMPETE', ContextInfo, ContextInfo.accID)
#print("Selling %s" %(security))
def get_holdings(accountid,datatype):
holdinglist={}
resultlist=get_trade_detail_data(accountid,datatype,"POSITION")
for obj in resultlist:
holdinglist[obj.m_strInstrumentID+"."+obj.m_strExchangeID]=obj.m_nVolume
return holdinglist
def get_portfolio(accountid,datatype):
result=0
resultlist=get_trade_detail_data(accountid,datatype,"ACCOUNT")
for obj in resultlist:
result=obj.m_dAvailable
return result
def get_stocks_list(ContextInfo, stype, index, daytime):
datetime_days = datetime.datetime.strptime(daytime, '%Y%m%d') #datetime.datetime.strptime(curDate, "%Y%m%d")
days_stamp = int(time.mktime(datetime_days.timetuple()) * 1000.0 + datetime_days.microsecond / 1000.0)#.astype(np.int64)
# 获取指数内的股票
if stype == 'index':#指数
stocks = ContextInfo.get_sector(index, days_stamp)
elif stype == 'industry':#行业分类
stocks = ContextInfo.get_industry(index)
elif stype == 'sector':#板块,左侧导航板块
stocks = ContextInfo.get_stock_list_in_sector(index, days_stamp)
elif stype == 'stock':
stocks = index #股票列表
else:
stocks = None
return stocks
# 计算相对强弱RPS值
def calRPS(ContextInfo,stockslist, curDate, preDate):
# 初始化参数信息
numStocks = len(stockslist)
rankValue = []
# 计算涨跌幅
for security in stockslist:
# 获取过去pastDay的指数值
lastDf = ContextInfo.get_market_data(['close'], stock_code = [security],
start_time = preDate, end_time = curDate, period = '1d', dividend_type = 'front_ratio')
lastDf.dropna(how='any', axis = 0, inplace=True)
#print(lastDf, type(lastDf))
if lastDf is not None and lastDf.shape[0] >0:
lastClosePrice = float(lastDf.iloc[-1])
firstClosePrice = float(lastDf.iloc[0])
if firstClosePrice != 0.0:
# 计算涨跌幅
errCloseOpen = [(lastClosePrice - firstClosePrice)/firstClosePrice]
rankValue += errCloseOpen
else:
errCloseOpen=[0.0]
rankValue += errCloseOpen
else:
rankValue =[0.0]
# 根据周涨跌幅排名
rpsStocks = {'code':stockslist,'rankValue':rankValue}
rpsStocks = pd.DataFrame(rpsStocks)
rpsStocks = rpsStocks.sort_values(by= 'rankValue',axis=0,ascending = False)
stocks = list(rpsStocks['code'])
rankValue = list(rpsStocks['rankValue'])
#print(rpsStocks)
# 计算RPS值
rpsValue = [99 - (100 * float(i)/numStocks) for i in range(numStocks)]
rpsStocks = {'code':stocks,'rpsValue':rpsValue,'rankValue':rankValue}
rpsStocks = pd.DataFrame(rpsStocks)
#print('rpsStocks', print(rpsStocks))
return rpsStocks
# 判断:是否存在羊群效应
def calHerdSign(ContextInfo, tradedate, index, stype, curDate, preDate):
# 获取pastDay内的价格
#index price
index_price = ContextInfo.get_market_data(['close'], stock_code = [index] ,
start_time = preDate, end_time = curDate, period = '1d', dividend_type = 'front_ratio')#.minor_xs('close')
stockslist = get_stocks_list(ContextInfo, stype, index, curDate)
#因子数据
factor_data = pd.DataFrame(index = tradedate)
#factor_data.index.name="date"
for stock in stockslist:
#print(factor_list1, stock, startDate, endDate)
df = ContextInfo.get_factor_data(ContextInfo.factor_list, stock, preDate, curDate)
df.index = pd.to_datetime(df.index, unit='ms', utc=True).tz_convert('Asia/Shanghai').strftime("%Y%m%d")
df.columns = [stock]
factor_data = factor_data.merge(df ,how='inner',left_index=True, right_index=True)
#factor_data = factor_data.append(df)
stockPeInfo = index_price
#stockPeInfo.columns=['close']
df_Rmt = factor_data.sum(axis=1) / len(factor_data.columns)
stockPeInfo['Rmt'] = abs((df_Rmt))
stockPeInfo['Rmt2'] = (df_Rmt)**2
formula = 'close~Rmt+Rmt2'
#formula = formula.encode('ascii')
olsResult = smFormula.api.ols(formula = formula, data=stockPeInfo).fit()
# testInfo = smApi.stats.linear_rainbow(olsResult)
coef = olsResult.params.loc['Rmt']
pvalues = olsResult.pvalues.loc['Rmt2']
if pvalues < 0.01 and coef < 0:
ret = 1
else:
ret = 0
print(index,ret, coef, pvalues )
return ret
|