交易
基於協整的配對交易-權益線
我正在我的大學準備一個項目,我必須使用兩隻股票之間的協整來製定一個簡單的配對交易策略。
我被困在淨值線計算上。我已經準備了開盤和收盤信號,但仍然需要準備一張**淨值線圖,**但我不知道如何計算它。
有一些細節:
做多被低估的股票,做空被高估的股票
允許無邊界賣空,押金為賣空價值的100%
開倉時,我們假設空頭頭寸和多頭頭寸的份額相等
-開/關信號由收盤價定義,倉位由次日開盤價****開/平
-交易費用為頭寸價值的0.1%(開盤和收盤時)
是的,即使使用 pandas 之類的好工具,它也可以非常複雜。但基本思想是找到頭寸進入和退出以獲得現金流。
這是我從生成的信號中獲取所有這些東西的程式碼(在我的回測器中,信號是每個時刻投資組合中 2 支股票的一部分)。我希望我在這裡找到了所有的錯誤,但沒有保證。 Total_invested變數用於僅使用初始資本計算投資組合中的股份總數。
實際上,這段程式碼是我將在幾個月內開源的回測引擎的一部分。它還處理點差和固定佣金,因此您可以跳過這一部分。這將需要適應您的條件,但希望有所幫助!
另請查看Mike Halls-Moore 的文章。這個網站對我幫助很大!
def get_portfolio(self, signals, prices): time_index = prices.index end = time_index[-1] # Assets prices x_prices = prices[self.sym1] y_prices = prices[self.sym2] # Assets weights in portfolio x_weights = signals.map(lambda sig:sig[self.sym1]) y_weights = signals.map(lambda sig:sig[self.sym2]) # Total number of invested shares total_invested = pd.Series(index = signals.index) # Need trade enters to calculate portfolio size enter_points = x_weights.diff().fillna(0)!=0 # Index magic here: # We need to delete position exits, we suppose there are separate enters/exits enter_points[enter_points[enter_points].index[1::2]] = False # capital = w₁⋅total⋅p₁ + w₂⋅total⋅p₂ (cover position) total_invested[enter_points] = (self.initial_capital /(x_weights.abs()[enter_points]*x_prices[enter_points] + y_weights.abs()[enter_points]*y_prices[enter_points])) # Zero for right initial open and final close total_invested.iloc[0] = 0; total_invested.iloc[-1] = 0; total_invested.fillna(method='ffill', inplace=True) # Positions rounded to lot sizes x_positions = (total_invested*x_weights//self.lot1*self.lot1).fillna(0) y_positions = (total_invested*y_weights//self.lot2*self.lot2).fillna(0) long_pos = x_positions.copy(); long_pos[long_pos<0] = 0 short_pos = x_positions.copy(); short_pos[short_pos>0] = 0 x_pos_diff = x_positions.diff().fillna(0) y_pos_diff = y_positions.diff().fillna(0) # Tribute to the market-makers: spread # Binary divide because we count twice: enter & exit tribute = (abs(x_pos_diff)*self.spread1 + abs(y_pos_diff)*self.spread2)/2 # Cashflow & Turnover: not the same! cashflow = -x_pos_diff*x_prices - y_pos_diff*y_prices turnover = abs(x_pos_diff)*x_prices + abs(y_pos_diff)*y_prices # Commission from turnover commission = turnover * self.commission commission[cashflow!=0] += self.fixed_commission portfolio = pd.DataFrame(index=time_index, columns=['EQ','holdings', 'cash','cashflow','long_trades','short_trades', 'x_positions','y_positions']) # Value of shares portfolio['holdings'] = x_positions*x_prices + y_positions*y_prices # Value of cash, paid commission on each transaction portfolio['cash'] = self.initial_capital + (cashflow - commission - tribute).cumsum() # Equity is the sum of both portfolio['EQ'] = portfolio['cash'] + portfolio['holdings'] portfolio['turnover'] = turnover # Time points of trades portfolio['long_trades'] = long_pos.diff().fillna(0) portfolio['short_trades'] = short_pos.diff().fillna(0) portfolio['x_positions'] = x_positions portfolio['y_positions'] = y_positions return portfolio