Пример #1
0
def get_priceMom(rebalDate, codes):

    past = ut.get_recentBday(rebalDate - datetime.timedelta(365))
    recent = ut.get_recentBday(rebalDate - datetime.timedelta(30))
    rebalDate = ut.get_recentBday(rebalDate)
    prices = ut.get_stock_price(codes, past, rebalDate )
    mom_12M = (prices.loc[rebalDate, :] / prices.loc[past, :]) - 1
    mom_1M = (prices.loc[rebalDate, :] / prices.loc[recent, :]) - 1
    momData = (mom_12M - mom_1M).dropna()
    return momData   
Пример #2
0
def get_priceMom(codes, rebalDate):
    
    yearAgo = rebalDate - datetime.timedelta(days=365)
    monthAgo = rebalDate - datetime.timedelta(days=30)
    
    yearAgo = util.get_recentBday(yearAgo)
    monthAgo = util.get_recentBday(monthAgo)
    rebalDate = util.get_recentBday(rebalDate)
    
    prices = util.get_stock_price(codes, yearAgo, rebalDate)
    
    mom_12M = (prices.loc[rebalDate, :] / prices.loc[yearAgo, :]) - 1
    mom_1M = (prices.loc[rebalDate, :] / prices.loc[monthAgo, :]) - 1
    
    momData = (mom_12M - mom_1M).dropna()
    
    return momData                    
Пример #3
0
def get_portfolio(factor, factorStyle = 'ratio'):

    rebalData_long = []
    rebalData_short = []
    
    for i in range(len(rebal_sche)):
        
        rebalDate_ = util.get_recentBday(rebal_sche[i], dateFormat = 'datetime')
        #print(rebalDate_)
        
        univ_ = getUniverse(marketInfo, mktcap, risk_1, risk_2, rebalDate_)
        print(len(univ_))
           
        if factorStyle == 'ratio':
            
            factor = factor.loc[:,univ_]  
            factor_ = getFactorData(factor, rebalDate_)
            mktcap_ = util.get_mktcap(factor_.index.values, rebalDate_, rebalDate_)
            ratio_ = get_priceRatio(mktcap_, factor_)
            long, short = get_longshort(ratio_, num_group = 10)
            longFinal = to_backtestFormat(long, rebalDate_)
            shortFinal = to_backtestFormat(short, rebalDate_)            
            rebalData_long.append(longFinal)
            rebalData_short.append(shortFinal)   
            
        elif factorStyle == 'Momentum':
            
            factor_mom = get_priceMom(univ_, rebalDate_)
            long, short = get_longshort(factor_mom, num_group = 10, asc = False)
            longFinal = to_backtestFormat(long, rebalDate_)
            shortFinal = to_backtestFormat(short, rebalDate_)            
            rebalData_long.append(longFinal)
            rebalData_short.append(shortFinal)              
    
    rebalData_long = pd.concat(rebalData_long).reset_index()[['date','code','weight']]
    rebalData_short = pd.concat(rebalData_short).reset_index()[['date','code','weight']]
    
    return rebalData_long, rebalData_short
