返回列表 发布新帖

数据使用:简单策略测试

534 1
发表于 2024-2-19 12:16:05 | 显示全部楼层 阅读模式
#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











评论1

*******0608
发表于 2024-2-21 14:05:28 | 显示全部楼层
你怎么这么高产.....

回复

您需要登录后才可以回帖 登录 | 立即注册

客服专线

400-080-8112

用思考的速度交易,用真诚的态度合作,我们是认真的!
  • 关注公众号
  • 添加微信客服
Copyright © 2001-2024 迅投QMT社区 版权所有 All Rights Reserved. 蜀ICP备19002686号-2
关灯 快速发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表