Hợp đồng tương lai là một hình thức hợp đồng được soạn thảo giữa hai bên để mua hoặc bán một lượng tài sản cơ bản vào một ngày cụ thể trong tương lai. Ngày này được gọi là giao hàng hoặc hết hạn. Khi ngày này đạt đến, người mua phải giao chứng khoán cơ bản (hoặc tương đương tiền mặt) cho người bán với giá đã thỏa thuận vào ngày thành lập hợp đồng.
Trong thực tế, hợp đồng tương lai được giao dịch trên sàn giao dịch ( trái ngược với giao dịch OTC) cho số lượng và chất lượng tiêu chuẩn của chứng khoán cơ bản. Giá được đánh dấu thị trường mỗi ngày. Hợp đồng tương lai rất thanh khoản và được sử dụng nhiều cho mục đích đầu cơ.
Một danh sách chi tiết về tất cả các mã biểu tượng được sử dụng cho các hợp đồng tương lai trên các sàn giao dịch khác nhau có thể được tìm thấy trên trang web CSI Data: Futures Factsheet.
Sự khác biệt chính giữa hợp đồng tương lai và quyền sở hữu cổ phiếu là một hợp đồng tương lai có cửa sổ hạn chế về khả năng sử dụng do ngày hết hạn. Tại bất kỳ thời điểm nào sẽ có nhiều hợp đồng tương lai khác nhau trên cùng một cơ sở với ngày hết hạn khác nhau. Hợp đồng có ngày hết hạn gần nhất được gọi là hợp đồng gần. Vấn đề mà chúng ta phải đối mặt với các nhà giao dịch định lượng là tại bất kỳ thời điểm nào chúng ta có thể lựa chọn nhiều hợp đồng để giao dịch. Do đó chúng ta đang đối phó với một tập hợp các chuỗi thời gian chồng chéo hơn là một luồng liên tục như trong trường hợp cổ phiếu hoặc ngoại hối.
Mục tiêu của bài viết này là phác thảo các cách tiếp cận khác nhau để xây dựng một luồng hợp đồng liên tục từ tập hợp nhiều chuỗi này và làm nổi bật các sự đánh đổi liên quan đến mỗi kỹ thuật.
Khó khăn chính trong việc cố gắng tạo ra một hợp đồng liên tục từ các hợp đồng cơ bản với các giao hàng khác nhau là các hợp đồng thường không giao dịch ở cùng một mức giá. Do đó, các tình huống phát sinh khi chúng không cung cấp một sự ghép nối trơn tru từ một đến khác. Điều này là do các hiệu ứng contango và backwardation. Có nhiều cách tiếp cận để giải quyết vấn đề này, mà bây giờ chúng tôi thảo luận.
Thật không may, không có phương pháp
Phương pháp này làm giảm khoảng cách giữa nhiều hợp đồng bằng cách di chuyển mỗi hợp đồng để các giao hàng riêng lẻ kết hợp một cách trơn tru với các hợp đồng lân cận.
Vấn đề chính với phương pháp Panama bao gồm việc giới thiệu một xu hướng thiên vị, sẽ giới thiệu một sự trôi dạt lớn vào giá cả. Điều này có thể dẫn đến dữ liệu tiêu cực cho các hợp đồng đủ lịch sử. Ngoài ra có sự mất mát của sự khác biệt giá tương đối do sự thay đổi tuyệt đối trong giá trị. Điều này có nghĩa là lợi nhuận rất phức tạp để tính toán (hoặc chỉ đơn giản là không chính xác).
Phương pháp điều chỉnh tỷ lệ tương tự như phương pháp điều chỉnh xử lý chia cổ phiếu trong cổ phiếu. Thay vì thực hiện một sự thay đổi tuyệt đối trong các hợp đồng liên tiếp, tỷ lệ giá thanh toán cũ hơn (kết thúc) với giá mở mới hơn được sử dụng để điều chỉnh tỷ lệ các giá của các hợp đồng lịch sử. Điều này cho phép một luồng liên tục mà không bị gián đoạn trong việc tính toán lợi nhuận tỷ lệ phần trăm.
Vấn đề chính với điều chỉnh tỷ lệ là bất kỳ chiến lược giao dịch nào dựa trên mức giá tuyệt đối cũng sẽ phải được điều chỉnh tương tự để thực hiện tín hiệu chính xác. Đây là một quá trình có vấn đề và dễ bị lỗi. Do đó, loại luồng liên tục này thường chỉ hữu ích cho phân tích thống kê tóm tắt, trái ngược với nghiên cứu kiểm tra ngược trực tiếp.
Bản chất của cách tiếp cận này là tạo ra một hợp đồng liên tục của các hợp đồng liên tiếp bằng cách lấy một tỷ lệ cân nhắc tuyến tính của mỗi hợp đồng trong một số ngày để đảm bảo chuyển đổi mượt mà hơn giữa mỗi hợp đồng.
Ví dụ: xem xét năm ngày làm mịn. Giá vào ngày 1, P1, bằng 80% giá hợp đồng xa (F1) và 20% giá hợp đồng gần (N1). Tương tự, vào ngày 2, giá là P2=0.6×F2+0.4×N2. Vào ngày 5, chúng ta có P5=0.0×F5+1.0×N5=N5 và hợp đồng sau đó chỉ trở thành sự tiếp tục của giá gần. Do đó, sau năm ngày, hợp đồng chuyển từ xa sang gần một cách mịn màng.
Vấn đề với phương pháp rollover là nó đòi hỏi giao dịch trong năm ngày, có thể làm tăng chi phí giao dịch.
Có những cách tiếp cận khác ít phổ biến hơn cho vấn đề nhưng chúng ta sẽ tránh chúng ở đây.
Phần còn lại của bài viết sẽ tập trung vào việc thực hiện phương pháp chuỗi vĩnh cửu vì đây là cách thích hợp nhất cho backtesting.
Chúng tôi sẽ kết hợp hợp đồng tương lai dầu thô WTI
Để thực hiện tải xuống dữ liệu tương lai, tôi đã sử dụng plugin Quandl. Hãy chắc chắn cài đặt môi trường ảo Python chính xác trên hệ thống của bạn và cài đặt gói Quandl bằng cách gõ những điều sau đây vào thiết bị đầu cuối:
import datetime
import numpy as np
import pandas as pd
import Quandl
Công việc chính được thực hiện trong hàm futures_rollover_weights. Nó đòi hỏi một ngày bắt đầu (ngày đầu tiên của hợp đồng gần), một từ điển các ngày thanh toán hợp đồng (ngày hết hạn), các biểu tượng của các hợp đồng và số ngày để lật hợp đồng (bên mặc định là năm).
def futures_rollover_weights(start_date, expiry_dates, contracts, rollover_days=5):
"""This constructs a pandas DataFrame that contains weights (between 0.0 and 1.0)
of contract positions to hold in order to carry out a rollover of rollover_days
prior to the expiration of the earliest contract. The matrix can then be
'multiplied' with another DataFrame containing the settle prices of each
contract in order to produce a continuous time series futures contract."""
# Construct a sequence of dates beginning from the earliest contract start
# date to the end date of the final contract
dates = pd.date_range(start_date, expiry_dates[-1], freq='B')
# Create the 'roll weights' DataFrame that will store the multipliers for
# each contract (between 0.0 and 1.0)
roll_weights = pd.DataFrame(np.zeros((len(dates), len(contracts))),
index=dates, columns=contracts)
prev_date = roll_weights.index[0]
# Loop through each contract and create the specific weightings for
# each contract depending upon the settlement date and rollover_days
for i, (item, ex_date) in enumerate(expiry_dates.iteritems()):
if i < len(expiry_dates) - 1:
roll_weights.ix[prev_date:ex_date - pd.offsets.BDay(), item] = 1
roll_rng = pd.date_range(end=ex_date - pd.offsets.BDay(),
periods=rollover_days + 1, freq='B')
# Create a sequence of roll weights (i.e. [0.0,0.2,...,0.8,1.0]
# and use these to adjust the weightings of each future
decay_weights = np.linspace(0, 1, rollover_days + 1)
roll_weights.ix[roll_rng, item] = 1 - decay_weights
roll_weights.ix[roll_rng, expiry_dates.index[i+1]] = decay_weights
else:
roll_weights.ix[prev_date:, item] = 1
prev_date = ex_date
return roll_weights
Bây giờ mà ma trận cân nhắc đã được tạo ra, có thể áp dụng điều này cho các chuỗi thời gian riêng lẻ. chức năng chính tải xuống các hợp đồng gần và xa, tạo ra một DataFrame duy nhất cho cả hai, xây dựng ma trận cân nhắc lật và sau đó cuối cùng tạo ra một chuỗi liên tục của cả hai giá, cân nhắc thích hợp:
if __name__ == "__main__":
# Download the current Front and Back (near and far) futures contracts
# for WTI Crude, traded on NYMEX, from Quandl.com. You will need to
# adjust the contracts to reflect your current near/far contracts
# depending upon the point at which you read this!
wti_near = Quandl.get("OFDP/FUTURE_CLF2014")
wti_far = Quandl.get("OFDP/FUTURE_CLG2014")
wti = pd.DataFrame({'CLF2014': wti_near['Settle'],
'CLG2014': wti_far['Settle']}, index=wti_far.index)
# Create the dictionary of expiry dates for each contract
expiry_dates = pd.Series({'CLF2014': datetime.datetime(2013, 12, 19),
'CLG2014': datetime.datetime(2014, 2, 21)}).order()
# Obtain the rollover weighting matrix/DataFrame
weights = futures_rollover_weights(wti_near.index[0], expiry_dates, wti.columns)
# Construct the continuous future of the WTI CL contracts
wti_cts = (wti * weights).sum(1).dropna()
# Output the merged series of contract settle prices
wti_cts.tail(60)
Kết quả là như sau:
2013-10-14 102.230 2013-10-15 101.240 2013-10-16 102.330 2013-10-17 100.620 2013-10-18 100.990 2013-10-21 99.760 2013-10-22 98.470 2013-10-23 97.000 2013-10-24 97.240 2013-10-25 97.950 ... ... 2013-12-24 99.220 2013-12-26 99.550 2013-12-27 100.320 2013-12-30 99.290 2013-12-31 98.420 2014-01-02 95.440 2014-01-03 93.960 2014-01-06 93.430 2014-01-07 93.670 2014-01-08 92.330 Chiều dài: 60, dtype: float64
Bạn có thể thấy rằng chuỗi này hiện là liên tục trên cả hai hợp đồng.