Пример #4
0
def get_backtest_history(dollar_inv, rebalData, roundup=False, tradeCost=0.01):

    dollar_ongoing = dollar_inv
    basket_history = {}
    rebal_date = list(set(rebalData.date))
    rebal_date.sort()
    tradeCost_history = {}
    turnover_history = {}
    weight_history = {}
    inv_money_list = [dollar_inv]
    inv_money_date = [rebal_date[0]]

    for i in tqdm(range(len(rebal_date))):

        if i < len(rebal_date) - 1:

            rebalDate = rebal_date[i]  # 리밸런싱 시점
            stock_list_i = rebalData[rebalData.date ==
                                     rebal_date[i]].code  # 기간별 종목 리스트
            w_ = rebalData[rebalData.date == rebal_date[i]].weight
            weightData = pd.concat([stock_list_i, w_],
                                   axis=1).set_index('code')

            if i == 0:
                weightData['money'] = weightData[
                    'weight'] * dollar_inv  # 1기인 경우 초기 투자금으로 시작
            else:
                weightData['money'] = weightData[
                    'weight'] * dollar_ongoing  # 1기 이후는 투자금의 매 기간별 마지막 시점에서의 금액 재투자

            stock_price_ = util.get_stock_price(
                stock_list_i, util.get_recentBday(rebalDate),
                util.get_recentBday(
                    rebalDate)).transpose()  # 해당 일자의 바스켓의 주가 추출

            weightData = pd.merge(
                weightData,
                stock_price_,
                how='inner',
                left_on=weightData.index,
                right_on=stock_price_.index).set_index('key_0')

            weightData.columns = ['weight', 'money', 'price']
            weightData['n_stocks'] = weightData['money'] / weightData['price']

            if roundup == True:  # 초기 투입자금으로 투자가능한 종목별 주식수 (정수로 내림)
                weightData.n_stocks = np.floor(weightData.n_stocks)
            else:
                weightData.n_stocks = weightData.n_stocks

            basket_price = util.get_basket_history(
                weightData.index.values, weightData.n_stocks.values,
                util.get_recentBday(rebal_date[i]),
                util.get_recentBday(rebal_date[i + 1]))

            dollar_ongoing = basket_price.iloc[-1, :].values[
                0]  # 투자금의 매 기간별 마지막 시점에서의 포트의 가치(금액)

            # 투자기간 마지막 시점 (다음리밸) 에서의 가격
            last_price = util.get_stock_price(
                weightData.index.values,
                util.get_recentBday(rebal_date[i + 1]),
                util.get_recentBday(rebal_date[i + 1])).transpose()

            weightData = pd.merge(weightData,
                                  last_price,
                                  how='inner',
                                  left_on=weightData.index,
                                  right_on=last_price.index).set_index('key_0')

            weightData.columns = [
                'weight', 'money', 'price', 'n_stocks', 'last_price'
            ]

            weightData['last_weight'] = (
                weightData.last_price * weightData.n_stocks) / (
                    weightData.last_price *
                    weightData.n_stocks).sum()  # 투자기간의 마지막 시점에서의 비중
            new_weight = rebalData[rebalData.date == rebal_date[
                i + 1]].set_index('code')['weight']  # 새로운 비중
            new_weight = pd.Series(new_weight, name='new_weight')
            weightData = pd.concat([weightData, new_weight], axis=1)
            weightData['new_weight'] = weightData['new_weight'].fillna(0)
            weightData['weight'] = weightData['weight'].fillna(0)

            tradingCost = np.abs(weightData.new_weight - weightData.last_weight
                                 ).sum() * tradeCost * dollar_ongoing

            dollar_ongoing -= tradingCost
            basket_history[rebalDate] = basket_price
            inv_money_list += list(basket_price.values.squeeze()[1:-1])
            inv_money_list += [dollar_ongoing]
            inv_money_date += list(basket_price.index[1:])
            tradeCost_history[''.join([
                x for x in str(rebal_date[i + 1])[:10] if x != '-'
            ])] = tradingCost
            turnover_history[''.join([
                x for x in str(rebal_date[i + 1])[:10] if x != '-'
            ])] = tradingCost / dollar_ongoing
            weight_history[''.join([
                x for x in str(rebal_date[i + 1])[:10] if x != '-'
            ])] = weightData

        elif i == len(rebal_date) - 1:

            rebalDate = rebal_date[i]  # 리밸런싱 시점
            #print(rebalDate)
            stock_list_i = rebalData[rebalData.date ==
                                     rebal_date[i]].code  # 기간별 종목 리스트
            lastDay = datetime.datetime.today() - datetime.timedelta(2)
            w_ = rebalData[rebalData.date == rebal_date[i]].weight
            weightData = pd.concat([stock_list_i, w_],
                                   axis=1).set_index('code')

            if i == 0:
                weightData['money'] = weightData[
                    'weight'] * dollar_inv  # 1기인 경우 초기 투자금으로 시작
            else:
                weightData['money'] = weightData[
                    'weight'] * dollar_ongoing  # 1기 이후는 투자금의 매 기간별 마지막 시점에서의 금액 재투자

            stock_price_ = util.get_stock_price(
                stock_list_i, util.get_recentBday(rebalDate),
                util.get_recentBday(
                    rebalDate)).transpose()  # 해당 일자의 바스켓의 주가 추출

            weightData = pd.merge(
                weightData,
                stock_price_,
                how='inner',
                left_on=weightData.index,
                right_on=stock_price_.index).set_index('key_0')

            weightData.columns = ['weight', 'money', 'price']
            weightData['n_stocks'] = weightData['money'] / weightData['price']

            if roundup == True:  # 초기 투입자금으로 투자가능한 종목별 주식수 (정수로 내림)
                weightData.n_stocks = np.floor(weightData.n_stocks)
            else:
                weightData.n_stocks = weightData.n_stocks

            basket_price = util.get_basket_history(
                weightData.index.values, weightData.n_stocks.values,
                util.get_recentBday(rebal_date[i]),
                util.get_recentBday(lastDay))

            dollar_ongoing = basket_price.iloc[-1, :].values[
                0]  # 투자금의 매 기간별 마지막 시점에서의 포트의 가치(금액)
            #print(inv_money_list)

            # 투자기간 마지막 시점 (다음리밸) 에서의 가격
            last_price = util.get_stock_price(
                weightData.index.values, util.get_recentBday(lastDay),
                util.get_recentBday(lastDay)).transpose()

            weightData = pd.merge(weightData,
                                  last_price,
                                  how='inner',
                                  left_on=weightData.index,
                                  right_on=last_price.index).set_index('key_0')

            weightData.columns = [
                'weight', 'money', 'price', 'n_stocks', 'last_price'
            ]
            weightData['last_weight'] = (
                weightData.last_price * weightData.n_stocks) / (
                    weightData.last_price *
                    weightData.n_stocks).sum()  # 투자기간의 마지막 시점에서의 비중
            weightData['new_weight'] = 0
            tradingCost = 0
            dollar_ongoing -= tradingCost
            basket_history[rebalDate] = basket_price
            inv_money_list += list(basket_price.values.squeeze()[1:-1])
            inv_money_list += [dollar_ongoing]
            inv_money_date += list(basket_price.index[1:])
            tradeCost_history[''.join(
                [x for x in str(lastDay)[:10] if x != '-'])] = tradingCost
            turnover_history[''.join([
                x for x in str(lastDay)[:10] if x != '-'
            ])] = tradingCost / dollar_ongoing
            weight_history[''.join([x for x in str(lastDay)[:10]
                                    if x != '-'])] = weightData

    inv_money_history = pd.DataFrame(inv_money_list, index=inv_money_date)

    return inv_money_history, tradeCost_history, turnover_history, weight_history
