Exemple #1
0
def trade_up_slope(s1_tick, s2_tick, table, strategy):
    trade_capital = 0
    cpA, cpB = 0, 0
    trading_profit = 0.0
    trade = 0
    trade_capital = 0
    trade_return = 0.0
    history = []

    # 波動太小的配對不開倉
    if volaitlity_small(strategy, table):
        history.append({"time": 0, "type": "配對波動太小,不開倉"})
        print(f'{table["S1"]} {table["S2"]}  配對波動太小,不開倉')
        return trade, trading_profit, trade_capital, trade_return, history

    spread = table["w1"] * np.log(s1_tick) + table["w2"] * np.log(s2_tick)
    close, up_open_val, down_open_val = build_open(spread, table, strategy)

    position = 0  # 持倉狀態,1:多倉,0:無倉,-1:空倉,-2:強制平倉
    stock1_profit = []
    stock2_profit = []
    spread_len = len(spread)
    w1 = 0
    w2 = 0
    for i in range(0, spread_len - 2):
        if position == 0 and i != spread_len - 3:  # 之前無開倉

            if spread[i] < down_open_val[i]:  # 碰到下開倉門檻且大於下停損門檻
                w1, w2 = num_weight(table["w1"], table["w2"], s1_tick[i],
                                    s2_tick[i], strategy["maxhold"],
                                    strategy["capital"])
                stock1_payoff, stock2_payoff = down_open(
                    w1, w2, s1_tick[1], s2_tick[i], strategy["tax_cost"])
                cpA, cpB = stock1_payoff, stock2_payoff
                position = 1
                trade = 1
                stock1_profit.append(stock1_payoff)
                stock2_profit.append(stock2_payoff)
                history.append({
                    "time": i,
                    "w1": -w1,
                    "stock1_payoff": stock1_payoff,
                    "w2": -w2,
                    "stock2_payoff": stock2_payoff,
                    "type": "下開倉"
                })
                print(
                    f'{i} {w1} 張 {table["S1"]} {stock1_payoff} , {w2} 張 {table["S2"]} {stock2_payoff} spread = {spread[i]} 下開倉'
                )

        elif position == 1:  # 之前有開多倉,平多倉

            if (i == spread_len - 3):  # 回測結束,強制平倉
                position = -4
                stock1_payoff, stock2_payoff = down_close(
                    w1, w2, s1_tick[i], s2_tick[i], strategy["tax_cost"],
                    position)
                stock1_profit.append(stock1_payoff)
                stock2_profit.append(stock2_payoff)
                print(
                    f'{i} {w1} 張 {table["S1"]} {stock1_payoff} , {w2} 張 {table["S2"]} {stock2_payoff} 強制平倉'
                )
                history.append({
                    "time": i,
                    "w1": w1,
                    "stock1_payoff": stock1_payoff,
                    "w2": w2,
                    "stock2_payoff": stock2_payoff,
                    "type": "尾盤強制平倉"
                })
                break

            elif (spread[i] - close[i]) > 0:
                position = 666  # 平倉
                stock1_payoff, stock2_payoff = down_close(
                    w1, w2, s1_tick[i], s2_tick[i], strategy["tax_cost"],
                    position)
                stock1_profit.append(stock1_payoff)
                stock2_profit.append(stock2_payoff)
                print(
                    f'{i} {w1} 張 {table["S1"]} {stock1_payoff} , {w2} 張 {table["S2"]} {stock2_payoff} 正常平倉'
                )
                history.append({
                    "time": i,
                    "w1": w1,
                    "stock1_payoff": stock1_payoff,
                    "w2": w2,
                    "stock2_payoff": stock2_payoff,
                    "type": "正常平倉"
                })
                break

    trading_profit = sum(stock1_profit) + sum(stock2_profit)

    if cpA > 0 and cpB > 0:
        trade_capital = abs(cpA) + abs(cpB)
    elif cpA > 0 and cpB < 0:
        trade_capital = abs(cpA) + 0.9 * abs(cpB)
    elif cpA < 0 and cpB > 0:
        trade_capital = 0.9 * abs(cpA) + abs(cpB)
    elif cpA < 0 and cpB < 0:
        trade_capital = 0.9 * abs(cpA) + 0.9 * abs(cpB)

    if trade > 0:  # 如果都沒有開倉,則報酬為0
        trade_return = trading_profit / trade_capital

    return trade, trading_profit, trade_capital, trade_return, history
Exemple #2
0
def trade_down(spread , trend , Row_ST ,Ibeta , trStd , trCost , tros, trcs, trMtp ):
    #spread:共整合序列 , trend:時間趨勢均值 , RowST:原始股價
    #Ibeta:整數化股票張數 , trStd:建模期間標準差 , trCost:交易成本
    #tros:開倉倍數, trcs:停損倍數
    '''    
    #Debug用
    spread, trend = cy[inNum:DailyNum+1,pi] ,cy_mean[inNum:DailyNum+1,pi]
    Row_ST= Smin[inNum:DailyNum+1,[int(OMinx[pi,0]), int(OMinx[pi,1])]] 
    Ibeta ,trStd, trCost ,tros , trcs= IntegerB[:,pi], SStd ,Cost ,Os, Fs
    trMtp = Max_tp
    '''
    #[總獲利,平倉獲利,停損獲利,換日強停獲利,換日強停虧損]
    Profit = np.zeros((1,5))
    #[開倉次數,平倉次數,停損次數,換日強停獲利次數,換日強停虧損次數]
    Count = np.zeros((1,5))
    OpenTrend = trend + trStd*tros
    StopTrend = trend + trStd*trcs
    Position = 0 # 部位控制
    LogTradeTime = np.zeros((1,spread.shape[0])) # 時間紀錄
    ForceP = 0
    openP = 0
    opencount = 0
    opentime = 0
    closetime = 0
    LongOrShort = -1
    opens1payoff = 0
    opens2payoff = 0
    closes1payoff = 0
    closes2payoff = 0
    capital = 50000000
    for ti in range(spread.shape[0]):
        
        #尾盤的強制平倉處理
        if ti == spread.shape[0]-1:
            #若有倉則強制平倉
            if Position == 1: 
                #ForceP = openP - np.dot(Row_ST[ti,:],Ibeta) + TradeCost(Row_ST[ti,:],Ibeta,trCost,'L') 
                closes1payoff = LongOrShort * Row_ST[97,0] * Ibeta[0]
                closes2payoff = LongOrShort * Row_ST[97,1] * Ibeta[1]
                ForceP = tax(closes1payoff,trCost)+tax(closes2payoff,trCost)+openP
                if ForceP > 0:
                    Profit[0,3] = ForceP
                    Count[0,3] = Count[0,3] + 1
                    Position = 0
                    LogTradeTime[0,ti] = 3
                    closetime = 97
                elif ForceP <= 0:
                    Profit[0,4] = ForceP
                    Count[0,4] = Count[0,4] + 1
                    Position = 0
                    LogTradeTime[0,ti] = 3
                    closetime = 97
        #尾盤前的交易
        else:
            if opencount <= 1 :
            #到期前若碰到平倉門檻且有倉,平倉
                if Position == 1 and spread[ti] <= trend[ti] and ti < 97:
                    #Profit[0,1] = openP - np.dot(Row_ST[ti+1,:],Ibeta) - TradeCost(Row_ST[ti+1,:],Ibeta,trCost,'L') 
                    closes1payoff = LongOrShort * Row_ST[ti,0] * Ibeta[0]
                    closes2payoff = LongOrShort * Row_ST[ti,1] * Ibeta[1]
                    ForceP = tax(closes1payoff,trCost)+tax(closes2payoff,trCost)+openP
                    #Profit[0,1] = openP - np.dot(Row_ST[ti,:],Ibeta) + TradeCost(Row_ST[ti,:],Ibeta,trCost,'L') 
                    Profit[0,1] = ForceP
                    Count[0,1] = Count[0,1] + 1
                    Position = 0 
                    LogTradeTime[0,ti] = -1
                    closetime = ti
                #到期前若碰到停損門檻且有倉,停損    
                elif Position == 1 and spread[ti]>=StopTrend[ti]:
                    #Profit[0,1] = openP - np.dot(Row_ST[ti+1,:],Ibeta) - TradeCost(Row_ST[ti+1,:],Ibeta,trCost,'L')  
                    Profit[0,1] = openP - np.dot(Row_ST[ti,:],Ibeta) + TradeCost(Row_ST[ti,:],Ibeta,trCost,'L')
                    Count[0,2] = Count[0,2] + 1
                    Position = -1
                    LogTradeTime[0,ti] = -2
                    closetime = ti
                #到期前,若碰到開倉門檻且無倉,開倉    
                elif Position == 0 and spread[ti]>=OpenTrend[ti] and ti<(trMtp-150) and opencount != 1:
                    #openP = np.dot(Row_ST[ti+1,:],Ibeta) - TradeCost(Row_ST[ti+1,:],Ibeta,trCost,'S')
                    #openP = np.dot(Row_ST[ti,:],Ibeta) - TradeCost(Row_ST[ti,:],Ibeta,trCost,'S')
                    Ibeta[0] , Ibeta[1] = num_weight(Ibeta[0],Ibeta[1],
                                 Row_ST[ti,0],Row_ST[ti,1], 5, capital)
                    opens1payoff = -LongOrShort * Row_ST[ti,0] * Ibeta[0]
                    opens2payoff = -LongOrShort * Row_ST[ti,1] * Ibeta[1]
                    openP = tax(opens1payoff,trCost)+tax(opens2payoff,trCost)
                    Count[0,0] = Count[0,0] + 1
                    Position = 1
                    LogTradeTime[0,ti] = 1
                    opencount += 1
                    opentime = ti
            else:
                break
    
    Profit[0,0]=sum(Profit[0,1:5])
    trade_capital = 0
    if opens1payoff > 0 and  opens2payoff > 0:
        trade_capital = abs(opens1payoff)+abs( opens2payoff)
    elif opens1payoff > 0 and opens2payoff < 0 :
        trade_capital = abs(opens1payoff)+0.9*abs( opens2payoff)
    elif opens1payoff < 0 and opens2payoff > 0 :
        trade_capital = 0.9*abs(opens1payoff)+abs( opens2payoff)
    elif opens1payoff < 0 and opens2payoff < 0 :
        trade_capital = 0.9*abs(opens1payoff)+0.9*abs(opens2payoff)
        
    return [Profit, Count,opentime,closetime,trade_capital]
