def up_open(w1, w2, s1_price, s2_price, tax_cost): position = -1 stock1_payoff = w1 * s1_price stock2_payoff = w2 * s2_price stock1_payoff, stock2_payoff = tax(stock1_payoff, stock2_payoff, position, tax_cost) # 計算交易成本 return stock1_payoff, stock2_payoff
def down_open(w1, w2, s1_price, s2_price, tax_cost): position = 0 stock1_payoff = -w1 * s1_price stock2_payoff = -w2 * s2_price stock1_payoff, stock2_payoff = tax(stock1_payoff, stock2_payoff, position, tax_cost) # 計算交易成本 return stock1_payoff, stock2_payoff
def up_close(w1, w2, s1_price, s2_price, tax_cost, position): stock1_payoff = -w1 * s1_price stock2_payoff = -w2 * s2_price stock1_payoff, stock2_payoff = tax(stock1_payoff, stock2_payoff, position, tax_cost) # 計算交易成本 return stock1_payoff, stock2_payoff
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
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]
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 single(self): min_price = self.day1 min_price = min_price.dropna(axis=1) min_price.index = np.arange(0, len(min_price), 1) num = np.arange(0, len(self.table), 1) open_num = [] profit = [] rt = [] for pair in num: if 1.5 * self.table.stdev[pair] < self.tax_cost: open_num.append(0) profit.append(0) rt.append(0) continue #pair = 55 spread = np.log(self.min_data[self.table.stock[pair]]) #x = np.arange(0,61) #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') up_open = self.table.mu[ pair] + self.table.stdev[pair] * self.open_time # 上開倉門檻 down_open = self.table.mu[ pair] - self.table.stdev[pair] * self.open_time # 下開倉門檻 stop_loss = self.table.stdev[pair] * self.stop_loss_time # 停損門檻 close = self.table.mu[pair] # 平倉(均值) M = round(self.table.zcr[pair] * len(spread)) # 平均持有時間 trade = 0 # 計算開倉次數 spread_return = 0 position = 0 # 持倉狀態,1:多倉,0:無倉,-1:空倉,-2:強制平倉 pos = [] stock_profit = [] for i in range(len(spread) - 2): if position == 0 and len(spread) - i > M: # 之前無開倉 if (spread[i] - up_open) * (spread[i + 1] - up_open) < 0: position = -1 stock_payoff = slip( self.tick_data[self.table.stock[pair]][(i + 2)], 1) stock_payoff, stock2_payoff = tax( stock_payoff, 1, position, self.tax_cost) # 交易成本 spreadprice = stock_payoff # 計算報酬用 trade = trade + 1 elif (spread[i] - down_open) * (spread[i + 1] - down_open) < 0: position = 1 stock_payoff = -slip( self.tick_data[self.table.stock[pair]][(i + 2)], -1) stock_payoff, stock2_payoff = tax( stock_payoff, 1, position, self.tax_cost) # 交易成本 spreadprice = stock_payoff # 計算報酬用 trade = trade + 1 else: position = 0 stock_payoff = 0 elif position == -1: # 之前有開空倉,平空倉 if (spread[i] - close) * (spread[i + 1] - close) < 0: position = 0 # 平倉 stock_payoff = -slip( self.tick_data[self.table.stock[pair]][(i + 2)], -1) stock_payoff, stock2_payoff = tax( stock_payoff, 1, position, self.tax_cost) # 交易成本 spread_return = spread_return + ( spreadprice + stock_payoff) / abs( spreadprice) # 每次交易報酬做累加(最後除以交易次數做平均) elif (spread[i] - (close + stop_loss)) * (spread[i + 1] - (close + stop_loss)) < 0: position = -2 # 碰到停損門檻,強制平倉 stock_payoff = -slip( self.tick_data[self.table.stock[pair]][(i + 2)], -1) stock_payoff, stock2_payoff = tax( stock_payoff, 1, position, self.tax_cost) # 交易成本 spread_return = spread_return + ( spreadprice + stock_payoff) / abs( spreadprice) # 每次交易報酬做累加(最後除以交易次數做平均) elif i == (len(spread) - 3): # 回測結束,強制平倉 position = 0 stock_payoff = -slip( self.tick_data[self.table.stock[pair]][ len(self.tick_data) - 1], -1) stock_payoff, stock2_payoff = tax( stock_payoff, 1, position, self.tax_cost) # 交易成本 spread_return = spread_return + ( spreadprice + stock_payoff) / abs( spreadprice) # 每次交易報酬做累加(最後除以交易次數做平均) else: position = -1 stock_payoff = 0 elif position == 1: # 之前有開多倉,平多倉 if (spread[i] - close) * (spread[i + 1] - close) < 0: position = 0 # 平倉 stock_payoff = slip( self.tick_data[self.table.stock[pair]][(i + 2)], 1) stock_payoff, stock2_payoff = tax( stock_payoff, 1, position, self.tax_cost) # 交易成本 spread_return = spread_return + ( spreadprice + stock_payoff) / abs( spreadprice) # 每次交易報酬做累加(最後除以交易次數做平均) elif (spread[i] - (close - stop_loss)) * (spread[i + 1] - (close - stop_loss)) < 0: position = -2 # 碰到停損門檻,強制平倉 stock_payoff = slip( self.tick_data[self.table.stock[pair]][(i + 2)], 1) stock_payoff, stock2_payoff = tax( stock_payoff, 1, position, self.tax_cost) # 交易成本 spread_return = spread_return + ( spreadprice + stock_payoff) / abs( spreadprice) # 每次交易報酬做累加(最後除以交易次數做平均) elif i == (len(spread) - 3): # 回測結束,強制平倉 position = 0 stock_payoff = slip( self.tick_data[self.table.stock[pair]][ len(self.tick_data) - 1], 1) stock_payoff, stock2_payoff = tax( stock_payoff, 1, position, self.tax_cost) # 交易成本 spread_return = spread_return + ( spreadprice + stock_payoff) / abs( spreadprice) # 每次交易報酬做累加(最後除以交易次數做平均) else: position = 1 stock_payoff = 0 else: if position == -2: position = -2 stock_payoff = 0 else: position = 0 # 剩下時間少於預期開倉時間,則不開倉,避免損失 stock_payoff = 0 pos.append(position) stock_profit.append(stock_payoff) trading_profit = sum(stock_profit) profit.append(trading_profit) open_num.append(trade) if trade == 0: # 如果都沒有開倉,報酬率為0 rt.append(0) else: # 計算平均報酬 rt.append(spread_return / trade) profit = pd.DataFrame(profit) if self.tax_cost == 0: profit.columns = ["profit without cost"] else: profit.columns = ["profit"] open_num = pd.DataFrame(open_num) open_num.columns = ["open number"] rt = pd.DataFrame(rt) rt.columns = ["return"] back_test = pd.concat([profit, open_num, rt], axis=1) return back_test
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
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
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
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
def down_close(w1, w2, s1_price, s2_price, tax_cost, position): stock1_payoff = w1 * slip(s1_price, w1) stock2_payoff = w2 * slip(s2_price, w2) stock1_payoff, stock2_payoff = tax(stock1_payoff, stock2_payoff, position, tax_cost) # 計算交易成本
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