Demo entry 6751466

py

   

Submitted by anonymous on Jun 23, 2018 at 13:21
Language: Python. Code size: 4.4 kB.

start = '2014-01-01'                       # 回测起始时间
end = '2018-06-20'                         # 回测结束时间

universe = ['159915.XSHE', '160216.XSHE', '510050.XSHG', '510300.XSHG','510500.XSHG',
            '511010.XSHG', '513100.XSHG', '513500.XSHG', '518880.XSHG']

# universe = DynamicUniverse('HS300')

benchmark = '511010.XSHG'                        # 策略参考标准
capital_base = 1000000                      # 起始资金
freq = 'd'                                 # 策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测
refresh_rate = 1                          # 调仓频率,表示执行handle_data的时间间隔,若freq = 'd'时间间隔的单位为交易日,若freq = 'm'时间间隔为分钟

_rtnLag = 80
max_history_window = _rtnLag

_single_asset_capacity = 0.30
alpha = 0.1

data=pd.DataFrame()
#weights=pd.DataFrame()

def initialize(account):                   # 初始化虚拟账户状态
    account.history_info = pd.Panel()
    account.original_position = {}
    pass

def handle_data(account):                  # 每个交易日的买入卖出指令
    update_info(account, max_history_window)
    global data
    #global weights
    if rebalance_signal(account):
        
        data = account.history_info.minor_xs('return')[-_rtnLag:]
        # 去除数据太少的证券,并去除有证券没有数据的天数观察
        data.drop([x for x in data.columns if len(data[x][data[x].isnull()])/len(data[x]) > 0.5], inplace = True, axis = 1)
        data.dropna(axis = 0, inplace = True)

        data.drop('benchmark', inplace = True, axis = 1) # 剔出基准
        
        if int(data.shape[0]*alpha) == 0:
            return
        
        weights = get_weight(data)
        
        for stk in weights.index:
            stk_position = 0 if not stk in account.security_position else \
                account.security_position[stk]*account.reference_price[stk]/account.reference_portfolio_value
                
            if abs(weights.ix[stk][0] - stk_position) > 0.001:
                order_pct_to(stk, weights.ix[stk][0])
            
        account.original_position = {x: weights.weight[x] for x in weights.index if weights.weight[x]>0}
        
        return


def update_info(account, initialLag = max_history_window):
    if account.history_info.empty:
        iniInfo = account.get_history(initialLag)
        tmpDict = {}
        for x in iniInfo:
            if not x == 'tradeDate':
                tmpDict[x] = pd.DataFrame(iniInfo[x]).merge(
                    pd.DataFrame(iniInfo['tradeDate']).rename_axis({0:'tradeDate'}, axis = 1)
                    , left_index = True, right_index = True).set_index('tradeDate')
                tmpDict[x]['return'] = tmpDict[x]['closePrice'] / tmpDict[x]['preClosePrice'] - 1
        account.history_info = pd.Panel(tmpDict)
    
    else:
        newInfo = account.get_history(refresh_rate)

        tmpDict = {}
        for x in newInfo:
            if not x == 'tradeDate':
                tmpDict[x] = pd.DataFrame(newInfo[x]).merge(
                    pd.DataFrame(newInfo['tradeDate']).rename_axis({0:'tradeDate'}, axis = 1)
                    , left_index = True, right_index = True).set_index('tradeDate')
                tmpDict[x]['return'] = tmpDict[x]['closePrice'] / tmpDict[x]['preClosePrice'] - 1

        newPan = pd.Panel(tmpDict)
        account.history_info = pd.concat([account.history_info, newPan], axis = 1)
        
        
def rebalance_signal(account):
    if account.cash / account.reference_portfolio_value > 0.3:
        #print '现金仓位超过30%%,触发重新配仓%s'%account.current_date.strftime('%Y-%m-%d')
        return True
    
    for stk in account.original_position:
        pos = 0 if not stk in account.security_position else \
            account.reference_price[stk] * account.security_position[stk] / account.reference_portfolio_value
        if abs(pos - account.original_position[stk]) > 0.10:
            #print '%s仓位绝对变化超过10%%,触发重新配仓%s'%(stk,account.current_date.strftime('%Y-%m-%d'))
            return True
    
    for stk in account.original_position:
        pos = 0 if not stk in account.security_position else \
            account.reference_price[stk] * account.security_position[stk] / account.reference_portfolio_value
        if abs(pos / account.original_position[stk] - 1) > 0.25:
            #print '%s仓位相对变化超过25%%,触发重新配仓%s'%(stk, account.current_date.strftime('%Y-%m-%d'))
            return True
        
    return False

This snippet took 0.01 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).