Пример #5
0
    df = pd.DataFrame(index=range(len(codes)),
                      columns=['date', 'code', 'weight'])
    df['code'] = codes
    df['weight'] = np.ones(len(codes)) / len(codes)
    df['date'] = rebalDate
    return df


rebalData_long = []
rebalData_short = []
num_group = 5
method = 'integrated'

for i in tqdm(range(len(rebal_sche))):

    date_spot = util.get_recentBday(rebal_sche[i], dateFormat='datetime')
    univ_ = util.getUniverse(marketInfo, mktcap, risk_1, risk_2, date_spot)
    psr_spot = util.getFinancialData(factor_PSR, date_spot)[univ_]
    pbr_spot = util.getFinancialData(factor_PBR, date_spot)[univ_]

    # I-1. Integrated Method (Signal Blend, 개별 팩터 스코어를 모두 더해 한번에 주식을 뽑는 방법)
    if method == 'integrated':

        factorName = ['sales', 'book']
        #        factorName = ['book']
        multifactor_df = pd.concat([psr_spot, pbr_spot], axis=1, sort=False)
        #        multifactor_df = pd.concat([pbr_spot], axis = 1, sort = False)
        multifactor_df.columns = factorName
        mktcaps = util.get_mktcap(multifactor_df.index.values, date_spot,
                                  date_spot)