Exemple #3
0
def pairs(pos, formate_time, table, min_data, tick_data, maxi, tax_cost,
          cost_gate, capital):
    actions = [[1.5, 3], [0.5000000000002669, 2.500000000000112],
               [0.7288428324698772, 4.0090056748083995],
               [1.1218344155846804, 3.0000000000002496],
               [1.2162849872773496, 7.4631043256997405],
               [1.4751902346226717, 3.9999999999997113],
               [1.749999999999973, 3.4999999999998117],
               [2.086678832116794, 6.2883211678832325],
               [2.193017888055368, 4.018753606462444],
               [2.2499999999999822, 7.500000000000021],
               [2.6328389830508536, 8.9762711864407],
               [2.980046948356806, 13.515845070422579],
               [3.2499999999999982, 5.500000000000034],
               [3.453852327447829, 11.505617977528125],
               [3.693027210884357, 6.0739795918367605],
               [4.000000000000004, 12.500000000000034],
               [4.151949541284411, 10.021788990825703],
               [4.752819548872187, 15.016917293233117],
               [4.8633603238866225, 7.977058029689605],
               [5.7367647058823605, 13.470588235294136],
               [6.071428571428564, 16.47435897435901],
               [6.408839779005503, 10.95488029465933],
               [7.837962962962951, 12.745370370370392],
               [8.772727272727282, 18.23295454545456],
               [9.242088607594926, 14.901898734177237], [100, 200]]
    s1 = str(table.stock1[pos])
    s2 = str(table.stock2[pos])

    tw1 = table.w1[pos]
    tw2 = table.w2[pos]
    e_stdev = table.Estd[pos]
    e_mu = table.Emu[pos]
    up_open_time = actions[table.action[pos]][0]
    down_open_time = up_open_time
    stop_loss_time = actions[table.action[pos]][1]

    trade_capital = 0
    cpA, cpB = 0, 0
    trading = [0, 0, 0]

    use_fore_lag5 = False
    use_adf = False

    trade_process = []
    # # 波動太小的配對不開倉
    # if (up_open_time + down_open_time) *e_stdev < cost_gate:
    # trade_process.append([tick_data.mtimestamp[1], "配對波動太小,不開倉"])
    #     # print("配對波動太小,不開倉")
    #     trading_profit = 0
    #     trade = 0
    #     local_profit = 0
    #     local_open_num = 0
    #     local_rt = 0
    #     local_std = 0
    #     local_skew = 0
    #     local_timetrend = 0
    #     position = 0
    #     return  {
    #         'trade_history' : trade_process ,
    #         "local_profit" : local_profit ,
    #         "local_open_num" : local_open_num,
    #         "trade_capital" :trade_capital,
    #         "local_rt" : "0.000",
    #         # "profit" : trading_profit
    #     }
    #     # return local_profit, local_open_num, trade_capital, trading, trade_process

    t = formate_time  # formate time
    # stock1_seq = min_data[s1].loc[0:t]
    # stock2_seq = min_data[s2].loc[0:t]

    local_open_num = []
    local_profit = []
    local_rt = []
    local_std = []
    local_skew = []
    local_timetrend = []

    spread = tw1 * np.log(tick_data[s1]) + tw2 * np.log(tick_data[s2])

    up_open = e_mu + e_stdev * up_open_time  # 上開倉門檻
    down_open = e_mu - e_stdev * down_open_time  # 下開倉門檻
    stop_loss = e_stdev * stop_loss_time  # 停損門檻
    close = e_mu  # 平倉(均值)
    # M = round(1 / table.zcr[pos])  # 平均持有時間
    trade = 0  # 計算開倉次數
    break_point = 0  # 計算累積斷裂點

    position = 0  # 持倉狀態,1:多倉,0:無倉,-1:空倉,-2:強制平倉
    pos = [0, 0]
    stock1_profit = []
    stock2_profit = []

    for i in range(1, len(spread) - 6):
        if position == 0 and i != len(spread) - 7:  # 之前無開倉
            if (spread[i] - up_open) * (
                    spread[i + 1] - up_open) < 0 and spread[i + 1] < (
                        close + stop_loss):  # 碰到上開倉門檻且小於上停損門檻
                # 資金權重轉股票張數,並整數化

                # print(tick_data.mtimestamp[i],"碰到上開倉門檻 ,上開倉")
                w1, w2 = num_weight(tw1, tw2, tick_data[s1][i + 1],
                                    tick_data[s2][i + 1], maxi, capital)
                position = -1
                stock1_payoff = w1 * slip(tick_data[s1][i + 1], tw1)
                stock2_payoff = w2 * slip(tick_data[s2][i + 1], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                cpA, cpB = stock1_payoff, stock2_payoff
                if cpA > 0 and cpB > 0:
                    trade_capital += abs(cpA) + abs(cpB)
                elif cpA > 0 and cpB < 0:
                    trade_capital += abs(cpA) + 0.9 * abs(cpB)
                elif cpA < 0 and cpB > 0:
                    trade_capital += 0.9 * abs(cpA) + abs(cpB)
                elif cpA < 0 and cpB < 0:
                    trade_capital += 0.9 * abs(cpA) + 0.9 * abs(cpB)
                    # down_open = table.mu[pos] - table.stdev[pos] * close_time
                trade += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到上開倉門檻 ,上開倉<br>",w1, w2, stock1_payoff+stock2_payoff])

            elif (spread[i] - down_open) * (
                    spread[i + 1] - down_open) < 0 and spread[i + 1] > (
                        close - stop_loss):  # 碰到下開倉門檻且大於下停損門檻
                # 資金權重轉股票張數,並整數化

                # print(tick_data.mtimestamp[i],"碰到下開倉門檻 ,下開倉")
                w1, w2 = num_weight(tw1, tw2, tick_data[s1][i + 1],
                                    tick_data[s2][i + 1], maxi, capital)
                position = 1
                stock1_payoff = -w1 * slip(tick_data[s1][i + 1], -tw1)
                stock2_payoff = -w2 * slip(tick_data[s2][i + 1], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                cpA, cpB = stock1_payoff, stock2_payoff
                if cpA > 0 and cpB > 0:
                    trade_capital += abs(cpA) + abs(cpB)
                elif cpA > 0 and cpB < 0:
                    trade_capital += abs(cpA) + 0.9 * abs(cpB)
                elif cpA < 0 and cpB > 0:
                    trade_capital += 0.9 * abs(cpA) + abs(cpB)
                elif cpA < 0 and cpB < 0:
                    trade_capital += 0.9 * abs(cpA) + 0.9 * abs(cpB)
                # up_open = table.mu[pos] + table.stdev[pos] * close_time
                trade += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到下開倉門檻 ,下開倉<br>", -w1, -w2, stock1_payoff+stock2_payoff])
            else:
                position = 0
                stock1_payoff = 0
                stock2_payoff = 0
        elif position == -1:  # 之前有開空倉,平空倉
            if (spread[i] - close) * (spread[i + 1] -
                                      close) < 0:  # 空倉碰到下開倉門檻即平倉

                # print(tick_data.mtimestamp[i],"之前有開空倉,碰到均值,平倉")
                position = 0  # 平倉
                stock1_payoff = -w1 * slip(tick_data[s1][i + 1], -tw1)
                stock2_payoff = -w2 * slip(tick_data[s2][i + 1], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[0] += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到均值,平倉<br>",-w1, -w2, stock1_payoff+stock2_payoff])
                # down_open = table.mu[pos] - table.stdev[pos] * open_time
                # 每次交易報酬做累加(最後除以交易次數做平均)
            elif spread[i + 1] > (close + stop_loss):  # 空倉碰到上停損門檻即平倉停損

                # print(tick_data.mtimestamp[i],"之前有開空倉,碰到上停損門檻,強制平倉")
                position = -2  # 碰到停損門檻,強制平倉
                stock1_payoff = -w1 * slip(tick_data[s1][i + 1], -tw1)
                stock2_payoff = -w2 * slip(tick_data[s2][i + 1], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[1] += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到上停損門檻,強制平倉<br>",-w1, -w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 7):  # 回測結束,強制平倉
                # trade_process.append([tick_data.mtimestamp[i],"回測結束,強制平倉<br>"])
                # print(tick_data.mtimestamp[i],"回測結束,強制平倉")
                position = -4
                stock1_payoff = -w1 * slip(tick_data[s1][len(tick_data) - 1],
                                           -tw1)
                stock2_payoff = -w2 * slip(tick_data[s2][len(tick_data) - 1],
                                           -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[2] += 1
                # trade_process.append([tick_data.mtimestamp[i],"回測結束,強制平倉<br>",-w1, -w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)
            else:
                position = -1
                stock1_payoff = 0
                stock2_payoff = 0
        elif position == 1:  # 之前有開多倉,平多倉
            if (spread[i] - close) * (spread[i + 1] - close) < 0:

                # print(tick_data.mtimestamp[i],"之前有開多倉,碰到均值,平倉")
                position = 0  # 平倉
                stock1_payoff = w1 * slip(tick_data[s1][i + 1], tw1)
                stock2_payoff = w2 * slip(tick_data[s2][i + 1], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[0] += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到均值,平倉<br>",w1, w2, stock1_payoff+stock2_payoff])
                # up_open = table.mu[pos] + table.stdev[pos] * open_time
                # 每次交易報酬做累加(最後除以交易次數做平均)
            elif spread[i + 1] < (close - stop_loss):

                # print(tick_data.mtimestamp[i],"之前有開多倉,碰到下停損門檻,強制平倉")
                position = -2  # 碰到停損門檻,強制平倉
                stock1_payoff = w1 * slip(tick_data[s1][i + 1], tw1)
                stock2_payoff = w2 * slip(tick_data[s2][i + 1], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[1] += 1

                # trade_process.append([tick_data.mtimestamp[i],"碰到下停損門檻,強制平倉<br>", w1, w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 7):  # 回測結束,強制平倉

                # print(tick_data.mtimestamp[i],"回測結束,強制平倉")
                position = -4
                stock1_payoff = w1 * slip(tick_data[s1][len(tick_data) - 1],
                                          tw1)
                stock2_payoff = w2 * slip(tick_data[s2][len(tick_data) - 1],
                                          tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[2] += 1

                # trade_process.append([tick_data.mtimestamp[i],"回測結束,強制平倉<br>", w1, w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)
            else:
                position = 1
                stock1_payoff = 0
                stock2_payoff = 0
        else:
            # -4: 強迫平倉 -3: 結構性斷裂平倉(for lag 5) -2:停損 666:正常平倉
            if position == -2 or position == -3 or position == -4 or position == 666:
                stock1_payoff = 0
                stock2_payoff = 0
            else:
                position = 0  # 剩下時間少於預期開倉時間,則不開倉,避免損失
                stock1_payoff = 0
                stock2_payoff = 0

        pos.append(position)
        stock1_profit.append(stock1_payoff)
        stock2_profit.append(stock2_payoff)
    trading_profit = sum(stock1_profit) + sum(stock2_profit)

    if trading_profit != 0 and position == 666:
        position = 666

    local_profit = trading_profit
    # local_open_num.append(trade)
    local_open_num = trade
    if trade == 0:  # 如果都沒有開倉,則報酬為0
        # trade_process.append([tick_data.mtimestamp.iloc[-1],"無任何交易"])
        # print("沒有開倉")
        local_rt = 0
        local_std = 0
        local_skew = 0
        local_timetrend = 0
        position = 0

    else:  # 計算平均報酬
        # spread2 = w1 * np.log(min_data[s1].iloc[0:t]) + w2 * np.log(min_data[s2].iloc[0:t])

        # x = np.arange(0, t)
        # b1, b0 = np.polyfit(x, spread2, 1)
        local_rt = trading_profit / trade_capital
        # local_std = np.std(spread2)
        # local_skew = skew(spread2)
        # local_timetrend = b1

        # trade_process.append(["總損益", trading_profit])

    # if cpA > 0 and cpB > 0:
    #     trade_capital = abs(cpA)+abs(cpB)
    # elif cpA > 0 and cpB < 0 :
    #     trade_capital = abs(cpA)+0.9*abs(cpB)
    # elif cpA < 0 and cpB > 0 :
    #     trade_capital = 0.9*abs(cpA)+abs(cpB)
    # elif cpA < 0 and cpB < 0 :
    #     trade_capital = 0.9*abs(cpA)+0.9*abs(cpB)

    return local_profit, trade_capital
Exemple #4
0
def pairs(pos, formate_time, table, tick_data, maxi, tax_cost, cost_gate,
          capital):
    # actions = [
    #     [1.5000000000002669, 2.500000000000112],
    #     [0.7288428324698772, 4.0090056748083995],
    #     [1.1218344155846804, 3.0000000000002496],
    #     [1.2162849872773496, 7.4631043256997405],
    #     [1.4751902346226717, 3.9999999999997113],
    #     [1.749999999999973, 3.4999999999998117],
    #     [2.086678832116794, 6.2883211678832325],
    #     [2.193017888055368, 4.018753606462444],
    #     [2.2499999999999822, 7.500000000000021],
    #     [2.6328389830508536, 8.9762711864407],
    #     [2.980046948356806, 13.515845070422579],
    #     [3.2499999999999982, 5.500000000000034],
    #     [3.453852327447829, 11.505617977528125],
    #     [3.693027210884357, 6.0739795918367605],
    #     [4.000000000000004, 12.500000000000034],
    #     [4.151949541284411, 10.021788990825703],
    #     [4.752819548872187, 15.016917293233117],
    #     [4.8633603238866225, 7.977058029689605],
    #     [5.7367647058823605, 13.470588235294136],
    #     [6.071428571428564, 16.47435897435901],
    #     [6.408839779005503, 10.95488029465933],
    #     [7.837962962962951, 12.745370370370392],
    #     [8.772727272727282, 18.23295454545456],
    #     [9.242088607594926, 14.901898734177237],
    #     [100, 200]
    # ]
    actions = [[0.5000000000001132, 2.9999999999999174],
               [0.5000000000001159, 1.4999999999998659],
               [0.5011026964048937, 5.057090545938981],
               [0.5997656402578979, 1.9999999999999885],
               [0.7450101488498877, 2.500000000000264],
               [0.9957274202272546, 3.5038669551108814],
               [0.9986299023806298, 3.00000000000035],
               [0.9989438479141635, 6.000440063369089],
               [1.2502992817239085, 7.499301675977626],
               [1.3748807883861818, 5.499999999999963],
               [1.4714078698027613, 5.000000000000162],
               [1.6540920096852696, 4.3137046004844875],
               [1.7331017056222244, 8.988629185091602],
               [1.9997078301519378, 10.003506038176837],
               [2.131133083912334, 6.300320684126101],
               [2.2702554744525623, 7.199270072992672],
               [2.6956923890063442, 7.93093727977449],
               [2.9601038145823297, 8.740704973442782],
               [3.4156698564593317, 10.223684210526311],
               [4.180390032502709, 11.496208017334773],
               [4.475710508922673, 13.83311302048908],
               [5.686262376237629, 16.102103960396033],
               [7.189858490566042, 19.562500000000004],
               [9.489123012389175, 23.9905618964017], [100, 200]]
    s1 = str(table.stock1[pos])
    s2 = str(table.stock2[pos])

    tw1 = table.w1[pos]
    tw2 = table.w2[pos]
    Estd = table.Estd[pos]  #table.Estd[pos]
    Emu = table.Emu[pos]  #

    up_open_time = 1.5
    down_open_time = up_open_time
    stop_loss_time = 1000  #actions[table.action[pos]][1] #actions[0][1] 2.5

    up_open = Emu + Estd * up_open_time  # 上開倉門檻
    down_open = Emu - Estd * down_open_time  # 下開倉門檻
    stop_loss = Estd * stop_loss_time  # stop_loss_time  # 停損門檻
    close = Emu  # 平倉(均值)

    trade_capital = 0
    cpA, cpB = 0, 0
    trading = [0, 0, 0]

    # # 波動太小的配對不開倉
    if up_open_time * Estd < cost_gate:
        # trade_process.append([tick_data.mtimestamp[1], "配對波動太小,不開倉"])
        # print("配對波動太小,不開倉")
        trading_profit = 0
        trade = 0
        local_profit = 0
        position = 0
        return local_profit, trade_capital, trade, 0, 0, 0

    t = formate_time  # formate time

    local_profit = []

    spread = tw1 * np.log(tick_data[s1]) + tw2 * np.log(tick_data[s2])

    # M = round(1 / table.zcr[pos])  # 平均持有時間
    trade = 0  # 計算開倉次數
    break_point = 0  # 計算累積斷裂點

    position = 0  # 持倉狀態,1:多倉,0:無倉,-1:空倉,-2:強制平倉
    pos = [0, 0]
    stock1_profit = []
    stock2_profit = []

    for i in range(0, len(spread) - 2):
        if position == 0 and i != len(spread) - 3 and i < 40:  # 之前無開倉
            if spread[i] < (close + stop_loss
                            ) and spread[i] > up_open:  # 碰到上開倉門檻且小於上停損門檻
                # 資金權重轉股票張數,並整數化

                # print(tick_data.mtimestamp[i],"碰到上開倉門檻 ,上開倉")
                w1, w2 = num_weight(tw1, tw2, tick_data[s1][i],
                                    tick_data[s2][i], maxi, capital)
                position = -1
                stock1_payoff = w1 * slip(tick_data[s1][i], tw1)
                stock2_payoff = w2 * slip(tick_data[s2][i], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                cpA, cpB = stock1_payoff, stock2_payoff
                if cpA > 0 and cpB > 0:
                    trade_capital += abs(cpA) + abs(cpB)
                elif cpA > 0 and cpB < 0:
                    trade_capital += abs(cpA) + 0.9 * abs(cpB)
                elif cpA < 0 and cpB > 0:
                    trade_capital += 0.9 * abs(cpA) + abs(cpB)
                elif cpA < 0 and cpB < 0:
                    trade_capital += 0.9 * abs(cpA) + 0.9 * abs(cpB)
                    # down_open = table.mu[pos] - table.stdev[pos] * close_time
                trade += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到上開倉門檻 ,上開倉<br>",w1, w2, stock1_payoff+stock2_payoff])

            elif spread[i] > (close - stop_loss
                              ) and spread[i] < down_open:  # 碰到下開倉門檻且大於下停損門檻
                # 資金權重轉股票張數,並整數化

                # print(tick_data.mtimestamp[i],"碰到下開倉門檻 ,下開倉")
                w1, w2 = num_weight(tw1, tw2, tick_data[s1][i],
                                    tick_data[s2][i], maxi, capital)
                position = 1
                stock1_payoff = -w1 * slip(tick_data[s1][i], -tw1)
                stock2_payoff = -w2 * slip(tick_data[s2][i], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                cpA, cpB = stock1_payoff, stock2_payoff
                if cpA > 0 and cpB > 0:
                    trade_capital += abs(cpA) + abs(cpB)
                elif cpA > 0 and cpB < 0:
                    trade_capital += abs(cpA) + 0.9 * abs(cpB)
                elif cpA < 0 and cpB > 0:
                    trade_capital += 0.9 * abs(cpA) + abs(cpB)
                elif cpA < 0 and cpB < 0:
                    trade_capital += 0.9 * abs(cpA) + 0.9 * abs(cpB)
                # up_open = table.mu[pos] + table.stdev[pos] * close_time
                trade += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到下開倉門檻 ,下開倉<br>", -w1, -w2, stock1_payoff+stock2_payoff])
            else:
                position = 0
                stock1_payoff = 0
                stock2_payoff = 0
        elif position == -1:  # 之前有開空倉,平空倉
            if (spread[i] - close) < 0:  # 空倉碰到下開倉門檻即平倉

                # print(tick_data.mtimestamp[i],"之前有開空倉,碰到均值,平倉")
                position = 666  # 平倉
                stock1_payoff = -w1 * slip(tick_data[s1][i], -tw1)
                stock2_payoff = -w2 * slip(tick_data[s2][i], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[0] += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到均值,平倉<br>",-w1, -w2, stock1_payoff+stock2_payoff])
                # down_open = table.mu[pos] - table.stdev[pos] * open_time
                # 每次交易報酬做累加(最後除以交易次數做平均)
            elif spread[i] > (close + stop_loss):  # 空倉碰到上停損門檻即平倉停損

                # print(tick_data.mtimestamp[i],"之前有開空倉,碰到上停損門檻,強制平倉")
                position = -2  # 碰到停損門檻,強制平倉
                stock1_payoff = -w1 * slip(tick_data[s1][i], -tw1)
                stock2_payoff = -w2 * slip(tick_data[s2][i], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[1] += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到上停損門檻,強制平倉<br>",-w1, -w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 3):  # 回測結束,強制平倉
                # trade_process.append([tick_data.mtimestamp[i],"回測結束,強制平倉<br>"])
                # print(tick_data.mtimestamp[i],"回測結束,強制平倉")
                position = -4
                stock1_payoff = -w1 * \
                    slip(tick_data[s1][len(tick_data) - 1], -tw1)
                stock2_payoff = -w2 * \
                    slip(tick_data[s2][len(tick_data) - 1], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[2] += 1
                # trade_process.append([tick_data.mtimestamp[i],"回測結束,強制平倉<br>",-w1, -w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)
            else:
                position = -1
                stock1_payoff = 0
                stock2_payoff = 0
        elif position == 1:  # 之前有開多倉,平多倉
            if (spread[i] - close) > 0:

                # print(tick_data.mtimestamp[i],"之前有開多倉,碰到均值,平倉")
                position = 666  # 平倉
                stock1_payoff = w1 * slip(tick_data[s1][i], tw1)
                stock2_payoff = w2 * slip(tick_data[s2][i], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[0] += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到均值,平倉<br>",w1, w2, stock1_payoff+stock2_payoff])
                # up_open = table.mu[pos] + table.stdev[pos] * open_time
                # 每次交易報酬做累加(最後除以交易次數做平均)
            elif spread[i] < (close - stop_loss):

                # print(tick_data.mtimestamp[i],"之前有開多倉,碰到下停損門檻,強制平倉")
                position = -2  # 碰到停損門檻,強制平倉
                stock1_payoff = w1 * slip(tick_data[s1][i], tw1)
                stock2_payoff = w2 * slip(tick_data[s2][i], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[1] += 1

                # trade_process.append([tick_data.mtimestamp[i],"碰到下停損門檻,強制平倉<br>", w1, w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 3):  # 回測結束,強制平倉

                # print(tick_data.mtimestamp[i],"回測結束,強制平倉")
                position = -4
                stock1_payoff = w1 * \
                    slip(tick_data[s1][len(tick_data) - 1], tw1)
                stock2_payoff = w2 * \
                    slip(tick_data[s2][len(tick_data) - 1], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[2] += 1

                # trade_process.append([tick_data.mtimestamp[i],"回測結束,強制平倉<br>", w1, w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)
            else:
                position = 1
                stock1_payoff = 0
                stock2_payoff = 0
        else:
            # -4: 強迫平倉 -3: 結構性斷裂平倉(for lag 5) -2:停損 666:正常平倉
            if position == -2 or position == -3 or position == -4 or position == 666:
                stock1_payoff = 0
                stock2_payoff = 0
            else:
                position = 0  # 剩下時間少於預期開倉時間,則不開倉,避免損失
                stock1_payoff = 0
                stock2_payoff = 0

        pos.append(position)
        stock1_profit.append(stock1_payoff)
        stock2_profit.append(stock2_payoff)
    trading_profit = sum(stock1_profit) + sum(stock2_profit)

    local_profit = trading_profit
    # local_open_num.append(trade)
    if trade == 0:  # 如果都沒有開倉,則報酬為0
        # trade_process.append([tick_data.mtimestamp.iloc[-1],"無任何交易"])
        # print("沒有開倉")
        position = 0

    return local_profit, trade_capital, trade, position, tick_data[s1][
        0], tick_data[s2][0]
Exemple #5
0
def pairs(
    choose_date,
    pos,
    formate_time,
    table,
    tick_data,
    half_data,
    maxi,
    tax_cost,
    cost_gate,
    capital,
):

    s1 = str(table.stock1[pos])
    s2 = str(table.stock2[pos])

    tw1 = table.w1[pos]
    tw2 = table.w2[pos]
    Estd = table.Estd[pos]  #table.Estd[pos]
    Emu = table.Emu[pos]  #

    up_open_time = 1.5
    down_open_time = up_open_time
    stop_loss_time = 10000  #actions[table.action[pos]][1] #actions[0][1] 2.5

    up_open = Emu + Estd * up_open_time  # 上開倉門檻
    down_open = Emu - Estd * down_open_time  # 下開倉門檻
    stop_loss = Estd * stop_loss_time  # stop_loss_time  # 停損門檻
    close = Emu  # 平倉(均值)

    trade_capital = 0
    cpA, cpB = 0, 0
    trading = [0, 0, 0]

    trade_capital = 0
    cpA, cpB = 0, 0
    trading = [0, 0, 0]

    used_news = False
    dup_news = False

    # if s1_news.empty and s2_news.empty:
    #     used_news = False

    # # 波動太小的配對不開倉
    if up_open_time * Estd < cost_gate:
        # trade_process.append([tick_data.mtimestamp[1], "配對波動太小,不開倉"])
        # print("配對波動太小,不開倉")
        trading_profit = 0
        trade = 0
        local_profit = 0
        position = 0
        return False, local_profit, trade_capital, trade, 0, 0, 0, dup_news

    t = formate_time  # formate time

    local_profit = []

    spread = tw1 * np.log(tick_data[s1]) + tw2 * np.log(tick_data[s2])

    # M = round(1 / table.zcr[pos])  # 平均持有時間
    trade = 0  # 計算開倉次數
    break_point = 0  # 計算累積斷裂點

    position = 0  # 持倉狀態,1:多倉,0:無倉,-1:空倉,-2:強制平倉
    pos = [0, 0]
    stock1_profit = []
    stock2_profit = []

    for i in range(0, len(spread) - 2):
        if position == 0 and i != len(spread) - 3 and i < 40:  # 之前無開倉

            if spread[i] < (close + stop_loss
                            ) and spread[i] > up_open:  # 碰到上開倉門檻且小於上停損門檻
                # 資金權重轉股票張數,並整數化

                # print(tick_data.mtimestamp[i],"碰到上開倉門檻 ,上開倉")
                w1, w2 = num_weight(tw1, tw2, tick_data[s1][i],
                                    tick_data[s2][i], maxi, capital)
                position = -1
                stock1_payoff = w1 * slip(half_data[s1][2 * i + 1], tw1)
                stock2_payoff = w2 * slip(half_data[s2][2 * i + 1], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                cpA, cpB = stock1_payoff, stock2_payoff
                if cpA > 0 and cpB > 0:
                    trade_capital += abs(cpA) + abs(cpB)
                elif cpA > 0 and cpB < 0:
                    trade_capital += abs(cpA) + 0.9 * abs(cpB)
                elif cpA < 0 and cpB > 0:
                    trade_capital += 0.9 * abs(cpA) + abs(cpB)
                elif cpA < 0 and cpB < 0:
                    trade_capital += 0.9 * abs(cpA) + 0.9 * abs(cpB)
                    # down_open = table.mu[pos] - table.stdev[pos] * close_time
                trade += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到上開倉門檻 ,上開倉<br>",w1, w2, stock1_payoff+stock2_payoff])

            elif spread[i] > (close - stop_loss
                              ) and spread[i] < down_open:  # 碰到下開倉門檻且大於下停損門檻
                # 資金權重轉股票張數,並整數化

                # print(tick_data.mtimestamp[i],"碰到下開倉門檻 ,下開倉")
                w1, w2 = num_weight(tw1, tw2, tick_data[s1][i],
                                    tick_data[s2][i], maxi, capital)
                position = 1
                stock1_payoff = -w1 * slip(half_data[s1][2 * i + 1], -tw1)
                stock2_payoff = -w2 * slip(half_data[s2][2 * i + 1], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                cpA, cpB = stock1_payoff, stock2_payoff
                if cpA > 0 and cpB > 0:
                    trade_capital += abs(cpA) + abs(cpB)
                elif cpA > 0 and cpB < 0:
                    trade_capital += abs(cpA) + 0.9 * abs(cpB)
                elif cpA < 0 and cpB > 0:
                    trade_capital += 0.9 * abs(cpA) + abs(cpB)
                elif cpA < 0 and cpB < 0:
                    trade_capital += 0.9 * abs(cpA) + 0.9 * abs(cpB)
                # up_open = table.mu[pos] + table.stdev[pos] * close_time
                trade += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到下開倉門檻 ,下開倉<br>", -w1, -w2, stock1_payoff+stock2_payoff])
            else:
                position = 0
                stock1_payoff = 0
                stock2_payoff = 0
        elif position == -1:  # 之前有開空倉,平空倉
            if (spread[i] - close) < 0:  # 空倉碰到下開倉門檻即平倉

                # print(tick_data.mtimestamp[i],"之前有開空倉,碰到均值,平倉")
                position = 666  # 平倉
                stock1_payoff = -w1 * slip(half_data[s1][2 * i + 1], -tw1)
                stock2_payoff = -w2 * slip(half_data[s2][2 * i + 1], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[0] += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到均值,平倉<br>",-w1, -w2, stock1_payoff+stock2_payoff])
                # down_open = table.mu[pos] - table.stdev[pos] * open_time
                # 每次交易報酬做累加(最後除以交易次數做平均)
            elif spread[i] > (close + stop_loss):  # 空倉碰到上停損門檻即平倉停損

                # print(tick_data.mtimestamp[i],"之前有開空倉,碰到上停損門檻,強制平倉")
                position = -2  # 碰到停損門檻,強制平倉
                stock1_payoff = -w1 * slip(half_data[s1][2 * i + 1], -tw1)
                stock2_payoff = -w2 * slip(half_data[s2][2 * i + 1], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[1] += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到上停損門檻,強制平倉<br>",-w1, -w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 3):  # 回測結束,強制平倉
                # trade_process.append([tick_data.mtimestamp[i],"回測結束,強制平倉<br>"])
                # print(tick_data.mtimestamp[i],"回測結束,強制平倉")
                position = -4
                stock1_payoff = -w1 * slip(half_data[s1][2 * i + 1], -tw1)
                stock2_payoff = -w2 * slip(half_data[s2][2 * i + 1], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[2] += 1
                # trade_process.append([tick_data.mtimestamp[i],"回測結束,強制平倉<br>",-w1, -w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)
            else:
                position = -1
                stock1_payoff = 0
                stock2_payoff = 0
        elif position == 1:  # 之前有開多倉,平多倉
            if (spread[i] - close) > 0:

                # print(tick_data.mtimestamp[i],"之前有開多倉,碰到均值,平倉")
                position = 666  # 平倉
                stock1_payoff = w1 * slip(half_data[s1][2 * i + 1], tw1)
                stock2_payoff = w2 * slip(half_data[s2][2 * i + 1], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[0] += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到均值,平倉<br>",w1, w2, stock1_payoff+stock2_payoff])
                # up_open = table.mu[pos] + table.stdev[pos] * open_time
                # 每次交易報酬做累加(最後除以交易次數做平均)
            elif spread[i] < (close - stop_loss):

                # print(tick_data.mtimestamp[i],"之前有開多倉,碰到下停損門檻,強制平倉")
                position = -2  # 碰到停損門檻,強制平倉
                stock1_payoff = w1 * slip(half_data[s1][2 * i + 1], tw1)
                stock2_payoff = w2 * slip(half_data[s2][2 * i + 1], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[1] += 1

                # trade_process.append([tick_data.mtimestamp[i],"碰到下停損門檻,強制平倉<br>", w1, w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 3):  # 回測結束,強制平倉

                # print(tick_data.mtimestamp[i],"回測結束,強制平倉")
                position = -4
                stock1_payoff = w1 * slip(half_data[s1][2 * i + 1], tw1)
                stock2_payoff = w2 * slip(half_data[s2][2 * i + 1], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[2] += 1

                # trade_process.append([tick_data.mtimestamp[i],"回測結束,強制平倉<br>", w1, w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)
            else:
                position = 1
                stock1_payoff = 0
                stock2_payoff = 0
        else:
            # -4: 強迫平倉 -3: 結構性斷裂平倉(for lag 5) -2:停損 666:正常平倉
            if position == -2 or position == -3 or position == -4 or position == 666:
                stock1_payoff = 0
                stock2_payoff = 0
            else:
                position = 0  # 剩下時間少於預期開倉時間,則不開倉,避免損失
                stock1_payoff = 0
                stock2_payoff = 0

        pos.append(position)
        stock1_profit.append(stock1_payoff)
        stock2_profit.append(stock2_payoff)
    trading_profit = sum(stock1_profit) + sum(stock2_profit)

    local_profit = trading_profit
    # local_open_num.append(trade)
    if trade == 0:  # 如果都沒有開倉,則報酬為0
        # trade_process.append([tick_data.mtimestamp.iloc[-1],"無任何交易"])
        # print("沒有開倉")
        position = 0

    return used_news, local_profit, trade_capital, trade, position, tick_data[
        s1][0], tick_data[s2][0], dup_news
def pairs(pair, formate_time, table, min_data, tick_data, open_time,
          close_time, stop_loss_time, day1, maxi, tax_cost, cost_gate, capital,
          model):

    table = pd.DataFrame(table).T

    # 波動太小的配對不開倉
    if (open_time + close_time) * table.stdev[
            pair] < cost_gate or table.model_type[pair] != 'model5':

        trading_profit = 0

        trade = 0

        local_profit = 0
        local_open_num = 0
        local_rt = 0
        local_std = 0
        local_skew = 0
        local_timetrend = 0
        position = 0

        return [
            local_profit, local_open_num, local_rt, local_std, local_skew,
            local_timetrend, position
        ]

    min_price = day1
    #min_price = min_price.dropna(axis = 1)
    #min_price.index  = np.arange(0,len(min_price),1)

    #num = np.arange(0,len(table),1)

    t = formate_time  # formate time

    local_open_num = []
    local_profit = []
    local_rt = []
    #for pair in num:

    #spread = table.w1[pair] * np.log(min_data[ table.stock1[pair] ]) + table.w2[pair] * np.log(min_data[ table.stock2[pair] ])
    spread = table.w1[pair] * np.log(
        tick_data[table.stock1[pair]]) + table.w2[pair] * np.log(
            tick_data[table.stock2[pair]])

    if table.model_type[pair] == 'model4':

        x = np.arange(0, t)

        # 算出spread在formation period的斜率
        y = table.w1[pair] * np.log(
            min_price[table.stock1[pair]].iloc[0:t]) + table.w2[pair] * np.log(
                min_price[table.stock2[pair]].iloc[0:t])
        b1, b0 = np.polyfit(x, y, 1)

        # 算trading period 的序列
        x = np.arange(t, len(min_price))

        trend_line = x * b1 + b0
        spread = spread - trend_line

    else:

        b1 = 0

    up_open = table.mu[pair] + table.stdev[pair] * open_time  # 上開倉門檻
    down_open = table.mu[pair] - table.stdev[pair] * open_time  # 下開倉門檻

    stop_loss = table.stdev[pair] * stop_loss_time  # 停損門檻

    close = table.mu[pair]  # 平倉(均值)

    M = round(1 / table.zcr[pair])  # 平均持有時間

    trade = 0  # 計算開倉次數

    break_point = 0

    #discount = 1

    position = 0  # 持倉狀態,1:多倉,0:無倉,-1:空倉,-2:強制平倉

    #model=load_model('model.h5')
    #model.summary()

    pos = []
    stock1_profit = []
    stock2_profit = []
    for i in range(len(spread) - 2):

        stock1_seq = min_price[table.stock1[pair]].loc[0:t + i]
        stock2_seq = min_price[table.stock2[pair]].loc[0:t + i]

        if position == 0 and len(spread) - i > M:  # 之前無開倉

            if (spread[i] - up_open) * (spread[i + 1] - up_open) < 0:

                # 資金權重轉股票張數,並整數化
                w1, w2 = num_weight(table.w1[pair], table.w2[pair],
                                    tick_data[table.stock1[pair]][(i + 1)],
                                    tick_data[table.stock2[pair]][(i + 1)],
                                    maxi, capital)

                spread1 = w1 * np.log(stock1_seq) + w2 * np.log(stock2_seq)

                if adfuller(spread1, regression='ct'
                            )[1] > 1 or b1 > 0:  # spread平穩才開倉 & 趨勢向上不開空倉

                    position = 0

                    stock1_payoff = 0

                    stock2_payoff = 0

                else:

                    position = -1

                    stock1_payoff = w1 * slip(
                        tick_data[table.stock1[pair]][(i + 1)], table.w1[pair])

                    stock2_payoff = w2 * slip(
                        tick_data[table.stock2[pair]][(i + 1)], table.w2[pair])

                    stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                       stock2_payoff, position,
                                                       tax_cost)  # 計算交易成本

                    down_open = table.mu[pair] - table.stdev[pair] * close_time

                    trade = trade + 1

            elif (spread[i] - down_open) * (spread[i + 1] - down_open) < 0:

                # 資金權重轉股票張數,並整數化
                w1, w2 = num_weight(table.w1[pair], table.w2[pair],
                                    tick_data[table.stock1[pair]][(i + 1)],
                                    tick_data[table.stock2[pair]][(i + 1)],
                                    maxi, capital)

                spread1 = w1 * np.log(stock1_seq) + w2 * np.log(stock2_seq)

                if adfuller(spread1, regression='ct'
                            )[1] > 1 or b1 < 0:  # spread平穩才開倉 & 趨勢向下不開多倉

                    position = 0

                    stock1_payoff = 0

                    stock2_payoff = 0

                else:

                    position = 1

                    stock1_payoff = -w1 * slip(
                        tick_data[table.stock1[pair]][(i + 1)],
                        -table.w1[pair])

                    stock2_payoff = -w2 * slip(
                        tick_data[table.stock2[pair]][(i + 1)],
                        -table.w2[pair])

                    stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                       stock2_payoff, position,
                                                       tax_cost)  # 計算交易成本

                    up_open = table.mu[pair] + table.stdev[pair] * close_time

                    trade = trade + 1

            else:

                position = 0

                stock1_payoff = 0

                stock2_payoff = 0

        elif position == -1:  # 之前有開空倉,平空倉

            spread1 = table.w1[pair] * np.log(
                stock1_seq) + table.w2[pair] * np.log(stock2_seq)

            num = fore_chow(min_price[table.stock1[pair]].loc[0:t],
                            min_price[table.stock2[pair]].loc[0:t], stock1_seq,
                            stock2_seq, table.model_type[pair])

            if num == 0:

                break_point = 0

            else:  # num == 1

                break_point = break_point + num

            if (spread[i] - down_open) * (spread[i + 1] - down_open) < 0:

                position = 666  # 平倉

                stock1_payoff = -w1 * slip(
                    tick_data[table.stock1[pair]][(i + 1)], -table.w1[pair])

                stock2_payoff = -w2 * slip(
                    tick_data[table.stock2[pair]][(i + 1)], -table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本

                down_open = table.mu[pair] - table.stdev[pair] * open_time

                #每次交易報酬做累加(最後除以交易次數做平均)

            elif (spread[i] - (close + stop_loss)) * (spread[i + 1] -
                                                      (close + stop_loss)) < 0:

                position = -2  # 碰到停損門檻,強制平倉

                stock1_payoff = -w1 * slip(
                    tick_data[table.stock1[pair]][(i + 1)], -table.w1[pair])

                stock2_payoff = -w2 * slip(
                    tick_data[table.stock2[pair]][(i + 1)], -table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本

                #每次交易報酬做累加(最後除以交易次數做平均)

            #elif adfuller( spread1 )[1] > 0.05 :

            #position = -3                                                                                    # 出現單跟,強制平倉

            #stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+1)] , -table.w1[pair] )

            #stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+1)] , -table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            elif break_point == 3:

                position = -3  # 結構性斷裂,強制平倉

                stock1_payoff = -w1 * slip(
                    tick_data[table.stock1[pair]][(i + 1)], -table.w1[pair])

                stock2_payoff = -w2 * slip(
                    tick_data[table.stock2[pair]][(i + 1)], -table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                #每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 3):  # 回測結束,強制平倉

                position = -4

                stock1_payoff = -w1 * slip(
                    tick_data[table.stock1[pair]][len(tick_data) - 1],
                    -table.w1[pair])

                stock2_payoff = -w2 * slip(
                    tick_data[table.stock2[pair]][len(tick_data) - 1],
                    -table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本

                #每次交易報酬做累加(最後除以交易次數做平均)

            else:

                position = -1

                stock1_payoff = 0

                stock2_payoff = 0

        elif position == 1:  # 之前有開多倉,平多倉

            spread1 = table.w1[pair] * np.log(
                stock1_seq) + table.w2[pair] * np.log(stock2_seq)

            num = fore_chow(min_price[table.stock1[pair]].loc[0:t],
                            min_price[table.stock2[pair]].loc[0:t], stock1_seq,
                            stock2_seq, table.model_type[pair])

            if num == 0:

                break_point = 0

            else:  # num == 1

                break_point = break_point + num

            if (spread[i] - up_open) * (spread[i + 1] - up_open) < 0:

                position = 666  # 平倉

                stock1_payoff = w1 * slip(
                    tick_data[table.stock1[pair]][(i + 1)], table.w1[pair])

                stock2_payoff = w2 * slip(
                    tick_data[table.stock2[pair]][(i + 1)], table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本

                up_open = table.mu[pair] + table.stdev[pair] * open_time

                #每次交易報酬做累加(最後除以交易次數做平均)

            elif (spread[i] - (close - stop_loss)) * (spread[i + 1] -
                                                      (close - stop_loss)) < 0:

                position = -2  # 碰到停損門檻,強制平倉

                stock1_payoff = w1 * slip(
                    tick_data[table.stock1[pair]][(i + 1)], table.w1[pair])

                stock2_payoff = w2 * slip(
                    tick_data[table.stock2[pair]][(i + 1)], table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本

                #每次交易報酬做累加(最後除以交易次數做平均)

            #elif adfuller( spread1 )[1] > 0.05 :

            #position = -2                                                                                    # 出現單跟,強制平倉

            #stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+1)] , table.w1[pair] )

            #stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+1)] , table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            elif break_point == 3:

                position = -3  # 結構性斷裂,強制平倉

                stock1_payoff = w1 * slip(
                    tick_data[table.stock1[pair]][(i + 1)], table.w1[pair])

                stock2_payoff = w2 * slip(
                    tick_data[table.stock2[pair]][(i + 1)], table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                #每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 3):  # 回測結束,強制平倉

                position = -4

                stock1_payoff = w1 * slip(
                    tick_data[table.stock1[pair]][len(tick_data) - 1],
                    table.w1[pair])

                stock2_payoff = w2 * slip(
                    tick_data[table.stock2[pair]][len(tick_data) - 1],
                    table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本

                #每次交易報酬做累加(最後除以交易次數做平均)

            else:

                position = 1

                stock1_payoff = 0

                stock2_payoff = 0

        else:

            if position == -2 or position == -3 or position == -4 or position == 666:

                stock1_payoff = 0

                stock2_payoff = 0

            else:

                position = 0  # 剩下時間少於預期開倉時間,則不開倉,避免損失

                stock1_payoff = 0

                stock2_payoff = 0

        pos.append(position)

        stock1_profit.append(stock1_payoff)

        stock2_profit.append(stock2_payoff)

    trading_profit = sum(stock1_profit) + sum(stock2_profit)

    if trading_profit != 0 and position == 666:

        position = 666

    #local_profit.append(trading_profit)
    local_profit = trading_profit

    #local_open_num.append(trade)
    local_open_num = trade

    if trade == 0:  # 如果都沒有開倉,則報酬為0

        #local_rt.append(0)
        #local_std.append(0)
        #local_skew.append(0)
        #local_timetrend.append(0)

        local_rt = 0
        local_std = 0
        local_skew = 0
        local_timetrend = 0
        position = 0

    else:  # 計算平均報酬

        #local_rt.append(trading_profit/(capital*trade) )

        spread2 = w1 * np.log(
            min_price[table.stock1[pair]].iloc[0:t]) + w2 * np.log(
                min_price[table.stock2[pair]].iloc[0:t])

        #local_std.append(np.std(spread2))
        #local_skew.append(skew(spread2))

        x = np.arange(0, t)
        b1, b0 = np.polyfit(x, spread2, 1)

        #local_timetrend.append(b1)

        local_rt = trading_profit / (capital * trade)
        local_std = np.std(spread2)
        local_skew = skew(spread2)
        local_timetrend = b1

        #x = np.arange(0,121)
        #plt.plot(spread)
        #plt.axhline(y=close,color='r')
        #plt.axhline(y=up_open,color='r')
        #plt.axhline(y=down_open,color='r')
        #plt.axhline(y=close+stop_loss,color='green')
        #plt.axhline(y=close-stop_loss,color='green')

        #bp = np.array(np.where( np.array(pos) == -3 ))

        #if bp.size != 0:

        #plt.axvline(x=bp[0][0],color='green')

        #plt.show()

        #print([table.stock1[pair],table.stock2[pair],trading_profit])

    #posi = pos[len(spread)-2]
    '''
    if tax_cost == 0:
    
        local_profit = pd.DataFrame(local_profit)       ; local_profit.columns = ["profit without cost"]
        
    else:
        
        local_profit = pd.DataFrame(local_profit)       ; local_profit.columns = ["profit"]
        
    local_open_num = pd.DataFrame(local_open_num)   ; local_open_num.columns = ["open number"]
    local_rt = pd.DataFrame(local_rt)               ; local_rt.columns = ["return"]
    
    #back_test = pd.concat([local_profit,local_open_num,local_rt],axis=1)
    '''

    return [
        local_profit, local_open_num, local_rt, local_std, local_skew,
        local_timetrend, position
    ]  #table.stock1 , table.stock2 , local_profit , local_open_num , local_rt , local_std , local_skew , local_timetrend #, 0
Exemple #7
0
CNNBreak_price = AllCNNBreak_price
test_spread = Alltest_spread
test_stock1 = Alltest_stock1
test_stock2 = Alltest_stock2
test_vol_stock1 = Alltest_vol_stock1
test_vol_stock2 = Alltest_vol_stock2
record = Allrecord

##Open Test

#ADF Test
Open_table_index = []
int_w = []
for i in range(len(arg_mix)):
    if arg_mix[i] != 0:
        w1, w2 = num_weight(table.w1.iloc[i], table.w2.iloc[i],
                            Open_price[i, 0], Open_price[i, 1], maxi, capital)
        if Adf:
            if tick:
                ADF_spread = w1 * np.log( test_stock1[i,:(150*(1*half)+arg_test[i])] ) +\
                             w2 * np.log( test_stock2[i,:(150*(1*half)+arg_test[i])] )
            else:  #此處僅為表示tick與非tick算式一樣但想法上有本質上的不同
                ADF_spread = w1 * np.log( test_stock1[i,:(150+arg_test[i])] ) +\
                             w2 * np.log( test_stock2[i,:(150+arg_test[i])] )
            if adfuller(ADF_spread, regression='c')[1] <= 0.05:
                Open_table_index.append(i)
                int_w.append([w1, w2])
        else:
            Open_table_index.append(i)
            int_w.append([w1, w2])

int_w = np.array(int_w)
Exemple #8
0
def pairs(pair,
          formate_time,
          table,
          tick_data,
          up_open_time,
          down_open_time,
          stop_loss_time,
          day1,
          maxi,
          tax_cost,
          cost_gate,
          capital,
          dump=False):
    '''
    if str(table.stock1[pair]) == '1504' and str(table.stock2[pair]) == '2301':
        pass
    else:
        return 0,0,0,[0,0,0]
    '''
    #table = pd.DataFrame(table).T
    trade_capital = 0
    cpA, cpB = 0, 0
    trading = [0, 0, 0]
    '''
    if table.model_type[pair] == 'model1':
        model_name = 'H2'
    elif table.model_type[pair] == 'model2':
        model_name = 'H1*'
    else:
        model_name = 'H1'
    '''
    use_fore_lag5 = False
    use_adf = False
    # 波動太小的配對不開倉
    if up_open_time * table.Estd[pair] < cost_gate:
        trading_profit = 0
        trade = 0
        local_profit = 0
        local_open_num = 0
        local_rt = 0
        local_std = 0
        local_skew = 0
        local_timetrend = 0
        position = 0
        return local_profit, local_open_num, trade_capital, trading
    min_price = day1
    # min_price = min_price.dropna(axis = 1)
    # min_price.index  = np.arange(0,len(min_price),1)
    # num = np.arange(0,len(table),1)
    t = formate_time  # formate time
    stock1_seq = min_price[str(table.stock1[pair])].loc[0:t]
    stock2_seq = min_price[str(table.stock2[pair])].loc[0:t]
    # z = ( np.vstack( [stock1_seq , stock2_seq] ).T )
    # p = order_select(z,5)
    local_open_num = []
    local_profit = []
    local_rt = []
    local_std = []
    local_skew = []
    local_timetrend = []
    # for pair in num:
    spread = table.w1[pair] * np.log(tick_data[str(
        table.stock1[pair])]) + table.w2[pair] * np.log(tick_data[str(
            table.stock2[pair])])
    #print("spread length :",len(spread))
    up_open = table.Emu[pair] + table.Estd[pair] * up_open_time  # 上開倉門檻
    down_open = table.Emu[pair] - table.Estd[pair] * down_open_time  # 下開倉門檻
    stop_loss = table.Estd[pair] * stop_loss_time  # 停損門檻
    close = table.Emu[pair]  # 平倉(均值)
    #M = round(1 / table.zcr[pair])  # 平均持有時間
    trade = 0  # 計算開倉次數
    break_point = 0  # 計算累積斷裂點
    # break_CNN = 0
    # discount = 1
    position = 0  # 持倉狀態,1:多倉,0:無倉,-1:空倉,-2:強制平倉
    pos = [0]
    stock1_profit = []
    stock2_profit = []
    num = 0
    for i in range(0, len(spread) - 2):
        stock1_seq = min_price[str(table.stock1[pair])].loc[0:t + i]
        stock2_seq = min_price[str(table.stock2[pair])].loc[0:t + i]
        # z = ( np.vstack( [stock1_seq , stock2_seq] ).T )
        # r = rank( pd.DataFrame(z) , model_name , p )
        # if position == 0 and len(spread) - i > M:  # 之前無開倉
        #if position == 0 and i != len(spread) - 3 and i < 40:  # 之前無開倉
        if position == 0 and i != len(spread) - 3:
            if spread[i] < (close + stop_loss
                            ) and spread[i] > up_open:  # 碰到上開倉門檻且小於上停損門檻
                # 資金權重轉股票張數,並整數化
                w1, w2 = num_weight(table.w1[pair], table.w2[pair],
                                    tick_data[str(table.stock1[pair])][i],
                                    tick_data[str(table.stock2[pair])][i],
                                    maxi, capital)
                # print(str(table.stock1[pair]),str(table.stock2[pair]),w1,w2,tick_data[str(table.stock1[pair])][(i)],tick_data[str(table.stock2[pair])][(i)])

                spread1 = w1 * np.log(stock1_seq) + w2 * np.log(stock2_seq)
                if use_adf and adfuller(
                        spread1, regression='c')[1] > 0.05:  # spread平穩才開倉
                    position = 0
                    stock1_payoff = 0
                    stock2_payoff = 0
                else:
                    position = -1
                    stock1_payoff = w1 * slip(
                        tick_data[str(table.stock1[pair])][(i)],
                        table.w1[pair])
                    stock2_payoff = w2 * slip(
                        tick_data[str(table.stock2[pair])][(i)],
                        table.w2[pair])
                    stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                       stock2_payoff, position,
                                                       tax_cost)  # 計算交易成本
                    cpA, cpB = stock1_payoff, stock2_payoff
                    # down_open = table.mu[pair] - table.stdev[pair] * close_time
                    trade = trade + 1
            elif spread[i] > (close - stop_loss
                              ) and spread[i] < down_open:  # 碰到下開倉門檻且大於下停損門檻
                # 資金權重轉股票張數,並整數化
                w1, w2 = num_weight(table.w1[pair], table.w2[pair],
                                    tick_data[str(table.stock1[pair])][(i)],
                                    tick_data[str(table.stock2[pair])][(i)],
                                    maxi, capital)
                # print(str(table.stock1[pair]), str(table.stock2[pair]),w1,w2,tick_data[str(table.stock1[pair])][(i)],tick_data[str(table.stock2[pair])][(i)])

                spread1 = w1 * np.log(stock1_seq) + w2 * np.log(stock2_seq)
                if use_adf and adfuller(
                        spread1, regression='c')[1] > 0.05:  # spread平穩才開倉
                    position = 0
                    stock1_payoff = 0
                    stock2_payoff = 0
                else:
                    position = 1
                    stock1_payoff = -w1 * slip(
                        tick_data[str(table.stock1[pair])][(i)],
                        -table.w1[pair])
                    stock2_payoff = -w2 * slip(
                        tick_data[str(table.stock2[pair])][(i)],
                        -table.w2[pair])
                    stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                       stock2_payoff, position,
                                                       tax_cost)  # 計算交易成本
                    cpA, cpB = stock1_payoff, stock2_payoff
                    # up_open = table.mu[pair] + table.stdev[pair] * close_time
                    trade = trade + 1
            else:
                position = 0
                stock1_payoff = 0
                stock2_payoff = 0
        elif position == -1:  # 之前有開空倉,平空倉
            spread1 = table.w1[pair] * np.log(
                stock1_seq) + table.w2[pair] * np.log(stock2_seq)
            #num = fore_chow(min_price[str(table.stock1[pair])].loc[0:t], min_price[str(table.stock2[pair])].loc[0:t], stock1_seq,
            #stock2_seq, table.model_type[pair])  #做forlag5
            if use_fore_lag5:
                if num == 0:
                    break_point = 0
                else:  # num == 1
                    break_point = break_point + num
            '''   
            temp=np.array(spread1[i:t+i]).reshape(1,200,1)
            num = model.predict_classes(temp)
            if num == 0 or num == 4:
                break_CNN = 0
            else: # num == 1
                num = 1
                break_CNN = break_CNN + num
            '''
            if i == (len(spread) - 3):  # 回測結束,強制平倉
                position = -4
                stock1_payoff = -w1 * slip(
                    tick_data[str(table.stock1[pair])][i], -table.w1[pair])
                stock2_payoff = -w2 * slip(
                    tick_data[str(table.stock2[pair])][i], -table.w2[pair])
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[2] += 1
            elif (spread[i] - close) < 0:  # 空倉碰到下開倉門檻即平倉
                position = 666  # 平倉
                stock1_payoff = -w1 * slip(
                    tick_data[str(table.stock1[pair])][i], -table.w1[pair])
                stock2_payoff = -w2 * slip(
                    tick_data[str(table.stock2[pair])][i], -table.w2[pair])
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                # print(str(table.stock1[pair]),str(table.stock2[pair]),w1,w2,tick_data[str(table.stock1[pair])][(i)],tick_data[str(table.stock2[pair])][(i)])

                trading[0] += 1
                # down_open = table.mu[pair] - table.stdev[pair] * open_time
                # 每次交易報酬做累加(最後除以交易次數做平均)
            elif spread[i] > (close + stop_loss):  # 空倉碰到上停損門檻即平倉停損
                position = -2  # 碰到停損門檻,強制平倉
                stock1_payoff = -w1 * slip(
                    tick_data[str(table.stock1[pair])][(i)], -table.w1[pair])
                stock2_payoff = -w2 * slip(
                    tick_data[str(table.stock2[pair])][(i)], -table.w2[pair])
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[1] += 1
                # 每次交易報酬做累加(最後除以交易次數做平均)
            # elif adfuller( spread1 , regression='c' )[1] > 0.05 :
            # position = -3                                                                                    # 出現單跟,強制平倉
            # stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+1)] , -table.w1[pair] )
            # stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+1)] , -table.w2[pair] )
            # stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            # 每次交易報酬做累加(最後除以交易次數做平均)
            # elif r < 1:
            # position = -3                                                                                    # 結構性斷裂,強制平倉
            # stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+1)] , -table.w1[pair] )
            # stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+1)] , -table.w2[pair] )
            # stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            # 每次交易報酬做累加(最後除以交易次數做平均)
            elif break_point == 5:
                position = -3  # 結構性斷裂,強制平倉
                stock1_payoff = -w1 * slip(
                    tick_data[str(table.stock1[pair])][(i + 1)],
                    -table.w1[pair])
                stock2_payoff = -w2 * slip(
                    tick_data[str(table.stock2[pair])][(i + 1)],
                    -table.w2[pair])
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[2] += 1
            # 每次交易報酬做累加(最後除以交易次數做平均)
            # elif spread_chow( spread1 , i ) == 1 :
            # position = -2                                                                                    # 結構性斷裂,強制平倉
            # stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+2)] , -table.w1[pair] )
            # stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+2)] , -table.w2[pair] )
            # stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            # 每次交易報酬做累加(最後除以交易次數做平均)
            # elif send_request( spread1 , 150 , 0.9 ) == 1:
            # position = -2                                                                                    # LSTM偵測,強制平倉
            # stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+2)] , -table.w1[pair] )
            # stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+2)] , -table.w2[pair] )
            # stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            # 每次交易報酬做累加(最後除以交易次數做平均)
            # elif break_CNN == 5:
            # position = -3                                                                                    # CNN偵測,強制平倉
            # stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+2)] , -table.w1[pair] )
            # stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+2)] , -table.w2[pair] )
            # stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            # 每次交易報酬做累加(最後除以交易次數做平均)

            # print(str(table.stock1[pair]), str(table.stock2[pair]), w1, w2, tick_data[str(table.stock1[pair])][(i)],
            #      tick_data[str(table.stock2[pair])][(i)])
            # 每次交易報酬做累加(最後除以交易次數做平均)
            else:
                position = -1
                stock1_payoff = 0
                stock2_payoff = 0
        elif position == 1:  # 之前有開多倉,平多倉
            spread1 = table.w1[pair] * np.log(
                stock1_seq) + table.w2[pair] * np.log(stock2_seq)
            #num = fore_chow(min_price[str(table.stock1[pair])].loc[0:t], min_price[str(table.stock2[pair])].loc[0:t], stock1_seq,
            # stock2_seq, table.model_type[pair]) #做forlag5
            if use_fore_lag5:
                if num == 0:
                    break_point = 0
                else:  # num == 1
                    break_point = break_point + num
            '''
            temp=np.array(spread1[i:t+i]).reshape(1,200,1)
            num = model.predict_classes(temp)
            if num == 0 or num == 4:
                break_CNN = 0
            else: # num == 1
                num = 1
                break_CNN = break_CNN + num
            '''
            if i == (len(spread) - 3):  # 回測結束,強制平倉
                position = -4
                stock1_payoff = w1 * slip(
                    tick_data[str(table.stock1[pair])][i], table.w1[pair])
                stock2_payoff = w2 * slip(
                    tick_data[str(table.stock2[pair])][i], table.w2[pair])
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[2] += 1
                # print(str(table.stock1[pair]), str(table.stock2[pair]), w1, w2, tick_data[str(table.stock1[pair])][(i)],
                #      tick_data[str(table.stock2[pair])][(i)])
                # 每次交易報酬做累加(最後除以交易次數做平均)
            elif (spread[i] - close) > 0:
                position = 666  # 平倉
                stock1_payoff = w1 * slip(
                    tick_data[str(table.stock1[pair])][(i)], table.w1[pair])
                stock2_payoff = w2 * slip(
                    tick_data[str(table.stock2[pair])][(i)], table.w2[pair])
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                # print(str(table.stock1[pair]),str(table.stock2[pair]),w1,w2,tick_data[str(table.stock1[pair])][(i)],tick_data[str(table.stock2[pair])][(i)])

                trading[0] += 1
                # up_open = table.mu[pair] + table.stdev[pair] * open_time
                # 每次交易報酬做累加(最後除以交易次數做平均)
            elif spread[i] < (close - stop_loss):
                position = -2  # 碰到停損門檻,強制平倉
                stock1_payoff = w1 * slip(
                    tick_data[str(table.stock1[pair])][(i)], table.w1[pair])
                stock2_payoff = w2 * slip(
                    tick_data[str(table.stock2[pair])][(i)], table.w2[pair])
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[1] += 1
                # 每次交易報酬做累加(最後除以交易次數做平均)
            # elif adfuller( spread1 , regression='c' )[1] > 0.05 :
            # position = -3                                                                                    # 出現單跟,強制平倉
            # stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+1)] , table.w1[pair] )
            # stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+1)] , table.w2[pair] )
            # stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            # 每次交易報酬做累加(最後除以交易次數做平均)
            # elif r < 1:
            # position = -3                                                                                        # 結構性斷裂,強制平倉
            # stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+1)] , table.w1[pair] )
            # stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+1)] , table.w2[pair] )
            # stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )            # 計算交易成本
            # 每次交易報酬做累加(最後除以交易次數做平均)
            elif break_point == 5:
                position = -3  # 結構性斷裂,強制平倉
                stock1_payoff = w1 * slip(
                    tick_data[str(table.stock1[pair])][(i)], table.w1[pair])
                stock2_payoff = w2 * slip(
                    tick_data[str(table.stock2[pair])][(i)], table.w2[pair])
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[2] += 1
            # 每次交易報酬做累加(最後除以交易次數做平均)
            # elif spread_chow( spread1 , i ) == 1 :
            # position = -2                                                                                        # 結構性斷裂,強制平倉
            # stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+2)] , table.w1[pair] )
            # stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+2)] , table.w2[pair] )
            # stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )            # 計算交易成本
            # 每次交易報酬做累加(最後除以交易次數做平均)
            # elif send_request( spread1 , 150 , 0.9 ) == 1:
            # position = -2                                                                                    # LSTM偵測,強制平倉
            # stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+2)] , table.w1[pair] )
            # stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+2)] , table.w2[pair] )
            # stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            # 每次交易報酬做累加(最後除以交易次數做平均)
            # elif break_CNN == 5:
            # position = -3                                                                                    # CNN偵測,強制平倉
            # stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+2)] , table.w1[pair] )
            # stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+2)] , table.w2[pair] )
            # stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            # 每次交易報酬做累加(最後除以交易次數做平均)
            else:
                position = 1
                stock1_payoff = 0
                stock2_payoff = 0
        else:
            # -4: 強迫平倉 -3: 結構性斷裂平倉(for lag 5) -2:停損 666:正常平倉
            if position == -2 or position == -3 or position == -4 or position == 666:
                stock1_payoff = 0
                stock2_payoff = 0
            else:
                position = 0  # 剩下時間少於預期開倉時間,則不開倉,避免損失
                stock1_payoff = 0
                stock2_payoff = 0
        pos.append(position)
        stock1_profit.append(stock1_payoff)
        stock2_profit.append(stock2_payoff)
    trading_profit = sum(stock1_profit) + sum(stock2_profit)

    if trading_profit != 0 and position == 666:
        position = 666
    # if (open_time + close_time) * table.stdev[pair] < cost_gate:
    # trading_profit = 0
    # trade = 0
    # local_profit.append(trading_profit)
    local_profit = trading_profit
    # local_open_num.append(trade)
    local_open_num = trade
    if trade == 0:  # 如果都沒有開倉,則報酬為0
        # local_rt.append(0)
        # local_std.append(0)
        # local_skew.append(0)
        # local_timetrend.append(0)
        local_rt = 0
        local_std = 0
        local_skew = 0
        local_timetrend = 0
        position = 0
    else:  # 計算平均報酬
        # local_rt.append(trading_profit/(capital*trade) )
        spread2 = w1 * np.log(min_price[str(
            table.stock1[pair])].iloc[0:t]) + w2 * np.log(min_price[str(
                table.stock2[pair])].iloc[0:t])
        # local_std.append(np.std(spread2))
        # local_skew.append(skew(spread2))
        x = np.arange(0, t)
        b1, b0 = np.polyfit(x, spread2, 1)
        # local_timetrend.append(b1)
        local_rt = trading_profit / (capital * trade)
        local_std = np.std(spread2)
        local_skew = skew(spread2)
        local_timetrend = b1

    if cpA > 0 and cpB > 0:
        trade_capital = abs(cpA) + abs(cpB)
    elif cpA > 0 and cpB < 0:
        trade_capital = abs(cpA) + 0.9 * abs(cpB)
    elif cpA < 0 and cpB > 0:
        trade_capital = 0.9 * abs(cpA) + abs(cpB)
    elif cpA < 0 and cpB < 0:
        trade_capital = 0.9 * abs(cpA) + 0.9 * abs(cpB)
    # -4: 強迫平倉 -3: 結構性斷裂平倉(for lag 5) -2:停損 666:正常平倉
    if True:  # (position == -2 or position == -3 or position == -4) and local_profit <= -10 :
        if dump:
            plot_spread(table.stock1[pair], table.stock2[pair], spread,
                        up_open, down_open, stop_loss, close, local_profit,
                        pos, position, up_open_time, down_open_time,
                        stop_loss_time)
    return local_profit, local_open_num, trade_capital, trading
Exemple #9
0
def pairs(pair, formate_time, table, min_data, tick_data, open_time,
          stop_loss_time, day1, maxi, tax_cost, capital):
    text_file = open("./label/label5.txt", "a", encoding="utf-8")
    table = pd.DataFrame(table).T
    #print(table.stock1[pair],table.stock2[pair])
    min_price = day1

    #min_price = min_price.dropna(axis = 1)
    #min_price.index  = np.arange(0,len(min_price),1)

    #num = np.arange(0,len(table),1)

    t = formate_time  # formate time

    local_open_num = []
    local_profit = []
    local_rt = []
    #for pair in num:

    spread = table.w1[pair] * np.log(
        min_data[table.stock1[pair]]) + table.w2[pair] * np.log(
            min_data[table.stock2[pair]])

    up_open = table.mu[pair] + table.stdev[pair] * open_time  # 上開倉門檻
    down_open = table.mu[pair] - table.stdev[pair] * open_time  # 下開倉門檻

    stop_loss = table.stdev[pair] * stop_loss_time  # 停損門檻

    close = table.mu[pair]  # 平倉(均值)

    M = round(1 /
              table.zcr[pair]) if (len(spread) >= 115
                                   and table.zcr[pair] != 0) else 0  # 平均持有時間

    trade = 0  # 計算開倉次數
    #discount = 1

    position = 0  # 持倉狀態,1:多倉,0:無倉,-1:空倉,-2:強制平倉

    #model=load_model('model.h5')
    #model.summary()

    pos = []
    stock1_profit = []
    stock2_profit = []
    no_more = False
    for i in range(len(spread) - 2):
        #print(str(min_price["mtimestamp"][t+i]) + ":  ", end="")
        stock1_seq = min_price[table.stock1[pair]].loc[0:t + i]
        stock2_seq = min_price[table.stock2[pair]].loc[0:t + i]

        if position == 0 and len(spread) - i > M:  # 之前無開倉
            #print("之前無開倉,且剩餘時間大於平均持有時間 ",  end="")
            if (spread[i] - up_open) * (spread[i + 1] - up_open) < 0:
                #print("碰到上開倉門檻, ", end="")
                # 資金權重轉股票張數,並整數化
                w1, w2 = num_weight(table.w1[pair], table.w2[pair],
                                    tick_data[table.stock1[pair]][(i + 2)],
                                    tick_data[table.stock2[pair]][(i + 2)],
                                    maxi, capital)

                spread1 = w1 * np.log(stock1_seq) + w2 * np.log(stock2_seq)

                if adfuller(spread1, regression='ct')[1] > 0.05:  # spread平穩才開倉
                    #print("spread不平穩,不開倉")
                    position = 0

                    stock1_payoff = 0

                    stock2_payoff = 0

                else:

                    position = -1

                    stock1_payoff = w1 * slip(
                        tick_data[table.stock1[pair]][(i + 2)], table.w1[pair])

                    stock2_payoff = w2 * slip(
                        tick_data[table.stock2[pair]][(i + 2)], table.w2[pair])

                    stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                       stock2_payoff, position,
                                                       tax_cost)  # 計算交易成本

                    trade = trade + 1
                    #print("spread平穩,上開倉", int(w1), stock1_payoff, int(w2), stock2_payoff)

            elif (spread[i] - down_open) * (spread[i + 1] - down_open) < 0:
                #print("碰到下開倉門檻, ", end="")
                # 資金權重轉股票張數,並整數化
                w1, w2 = num_weight(table.w1[pair], table.w2[pair],
                                    tick_data[table.stock1[pair]][(i + 2)],
                                    tick_data[table.stock2[pair]][(i + 2)],
                                    maxi, capital)

                spread1 = w1 * np.log(stock1_seq) + w2 * np.log(stock2_seq)

                if adfuller(spread1, regression='ct')[1] > 0.05:  # spread平穩才開倉
                    #print("spread不平穩,不開倉")
                    position = 0

                    stock1_payoff = 0

                    stock2_payoff = 0

                else:

                    position = 1

                    stock1_payoff = -w1 * slip(
                        tick_data[table.stock1[pair]][(i + 2)],
                        -table.w1[pair])

                    stock2_payoff = -w2 * slip(
                        tick_data[table.stock2[pair]][(i + 2)],
                        -table.w2[pair])

                    stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                       stock2_payoff, position,
                                                       tax_cost)  # 計算交易成本

                    trade = trade + 1
                    #print("spread平穩,下開倉", int(w1), stock1_payoff, int(w2), stock2_payoff)

            else:
                #print("沒碰到開倉門檻,維持不開倉")
                position = 0

                stock1_payoff = 0

                stock2_payoff = 0

        elif position == -1:  # 之前有開空倉,平空倉
            #print("之前有開空倉, ", end="")
            spread1 = table.w1[pair] * np.log(
                stock1_seq) + table.w2[pair] * np.log(stock2_seq)

            #temp=spread1[i+1:t+i+1].reshape(1,150,1)
            #pre=model.predict_classes(temp)

            if (spread[i] - close) * (spread[i + 1] - close) < 0:

                position = 0  # 平倉

                stock1_payoff = -w1 * slip(
                    tick_data[table.stock1[pair]][(i + 2)], -table.w1[pair])

                stock2_payoff = -w2 * slip(
                    tick_data[table.stock2[pair]][(i + 2)], -table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                #print("碰到均值,平空倉", int(w1), stock1_payoff, int(w2), stock2_payoff)

                #每次交易報酬做累加(最後除以交易次數做平均)

            elif (spread[i] - (close + stop_loss)) * (spread[i + 1] -
                                                      (close + stop_loss)) < 0:

                position = -2  # 碰到停損門檻,強制平倉

                stock1_payoff = -w1 * slip(
                    tick_data[table.stock1[pair]][(i + 2)], -table.w1[pair])

                stock2_payoff = -w2 * slip(
                    tick_data[table.stock2[pair]][(i + 2)], -table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                #print("碰到停損門檻,強制平倉", int(w1), stock1_payoff, int(w2), stock2_payoff)
                #每次交易報酬做累加(最後除以交易次數做平均)

            #elif adfuller( spread1 , regression='ct' )[1] > 0.05 :

            #position = -3                                                                                    # 出現單跟,強制平倉

            #stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+2)] , -table.w1[pair] )

            #stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+2)] , -table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            elif fore_chow(min_price[table.stock1[pair]].loc[0:t],
                           min_price[table.stock2[pair]].loc[0:t], stock1_seq,
                           stock2_seq) == 1:

                position = -3  # 結構性斷裂,強制平倉

                stock1_payoff = -w1 * slip(
                    tick_data[table.stock1[pair]][(i + 2)], -table.w1[pair])

                stock2_payoff = -w2 * slip(
                    tick_data[table.stock2[pair]][(i + 2)], -table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                print("結構性斷裂,強制平倉", int(w1), stock1_payoff, int(w2),
                      stock2_payoff)
                #每次交易報酬做累加(最後除以交易次數做平均)

            #elif spread_chow( spread1 , i ) == 1 :

            #position = -2                                                                                    # 結構性斷裂,強制平倉

            #stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+2)] , -table.w1[pair] )

            #stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+2)] , -table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif send_request( spread1 , 150 , 0.9 ) == 1:

            #position = -2                                                                                    # LSTM偵測,強制平倉

            #stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+2)] , -table.w1[pair] )

            #stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+2)] , -table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif ( (pre!=0) | (pre!=4) ):

            #position = -2                                                                                    # CNN偵測,強制平倉

            #stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+2)] , -table.w1[pair] )

            #stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+2)] , -table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 3):  # 回測結束,強制平倉

                position = -2

                stock1_payoff = -w1 * slip(
                    tick_data[table.stock1[pair]][len(tick_data) - 1],
                    -table.w1[pair])

                stock2_payoff = -w2 * slip(
                    tick_data[table.stock2[pair]][len(tick_data) - 1],
                    -table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                #print("回測結束,強制平倉", int(w1), stock1_payoff, int(w2), stock2_payoff)
                #每次交易報酬做累加(最後除以交易次數做平均)

            else:
                #print("沒碰到均值,維持")
                position = -1

                stock1_payoff = 0

                stock2_payoff = 0

        elif position == 1:  # 之前有開多倉,平多倉
            #print("之前有開多倉, ", end="")
            spread1 = table.w1[pair] * np.log(
                stock1_seq) + table.w2[pair] * np.log(stock2_seq)

            #temp=spread1[i+1:t+i+1].reshape(1,150,1)
            #pre=model.predict_classes(temp)

            if (spread[i] - close) * (spread[i + 1] - close) < 0:

                position = 0  # 平倉

                stock1_payoff = w1 * slip(
                    tick_data[table.stock1[pair]][(i + 2)], table.w1[pair])

                stock2_payoff = w2 * slip(
                    tick_data[table.stock2[pair]][(i + 2)], table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                #print("碰到均值,平多倉", int(w1), stock1_payoff, int(w2), stock2_payoff)
                #每次交易報酬做累加(最後除以交易次數做平均)

            elif (spread[i] - (close - stop_loss)) * (spread[i + 1] -
                                                      (close - stop_loss)) < 0:

                position = -2  # 碰到停損門檻,強制平倉

                stock1_payoff = w1 * slip(
                    tick_data[table.stock1[pair]][(i + 2)], table.w1[pair])

                stock2_payoff = w2 * slip(
                    tick_data[table.stock2[pair]][(i + 2)], table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                #print("碰到停損門檻,強制平倉", int(w1), stock1_payoff, int(w2), stock2_payoff)
                #每次交易報酬做累加(最後除以交易次數做平均)

            #elif adfuller( spread1 , regression='ct' )[1] > 0.05 :

            #position = -3                                                                                    # 出現單跟,強制平倉

            #stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+2)] , table.w1[pair] )

            #stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+2)] , table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            elif fore_chow(min_price[table.stock1[pair]].loc[0:t],
                           min_price[table.stock2[pair]].loc[0:t], stock1_seq,
                           stock2_seq) == 1:

                position = -3  # 結構性斷裂,強制平倉

                stock1_payoff = w1 * slip(
                    tick_data[table.stock1[pair]][(i + 2)], table.w1[pair])

                stock2_payoff = w2 * slip(
                    tick_data[table.stock2[pair]][(i + 2)], table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                print("結構性斷裂,強制平倉", int(w1), stock1_payoff, int(w2),
                      stock2_payoff)
                #每次交易報酬做累加(最後除以交易次數做平均)

            #elif spread_chow( spread1 , i ) == 1 :

            #position = -2                                                                                        # 結構性斷裂,強制平倉

            #stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+2)] , table.w1[pair] )

            #stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+2)] , table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )            # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif send_request( spread1 , 150 , 0.9 ) == 1:

            #position = -2                                                                                    # LSTM偵測,強制平倉

            #stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+2)] , table.w1[pair] )

            #stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+2)] , table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif ( (pre!=0) | (pre!=4) ):

            #position = -2                                                                                    # CNN偵測,強制平倉

            #stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+2)] , table.w1[pair] )

            #stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+2)] , table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 3):  # 回測結束,強制平倉

                position = -2

                stock1_payoff = w1 * slip(
                    tick_data[table.stock1[pair]][len(tick_data) - 1],
                    table.w1[pair])

                stock2_payoff = w2 * slip(
                    tick_data[table.stock2[pair]][len(tick_data) - 1],
                    table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                #print("回測結束,強制平倉", int(w1), stock1_payoff, int(w2), stock2_payoff)
                #每次交易報酬做累加(最後除以交易次數做平均)

            else:
                #print("沒碰到均值,維持")
                position = 1

                stock1_payoff = 0

                stock2_payoff = 0

        else:
            no_more = True
            if position == -2 or position == -3:
                if (position == -3):

                    #print(",".join([table.stock1[pair],str(min_price["mtimestamp"][t+i])]))
                    print(",".join([
                        table.stock1[pair], table.stock2[pair],
                        str(min_price["mtimestamp"][t + i])
                    ]),
                          file=text_file)
                    #print(",".join([table.stock1[pair],str(min_price["mtimestamp"][t+i])]),file=text_file)
                print("配對已經不適合交易")
                stock1_payoff = 0

                stock2_payoff = 0

            else:
                #print("剩下時間少於預期開倉時間,不開倉,避免損失")
                position = 0  # 剩下時間少於預期開倉時間,則不開倉,避免損失

                stock1_payoff = 0

                stock2_payoff = 0

        pos.append(position)

        stock1_profit.append(stock1_payoff)

        stock2_profit.append(stock2_payoff)
        if (no_more):
            break

    #print(position)

    #x = np.arange(0,121)
    #plt.plot(spread)
    #plt.axhline(y=close,color='r')
    #plt.axhline(y=up_open,color='r')
    #plt.axhline(y=down_open,color='r')
    #plt.axhline(y=close+stop_loss,color='green')
    #plt.axhline(y=close-stop_loss,color='green')

    #bp = np.array(np.where( pos == -3 ))

    #if bp.size != 0:

    #plt.axvline(x=bp[0][0],color='green')

    #plt.show()

    trading_profit = sum(stock1_profit) + sum(stock2_profit)

    if 1.2 * table.stdev[pair] < tax_cost:

        trading_profit = 0

        trade = 0

    local_profit.append(trading_profit)
    #local_profit = trading_profit

    local_open_num.append(trade)
    #local_open_num = trade

    if trade == 0:  # 如果都沒有開倉,則報酬為0

        local_rt.append(0)
        #local_rt = 0

    else:  # 計算平均報酬

        local_rt.append(trading_profit / (capital * trade))
        #local_rt = trading_profit/(capital*trade)

    #posi = pos[len(spread)-2]
    '''
    if tax_cost == 0:
    
        local_profit = pd.DataFrame(local_profit)       ; local_profit.columns = ["profit without cost"]
        
    else:
        
        local_profit = pd.DataFrame(local_profit)       ; local_profit.columns = ["profit"]
        
    local_open_num = pd.DataFrame(local_open_num)   ; local_open_num.columns = ["open number"]
    local_rt = pd.DataFrame(local_rt)               ; local_rt.columns = ["return"]
    
    #back_test = pd.concat([local_profit,local_open_num,local_rt],axis=1)
    '''
    return table.stock1, table.stock2, local_profit, local_open_num, local_rt  #, 0
Exemple #10
0
def pairs(pair, formate_time, table, min_data, tick_data, open_time,
          close_time, stop_loss_time, day1, maxi, tax_cost, cost_gate, capital,
          model):

    table = pd.DataFrame(table).T
    '''
    if table.model_type[pair] == 'model1':
        
        model_name = 'H2'
        
    elif table.model_type[pair] == 'model2':
        
        model_name = 'H1*'
        
    else:
       
        model_name = 'H1'
    '''
    # 波動太小的配對不開倉
    if (open_time + close_time) * table.stdev[pair] < cost_gate:

        trading_profit = 0

        trade = 0

        local_profit = 0
        local_open_num = 0
        local_rt = 0
        local_std = 0
        local_skew = 0
        local_timetrend = 0
        position = 0

        return [
            local_profit, local_open_num, local_rt, local_std, local_skew,
            local_timetrend, position
        ]

    min_price = day1
    #min_price = min_price.dropna(axis = 1)
    #min_price.index  = np.arange(0,len(min_price),1)

    #num = np.arange(0,len(table),1)

    t = formate_time  # formate time

    stock1_seq = min_price[table.stock1[pair]].loc[0:t]
    stock2_seq = min_price[table.stock2[pair]].loc[0:t]

    #z = ( np.vstack( [stock1_seq , stock2_seq] ).T )
    #p = order_select(z,5)

    local_open_num = []
    local_profit = []
    local_rt = []
    local_std = []
    local_skew = []
    local_timetrend = []
    #for pair in num:

    #spread = table.w1[pair] * np.log(min_data[ table.stock1[pair] ]) + table.w2[pair] * np.log(min_data[ table.stock2[pair] ])
    spread = table.w1[pair] * np.log(
        tick_data[table.stock1[pair]]) + table.w2[pair] * np.log(
            tick_data[table.stock2[pair]])

    up_open = table.mu[pair] + table.stdev[pair] * open_time  # 上開倉門檻
    down_open = table.mu[pair] - table.stdev[pair] * open_time  # 下開倉門檻

    stop_loss = table.stdev[pair] * stop_loss_time  # 停損門檻

    close = table.mu[pair]  # 平倉(均值)

    M = round(1 / table.zcr[pair])  # 平均持有時間

    trade = 0  # 計算開倉次數

    break_point = 0  # 計算累積斷裂點

    #break_CNN = 0

    #discount = 1

    position = 0  # 持倉狀態,1:多倉,0:無倉,-1:空倉,-2:強制平倉

    pos = []
    stock1_profit = []
    stock2_profit = []
    for i in range(len(spread) - 2):

        stock1_seq = min_price[table.stock1[pair]].loc[0:t + i]
        stock2_seq = min_price[table.stock2[pair]].loc[0:t + i]

        #z = ( np.vstack( [stock1_seq , stock2_seq] ).T )

        #r = rank( pd.DataFrame(z) , model_name , p )

        if position == 0 and len(spread) - i > M:  # 之前無開倉

            if (spread[i] - up_open) * (spread[i + 1] - up_open) < 0:

                # 資金權重轉股票張數,並整數化
                w1, w2 = num_weight(table.w1[pair], table.w2[pair],
                                    tick_data[table.stock1[pair]][(i + 1)],
                                    tick_data[table.stock2[pair]][(i + 1)],
                                    maxi, capital)

                spread1 = w1 * np.log(stock1_seq) + w2 * np.log(stock2_seq)

                if adfuller(spread1, regression='c')[1] > 1:  # spread平穩才開倉

                    position = 0

                    stock1_payoff = 0

                    stock2_payoff = 0

                else:

                    position = -1

                    stock1_payoff = w1 * slip(
                        tick_data[table.stock1[pair]][(i + 1)], table.w1[pair])

                    stock2_payoff = w2 * slip(
                        tick_data[table.stock2[pair]][(i + 1)], table.w2[pair])

                    stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                       stock2_payoff, position,
                                                       tax_cost)  # 計算交易成本

                    down_open = table.mu[pair] - table.stdev[pair] * close_time

                    trade = trade + 1

            elif (spread[i] - down_open) * (spread[i + 1] - down_open) < 0:

                # 資金權重轉股票張數,並整數化
                w1, w2 = num_weight(table.w1[pair], table.w2[pair],
                                    tick_data[table.stock1[pair]][(i + 1)],
                                    tick_data[table.stock2[pair]][(i + 1)],
                                    maxi, capital)

                spread1 = w1 * np.log(stock1_seq) + w2 * np.log(stock2_seq)

                if adfuller(spread1, regression='c')[1] > 1:  # spread平穩才開倉

                    position = 0

                    stock1_payoff = 0

                    stock2_payoff = 0

                else:

                    position = 1

                    stock1_payoff = -w1 * slip(
                        tick_data[table.stock1[pair]][(i + 1)],
                        -table.w1[pair])

                    stock2_payoff = -w2 * slip(
                        tick_data[table.stock2[pair]][(i + 1)],
                        -table.w2[pair])

                    stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                       stock2_payoff, position,
                                                       tax_cost)  # 計算交易成本

                    up_open = table.mu[pair] + table.stdev[pair] * close_time

                    trade = trade + 1

            else:

                position = 0

                stock1_payoff = 0

                stock2_payoff = 0

        elif position == -1:  # 之前有開空倉,平空倉

            spread1 = table.w1[pair] * np.log(
                stock1_seq) + table.w2[pair] * np.log(stock2_seq)

            num = fore_chow(min_price[table.stock1[pair]].loc[0:t],
                            min_price[table.stock2[pair]].loc[0:t], stock1_seq,
                            stock2_seq, table.model_type[pair])

            if num == 0:

                break_point = 0

            else:  # num == 1

                break_point = break_point + num
            '''   
            temp=np.array(spread1[i:t+i]).reshape(1,200,1)
            num = model.predict_classes(temp)
            
            if num == 0 or num == 4:
                
                break_CNN = 0
                
            else: # num == 1
                
                num = 1
                break_CNN = break_CNN + num
            '''

            if (spread[i] - down_open) * (spread[i + 1] - down_open) < 0:

                position = 666  # 平倉

                stock1_payoff = -w1 * slip(
                    tick_data[table.stock1[pair]][(i + 1)], -table.w1[pair])

                stock2_payoff = -w2 * slip(
                    tick_data[table.stock2[pair]][(i + 1)], -table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本

                down_open = table.mu[pair] - table.stdev[pair] * open_time

                #每次交易報酬做累加(最後除以交易次數做平均)

            elif (spread[i] - (close + stop_loss)) * (spread[i + 1] -
                                                      (close + stop_loss)) < 0:

                position = -2  # 碰到停損門檻,強制平倉

                stock1_payoff = -w1 * slip(
                    tick_data[table.stock1[pair]][(i + 1)], -table.w1[pair])

                stock2_payoff = -w2 * slip(
                    tick_data[table.stock2[pair]][(i + 1)], -table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本

                #每次交易報酬做累加(最後除以交易次數做平均)

            #elif adfuller( spread1 , regression='c' )[1] > 0.05 :

            #position = -3                                                                                    # 出現單跟,強制平倉

            #stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+1)] , -table.w1[pair] )

            #stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+1)] , -table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif r < 1:

            #position = -3                                                                                    # 結構性斷裂,強制平倉

            #stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+1)] , -table.w1[pair] )

            #stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+1)] , -table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif break_point == 1:

            #position = -3                                                                                    # 結構性斷裂,強制平倉

            #stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+1)] , -table.w1[pair] )

            #stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+1)] , -table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif spread_chow( spread1 , i ) == 1 :

            #position = -2                                                                                    # 結構性斷裂,強制平倉

            #stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+2)] , -table.w1[pair] )

            #stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+2)] , -table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif send_request( spread1 , 150 , 0.9 ) == 1:

            #position = -2                                                                                    # LSTM偵測,強制平倉

            #stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+2)] , -table.w1[pair] )

            #stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+2)] , -table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif break_CNN == 5:

            #position = -3                                                                                    # CNN偵測,強制平倉

            #stock1_payoff = -w1 * slip( tick_data[table.stock1[pair]][(i+2)] , -table.w1[pair] )

            #stock2_payoff = -w2 * slip( tick_data[table.stock2[pair]][(i+2)] , -table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 3):  # 回測結束,強制平倉

                position = -4

                stock1_payoff = -w1 * slip(
                    tick_data[table.stock1[pair]][len(tick_data) - 1],
                    -table.w1[pair])

                stock2_payoff = -w2 * slip(
                    tick_data[table.stock2[pair]][len(tick_data) - 1],
                    -table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本

                #每次交易報酬做累加(最後除以交易次數做平均)

            else:

                position = -1

                stock1_payoff = 0

                stock2_payoff = 0

        elif position == 1:  # 之前有開多倉,平多倉

            spread1 = table.w1[pair] * np.log(
                stock1_seq) + table.w2[pair] * np.log(stock2_seq)

            num = fore_chow(min_price[table.stock1[pair]].loc[0:t],
                            min_price[table.stock2[pair]].loc[0:t], stock1_seq,
                            stock2_seq, table.model_type[pair])

            if num == 0:

                break_point = 0

            else:  # num == 1

                break_point = break_point + num
            '''
            temp=np.array(spread1[i:t+i]).reshape(1,200,1)
            num = model.predict_classes(temp)
            
            if num == 0 or num == 4:
                
                break_CNN = 0
                
            else: # num == 1
                
                num = 1
                break_CNN = break_CNN + num
            '''

            if (spread[i] - up_open) * (spread[i + 1] - up_open) < 0:

                position = 666  # 平倉

                stock1_payoff = w1 * slip(
                    tick_data[table.stock1[pair]][(i + 1)], table.w1[pair])

                stock2_payoff = w2 * slip(
                    tick_data[table.stock2[pair]][(i + 1)], table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本

                up_open = table.mu[pair] + table.stdev[pair] * open_time

                #每次交易報酬做累加(最後除以交易次數做平均)

            elif (spread[i] - (close - stop_loss)) * (spread[i + 1] -
                                                      (close - stop_loss)) < 0:

                position = -2  # 碰到停損門檻,強制平倉

                stock1_payoff = w1 * slip(
                    tick_data[table.stock1[pair]][(i + 1)], table.w1[pair])

                stock2_payoff = w2 * slip(
                    tick_data[table.stock2[pair]][(i + 1)], table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本

                #每次交易報酬做累加(最後除以交易次數做平均)

            #elif adfuller( spread1 , regression='c' )[1] > 0.05 :

            #position = -3                                                                                    # 出現單跟,強制平倉

            #stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+1)] , table.w1[pair] )

            #stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+1)] , table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif r < 1:

            #position = -3                                                                                        # 結構性斷裂,強制平倉

            #stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+1)] , table.w1[pair] )

            #stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+1)] , table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )            # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif break_point == 1:

            #position = -3                                                                                        # 結構性斷裂,強制平倉

            #stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+1)] , table.w1[pair] )

            #stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+1)] , table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )            # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif spread_chow( spread1 , i ) == 1 :

            #position = -2                                                                                        # 結構性斷裂,強制平倉

            #stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+2)] , table.w1[pair] )

            #stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+2)] , table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )            # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif send_request( spread1 , 150 , 0.9 ) == 1:

            #position = -2                                                                                    # LSTM偵測,強制平倉

            #stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+2)] , table.w1[pair] )

            #stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+2)] , table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            #elif break_CNN == 5:

            #position = -3                                                                                    # CNN偵測,強制平倉

            #stock1_payoff = w1 * slip( tick_data[table.stock1[pair]][(i+2)] , table.w1[pair] )

            #stock2_payoff = w2 * slip( tick_data[table.stock2[pair]][(i+2)] , table.w2[pair] )

            #stock1_payoff , stock2_payoff = tax(stock1_payoff , stock2_payoff , position , tax_cost )        # 計算交易成本
            #每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 3):  # 回測結束,強制平倉

                position = -4

                stock1_payoff = w1 * slip(
                    tick_data[table.stock1[pair]][len(tick_data) - 1],
                    table.w1[pair])

                stock2_payoff = w2 * slip(
                    tick_data[table.stock2[pair]][len(tick_data) - 1],
                    table.w2[pair])

                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本

                #每次交易報酬做累加(最後除以交易次數做平均)

            else:

                position = 1

                stock1_payoff = 0

                stock2_payoff = 0

        else:

            if position == -2 or position == -3 or position == -4 or position == 666:

                stock1_payoff = 0

                stock2_payoff = 0

            else:

                position = 0  # 剩下時間少於預期開倉時間,則不開倉,避免損失

                stock1_payoff = 0

                stock2_payoff = 0

        pos.append(position)

        stock1_profit.append(stock1_payoff)

        stock2_profit.append(stock2_payoff)

    trading_profit = sum(stock1_profit) + sum(stock2_profit)

    if trading_profit != 0 and position == 666:

        position = 666

    #if (open_time + close_time) * table.stdev[pair] < cost_gate:

    #trading_profit = 0

    #trade = 0

    #local_profit.append(trading_profit)
    local_profit = trading_profit

    #local_open_num.append(trade)
    local_open_num = trade

    if trade == 0:  # 如果都沒有開倉,則報酬為0

        #local_rt.append(0)
        #local_std.append(0)
        #local_skew.append(0)
        #local_timetrend.append(0)

        local_rt = 0
        local_std = 0
        local_skew = 0
        local_timetrend = 0
        position = 0

    else:  # 計算平均報酬

        #local_rt.append(trading_profit/(capital*trade) )

        spread2 = w1 * np.log(
            min_price[table.stock1[pair]].iloc[0:t]) + w2 * np.log(
                min_price[table.stock2[pair]].iloc[0:t])

        #local_std.append(np.std(spread2))
        #local_skew.append(skew(spread2))

        x = np.arange(0, t)
        b1, b0 = np.polyfit(x, spread2, 1)

        #local_timetrend.append(b1)

        local_rt = trading_profit / (capital * trade)
        local_std = np.std(spread2)
        local_skew = skew(spread2)
        local_timetrend = b1

        #x = np.arange(0,121)
        #plt.plot(spread)
        #plt.axhline(y=close,color='r')
        #plt.axhline(y=up_open,color='r')
        #plt.axhline(y=down_open,color='r')
        #plt.axhline(y=close+stop_loss,color='green')
        #plt.axhline(y=close-stop_loss,color='green')

        #bp = np.array(np.where( np.array(pos) == -3 ))

        #if bp.size != 0:

        #plt.axvline(x=bp[0][0],color='green')

        #plt.show()

        #print([table.stock1[pair],table.stock2[pair],trading_profit])

    #posi = pos[len(spread)-2]
    '''
    if tax_cost == 0:
    
        local_profit = pd.DataFrame(local_profit)       ; local_profit.columns = ["profit without cost"]
        
    else:
        
        local_profit = pd.DataFrame(local_profit)       ; local_profit.columns = ["profit"]
        
    local_open_num = pd.DataFrame(local_open_num)   ; local_open_num.columns = ["open number"]
    local_rt = pd.DataFrame(local_rt)               ; local_rt.columns = ["return"]
    
    #back_test = pd.concat([local_profit,local_open_num,local_rt],axis=1)
    '''

    return [
        local_profit, local_open_num, local_rt, local_std, local_skew,
        local_timetrend, position
    ]  #table.stock1 , table.stock2 , local_profit , local_open_num , local_rt , local_std , local_skew , local_timetrend #, 0
Exemple #11
0
def pairs(s1_tick, s2_tick, table, strategy):

    trade_capital = 0
    cpA,cpB = 0,0
    trading_profit = 0.0
    trade = 0
    trade_capital = 0    
    trade_return = 0.0


    # 波動太小的配對不開倉
    if volaitlity_small(strategy, table):
        return trade, trading_profit, trade_capital, trade_return


    spread = table["w1"] * np.log(s1_tick) + table["w2"] * np.log(s2_tick)
    close, up_open, down_open = build_open(spread, table, strategy)

    position = 0  # 持倉狀態,1:多倉,0:無倉,-1:空倉,-2:強制平倉 
    stock1_profit = []
    stock2_profit = []
    spread_len = len(spread)
    for i in range(0, spread_len - 2):
        if position == 0 and i != spread_len - 3:  # 之前無開倉
        
            if spread[i] < down_open[i]:  # 碰到下開倉門檻且大於下停損門檻
                w1, w2 = num_weight(table["w1"], table["w2"], s1_tick[i], s2_tick[i], strategy["maxhold"], strategy["captial"])
                stock1_payoff, stock2_payoff = down_open(
                    time = i,
                    s1_tick = s1_tick
                    s2_tick = s2_tick, 
                    table = table,
                    strategy = strategy                    
                )
                cpA, cpB = stock1_payoff, stock2_payoff
                position = 1
                trade = 1
                stock1_profit.append(stock1_payoff)
                stock2_profit.append(stock2_payoff)


        elif position == -1:  # 之前有開空倉,平空倉

            if i == (spread_len - 3):  # 回測結束,強制平倉
                position = -4
                stock1_payoff, stock2_payoff = up_close(w1, w2,  s1_tick[i], s2_tick[i], strategy["tax_cost"], position)
                stock1_profit.append(stock1_payoff)
                stock2_profit.append(stock2_payoff)
                break

            elif (spread[i] - close[i]) < 0:  # 空倉碰到下開倉門檻即平倉
                position = 666  # 平倉
                stock1_payoff, stock2_payoff = up_close(w1, w2,  s1_tick[i], s2_tick[i], strategy["tax_cost"], position)
                stock1_profit.append(stock1_payoff)
                stock2_profit.append(stock2_payoff)
                break


        elif position == 1:  # 之前有開多倉,平多倉

            if (i == spread_len - 3):  # 回測結束,強制平倉
                position = -4
                stock1_payoff, stock2_payoff = down_close(w1, w2,  s1_tick[i], s2_tick[i], strategy["tax_cost"], position)
                stock1_profit.append(stock1_payoff)
                stock2_profit.append(stock2_payoff)
                break

            elif (spread[i] - close[i]) > 0:
                position = 666  # 平倉
                stock1_payoff, stock2_payoff = down_close(w1, w2,  s1_tick[i], s2_tick[i], strategy["tax_cost"], position)
                stock1_profit.append(stock1_payoff)
                stock2_profit.append(stock2_payoff)
                break

    trading_profit = sum(stock1_profit) + sum(stock2_profit)



    if cpA > 0 and cpB > 0:
        trade_capital = abs(cpA) + abs(cpB)
    elif cpA > 0 and cpB < 0 :
        trade_capital = abs(cpA) + 0.9 * abs(cpB)
    elif cpA < 0 and cpB > 0 :
        trade_capital = 0.9 * abs(cpA) + abs(cpB)
    elif cpA < 0 and cpB < 0 :
        trade_capital = 0.9 * abs(cpA) + 0.9 * abs(cpB)

    if trade > 0:  # 如果都沒有開倉,則報酬為0
        trade_return = trading_profit / trade_capital


    return trade, trading_profit, trade_capital
            
Exemple #12
0
def pairs(
    choose_date,
    pos,
    formate_time,
    table,
    tick_data,
    half_data,
    prev_data,
    maxi,
    tax_cost,
    cost_gate,
    capital,
):

    s1 = str(table.stock1[pos])
    s2 = str(table.stock2[pos])

    tw1 = table.w1[pos]
    tw2 = table.w2[pos]
    Estd = table.Estd[pos]
    Emu = table.Emu[pos]

    up_open_time = 1.5
    down_open_time = up_open_time
    stop_loss_time = 10000  #actions[table.action[pos]][1] #actions[0][1] 2.5

    up_open = Emu + Estd * up_open_time  # 上開倉門檻
    down_open = Emu - Estd * down_open_time  # 下開倉門檻
    stop_loss = Estd * stop_loss_time  # stop_loss_time  # 停損門檻
    close = Emu  # 平倉(均值)

    trade_capital = 0
    cpA, cpB = 0, 0
    trading = [0, 0, 0]

    trade_capital = 0
    cpA, cpB = 0, 0
    trading = [0, 0, 0]

    used_news = False
    re_last = False

    choose_date = choose_date[:4] + "-" + choose_date[4:6] + "-" + choose_date[
        6:]
    s1_news = pd.DataFrame()
    s2_news = pd.DataFrame()
    if s1 in all_news:
        s1_news = pd.DataFrame.from_dict(all_news[s1])
        s1_news = s1_news[s1_news["time"].str.startswith(choose_date)]
    if s2 in all_news:
        s2_news = pd.DataFrame.from_dict(all_news[s2])
        s2_news = s2_news[s2_news["time"].str.startswith(choose_date)]

    _9am = pd.to_datetime(choose_date + " 01:00", utc=True)
    if not s1_news.empty:
        s1_news["predict"] = s1_news["predict"].apply(lambda x: -1
                                                      if x == 0 else x)
        s1_news["time"] = pd.to_datetime(s1_news["time"], utc=True)
        s1_news["9am_offset"] = s1_news["time"].apply(
            lambda x: (x.ceil(freq='1T') - _9am).total_seconds() // 60)
        s1_news = s1_news[(s1_news["9am_offset"] <= 300)
                          & (s1_news["9am_offset"] >= -120)]

    if not s2_news.empty:
        s2_news["predict"] = s2_news["predict"].apply(lambda x: -1
                                                      if x == 0 else x)
        s2_news["time"] = pd.to_datetime(s2_news["time"], utc=True)
        s2_news["9am_offset"] = s2_news["time"].apply(
            lambda x: (x.ceil(freq='1T') - _9am).total_seconds() // 60)
        s2_news = s2_news[(s2_news["9am_offset"] <= 300)
                          & (s2_news["9am_offset"] >= -120)]

    # if not s1_news.empty or not s2_news.empty:
    #     print(s1_news, s2_news)

    # # 波動太小的配對不開倉
    if up_open_time * Estd < cost_gate:
        # trade_process.append([tick_data.mtimestamp[1], "配對波動太小,不開倉"])
        # print("配對波動太小,不開倉")
        trading_profit = 0
        trade = 0
        local_profit = 0
        position = 0
        return used_news, local_profit, trade_capital, trade, 0, 0, 0, re_last

    t = formate_time  # formate time

    local_profit = []

    spread = tw1 * np.log(tick_data[s1]) + tw2 * np.log(tick_data[s2])

    # M = round(1 / table.zcr[pos])  # 平均持有時間
    trade = 0  # 計算開倉次數
    break_point = 0  # 計算累積斷裂點

    position = 0  # 持倉狀態,1:多倉,0:無倉,-1:空倉,-2:強制平倉
    pos = [0, 0]
    stock1_profit = []
    stock2_profit = []

    # print(s1_news, s2_news)
    for i in range(0, len(spread) - 2):
        if (position == 0 and i != (len(spread) - 3) and i < 40):  # 之前無開倉
            s1_news_trend = 0
            s2_news_trend = 0
            if not s1_news.empty:
                tmp_s1_news = s1_news[(s1_news["9am_offset"] <=
                                       (i + formate_time))].tail()
                if not tmp_s1_news.empty:
                    s1_news_trend = tmp_s1_news["predict"].iloc[0]

            if not s2_news.empty:
                tmp_s2_news = s2_news[(s2_news["9am_offset"] <=
                                       (i + formate_time))].tail()
                if not tmp_s2_news.empty:
                    s2_news_trend = tmp_s2_news["predict"].iloc[0]

            s1_stock_trend = tick_data[s1][i] - prev_data[s1][0]
            s2_stock_trend = tick_data[s2][i] - prev_data[s2][0]

            if spread[i] < (close + stop_loss
                            ) and spread[i] > up_open:  # 碰到上開倉門檻且小於上停損門檻
                # 資金權重轉股票張數,並整數化
                if ((s1_news_trend * (-tw1)) < 0
                        or (s2_news_trend * (-tw2)) < 0):
                    used_news = True
                    if (((-tw1) * (-s1_stock_trend)) < 0
                            or ((-tw2) * (-s2_stock_trend)) < 0):
                        re_last = True
                        continue
                else:
                    if (s1_news_trend != 0 or s2_news_trend != 0):
                        used_news = True
                        if (((-tw1) * (-s1_stock_trend)) < 0
                                or ((-tw2) * (-s2_stock_trend)) < 0):
                            re_last = True
                            continue

                # print(tick_data.mtimestamp[i],"碰到上開倉門檻 ,上開倉")
                w1, w2 = num_weight(tw1, tw2, tick_data[s1][2 * i + 1],
                                    tick_data[s2][2 * i + 1], maxi, capital)
                position = -1
                stock1_payoff = w1 * slip(half_data[s1][2 * i + 1], tw1)
                stock2_payoff = w2 * slip(half_data[s2][2 * i + 1], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                cpA, cpB = stock1_payoff, stock2_payoff
                if cpA > 0 and cpB > 0:
                    trade_capital += abs(cpA) + abs(cpB)
                elif cpA > 0 and cpB < 0:
                    trade_capital += abs(cpA) + 0.9 * abs(cpB)
                elif cpA < 0 and cpB > 0:
                    trade_capital += 0.9 * abs(cpA) + abs(cpB)
                elif cpA < 0 and cpB < 0:
                    trade_capital += 0.9 * abs(cpA) + 0.9 * abs(cpB)
                    # down_open = table.mu[pos] - table.stdev[pos] * close_time
                trade += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到上開倉門檻 ,上開倉<br>",w1, w2, stock1_payoff+stock2_payoff])

            elif spread[i] > (close - stop_loss
                              ) and spread[i] < down_open:  # 碰到下開倉門檻且大於下停損門檻
                # 資金權重轉股票張數,並整數化
                if ((s1_news_trend * tw1) < 0 or (s2_news_trend * tw2) < 0):
                    used_news = True
                    if (((tw1) * (-s1_stock_trend)) < 0
                            or ((tw2) * (-s2_stock_trend)) < 0):
                        re_last = True
                        continue
                else:
                    if (s1_news_trend != 0 or s2_news_trend != 0):
                        used_news = True
                        if (((tw1) * (-s1_stock_trend)) < 0
                                or ((tw2) * (-s2_stock_trend)) < 0):
                            re_last = True
                            continue

                # print(tick_data.mtimestamp[i],"碰到下開倉門檻 ,下開倉")
                w1, w2 = num_weight(tw1, tw2, tick_data[s1][2 * i + 1],
                                    tick_data[s2][2 * i + 1], maxi, capital)
                position = 1
                stock1_payoff = -w1 * slip(half_data[s1][2 * i + 1], -tw1)
                stock2_payoff = -w2 * slip(half_data[s2][2 * i + 1], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                cpA, cpB = stock1_payoff, stock2_payoff
                if cpA > 0 and cpB > 0:
                    trade_capital += abs(cpA) + abs(cpB)
                elif cpA > 0 and cpB < 0:
                    trade_capital += abs(cpA) + 0.9 * abs(cpB)
                elif cpA < 0 and cpB > 0:
                    trade_capital += 0.9 * abs(cpA) + abs(cpB)
                elif cpA < 0 and cpB < 0:
                    trade_capital += 0.9 * abs(cpA) + 0.9 * abs(cpB)
                # up_open = table.mu[pos] + table.stdev[pos] * close_time
                trade += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到下開倉門檻 ,下開倉<br>", -w1, -w2, stock1_payoff+stock2_payoff])
            else:
                position = 0
                stock1_payoff = 0
                stock2_payoff = 0
        elif position == -1:  # 之前有開空倉,平空倉
            if (spread[i] - close) < 0:  # 空倉碰到下開倉門檻即平倉

                # print(tick_data.mtimestamp[i],"之前有開空倉,碰到均值,平倉")
                position = 666  # 平倉
                stock1_payoff = -w1 * slip(half_data[s1][2 * i + 1], -tw1)
                stock2_payoff = -w2 * slip(half_data[s2][2 * i + 1], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[0] += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到均值,平倉<br>",-w1, -w2, stock1_payoff+stock2_payoff])
                # down_open = table.mu[pos] - table.stdev[pos] * open_time
                # 每次交易報酬做累加(最後除以交易次數做平均)
            elif spread[i] > (close + stop_loss):  # 空倉碰到上停損門檻即平倉停損

                # print(tick_data.mtimestamp[i],"之前有開空倉,碰到上停損門檻,強制平倉")
                position = -2  # 碰到停損門檻,強制平倉
                stock1_payoff = -w1 * slip(half_data[s1][2 * i + 1], -tw1)
                stock2_payoff = -w2 * slip(half_data[s2][2 * i + 1], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[1] += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到上停損門檻,強制平倉<br>",-w1, -w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 3):  # 回測結束,強制平倉
                # trade_process.append([tick_data.mtimestamp[i],"回測結束,強制平倉<br>"])
                # print(tick_data.mtimestamp[i],"回測結束,強制平倉")
                position = -4
                stock1_payoff = -w1 * slip(half_data[s1][2 * i + 1], -tw1)
                stock2_payoff = -w2 * slip(half_data[s2][2 * i + 1], -tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[2] += 1
                # trade_process.append([tick_data.mtimestamp[i],"回測結束,強制平倉<br>",-w1, -w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)
            else:
                position = -1
                stock1_payoff = 0
                stock2_payoff = 0
        elif position == 1:  # 之前有開多倉,平多倉
            if (spread[i] - close) > 0:

                # print(tick_data.mtimestamp[i],"之前有開多倉,碰到均值,平倉")
                position = 666  # 平倉
                stock1_payoff = w1 * slip(half_data[s1][2 * i + 1], tw1)
                stock2_payoff = w2 * slip(half_data[s2][2 * i + 1], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[0] += 1
                # trade_process.append([tick_data.mtimestamp[i],"碰到均值,平倉<br>",w1, w2, stock1_payoff+stock2_payoff])
                # up_open = table.mu[pos] + table.stdev[pos] * open_time
                # 每次交易報酬做累加(最後除以交易次數做平均)
            elif spread[i] < (close - stop_loss):

                # print(tick_data.mtimestamp[i],"之前有開多倉,碰到下停損門檻,強制平倉")
                position = -2  # 碰到停損門檻,強制平倉
                stock1_payoff = w1 * slip(half_data[s1][2 * i + 1], tw1)
                stock2_payoff = w2 * slip(half_data[s2][2 * i + 1], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[1] += 1

                # trade_process.append([tick_data.mtimestamp[i],"碰到下停損門檻,強制平倉<br>", w1, w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)

            elif i == (len(spread) - 3):  # 回測結束,強制平倉

                # print(tick_data.mtimestamp[i],"回測結束,強制平倉")
                position = -4
                stock1_payoff = w1 * slip(half_data[s1][2 * i + 1], tw1)
                stock2_payoff = w2 * slip(half_data[s2][2 * i + 1], tw2)
                stock1_payoff, stock2_payoff = tax(stock1_payoff,
                                                   stock2_payoff, position,
                                                   tax_cost)  # 計算交易成本
                trading[2] += 1

                # trade_process.append([tick_data.mtimestamp[i],"回測結束,強制平倉<br>", w1, w2, stock1_payoff+stock2_payoff])
                # 每次交易報酬做累加(最後除以交易次數做平均)
            else:
                position = 1
                stock1_payoff = 0
                stock2_payoff = 0
        else:
            # -4: 強迫平倉 -3: 結構性斷裂平倉(for lag 5) -2:停損 666:正常平倉
            if position == -2 or position == -3 or position == -4 or position == 666:
                stock1_payoff = 0
                stock2_payoff = 0
            else:
                position = 0  # 剩下時間少於預期開倉時間,則不開倉,避免損失
                stock1_payoff = 0
                stock2_payoff = 0

        pos.append(position)
        stock1_profit.append(stock1_payoff)
        stock2_profit.append(stock2_payoff)
    trading_profit = sum(stock1_profit) + sum(stock2_profit)

    local_profit = trading_profit
    # local_open_num.append(trade)
    if trade == 0:  # 如果都沒有開倉,則報酬為0
        # trade_process.append([tick_data.mtimestamp.iloc[-1],"無任何交易"])
        # print("沒有開倉")
        position = 0

    return used_news, local_profit, trade_capital, trade, position, tick_data[
        s1][0], tick_data[s2][0], re_last