Khi thực hiện một chiến lược giao dịch thuật toán, rất hấp dẫn khi xem xét lợi nhuận hàng năm là thước đo hiệu suất hữu ích nhất. Tuy nhiên, có nhiều nhược điểm khi sử dụng biện pháp này một cách cô lập. Việc tính toán lợi nhuận cho một số chiến lược không hoàn toàn đơn giản. Điều này đặc biệt đúng đối với các chiến lược không hướng như các biến thể trung lập với thị trường hoặc các chiến lược sử dụng đòn bẩy. Những yếu tố này làm cho khó so sánh hai chiến lược chỉ dựa trên lợi nhuận của chúng.
Ngoài ra, nếu chúng ta được trình bày với hai chiến lược có lợi nhuận giống hệt nhau, làm thế nào chúng ta biết được chiến lược nào có rủi ro nhiều hơn? Hơn nữa, chúng ta thậm chí có ý nghĩa gì với "rủi ro nhiều hơn"? Trong tài chính, chúng ta thường quan tâm đến biến động lợi nhuận và thời gian rút vốn. Do đó, nếu một trong những chiến lược này có biến động lợi nhuận cao hơn đáng kể, chúng ta có thể thấy nó ít hấp dẫn hơn, mặc dù thực tế là lợi nhuận lịch sử của nó có thể tương tự nếu không giống hệt nhau.
Những vấn đề so sánh chiến lược và đánh giá rủi ro này thúc đẩy việc sử dụng tỷ lệ Sharpe.
William Forsyth Sharpe là một nhà kinh tế đoạt giải Nobel, người đã giúp tạo ra Mô hình định giá tài sản vốn (CAPM) và phát triển Tỷ lệ Sharpe vào năm 1966 (sau đó được cập nhật vào năm 1994).
Tỷ lệ Sharpe S được xác định bởi mối quan hệ sau:Trong đó Ra là lợi nhuận giai đoạn của tài sản hoặc chiến lược và Rb là lợi nhuận giai đoạn của một chỉ số chuẩn phù hợp.
Tỷ lệ này so sánh trung bình của lợi nhuận vượt quá của tài sản hoặc chiến lược với độ lệch chuẩn của lợi nhuận đó.
Công thức cho tỷ lệ Sharpe ở trên ám chỉ đến việc sử dụng một chỉ số chuẩn. Một chỉ số chuẩn được sử dụng như một
Sự lựa chọn của chỉ số chuẩn đôi khi có thể không rõ ràng. Ví dụ, một quỹ giao dịch trao đổi (ETF) nên được sử dụng làm chỉ số chuẩn cho các cổ phiếu cá nhân, hoặc chính S & P500? Tại sao không phải là Russell 3000? Tương tự như vậy, một chiến lược quỹ phòng hộ nên được so sánh với chỉ số thị trường hoặc chỉ số của các quỹ phòng hộ khác? Ngoài ra còn có sự phức tạp của
Trong một trường hợp cụ thể, đối với các chiến lược trung lập thị trường, có một sự phức tạp đặc biệt về việc sử dụng tỷ lệ không rủi ro hoặc không như điểm chuẩn. Chỉ số thị trường không nên được sử dụng vì chiến lược, theo thiết kế, trung lập thị trường. Lựa chọn chính xác cho một danh mục đầu tư trung lập thị trường không phải là trừ tỷ lệ không rủi ro vì nó tự tài trợ. Vì bạn có được lợi ích tín dụng, Rf, từ việc nắm giữ biên, tính toán thực tế cho lợi nhuận là: (Ra + Rf) -Rf = Ra. Do đó, không có sự khấu trừ thực tế tỷ lệ đô la không rủi ro cho các chiến lược trung lập.
Mặc dù tỷ lệ Sharpe phổ biến trong tài chính định lượng, nó vẫn bị hạn chế.
Thứ nhất, tỷ lệ Sharpe là nhìn lại. Nó chỉ tính đến sự phân bố lợi nhuận lịch sử và biến động, không phải những gì xảy ra trong tương lai. Khi đưa ra phán đoán dựa trên tỷ lệ Sharpe, có một giả định ngụ ý rằng quá khứ sẽ tương tự như tương lai. Điều này rõ ràng không phải lúc nào cũng đúng, đặc biệt là dưới sự thay đổi chế độ thị trường.
Tính toán tỷ lệ Sharpe giả định rằng lợi nhuận được sử dụng được phân phối bình thường (tức là Gaussian). Thật không may, thị trường thường bị kurtosis cao hơn so với phân phối bình thường. Về cơ bản, sự phân phối lợi nhuận có
Điều này có thể được thấy rõ trong các chiến lược có xu hướng cao đối với những rủi ro như vậy. Ví dụ, việc bán các tùy chọn gọi (tên gọi là
Mặc dù điểm này có vẻ hiển nhiên với một số người, chi phí giao dịch phải được đưa vào tính toán tỷ lệ Sharpe để nó thực tế. Có vô số ví dụ về các chiến lược giao dịch có Sharpe cao (và do đó có khả năng lợi nhuận cao) chỉ được giảm xuống thành các chiến lược Sharpe thấp, lợi nhuận thấp một khi chi phí thực tế đã được tính vào. Điều này có nghĩa là sử dụng lợi nhuận ròng khi tính toán vượt quá chỉ số chuẩn. Do đó, chi phí giao dịch phải được tính vào tính toán tỷ lệ Sharpe.
Một câu hỏi rõ ràng mà vẫn chưa được trả lời cho đến nay trong bài viết này là
Tỷ lệ Sharpe thường tăng theo tần suất giao dịch. Một số chiến lược tần suất cao sẽ có tỷ lệ Sharpe đơn chữ số cao (và đôi khi thấp gấp đôi), vì chúng có thể có lợi nhuận gần như mỗi ngày và chắc chắn mỗi tháng.
Đây là một bài viết khá lý thuyết cho đến thời điểm này. Bây giờ chúng ta sẽ chuyển sự chú ý của chúng ta đến một số ví dụ thực tế. Chúng ta sẽ bắt đầu đơn giản, bằng cách xem xét một mua và giữ một cổ phiếu cá nhân chỉ trong thời gian dài sau đó xem xét một chiến lược trung lập với thị trường. Cả hai ví dụ này đã được thực hiện trong thư viện phân tích dữ liệu Python panda.
Nhiệm vụ đầu tiên là thực sự lấy dữ liệu và đưa nó vào một đối tượng Panda DataFrame. Trong bài viết về việc thực hiện chứng khoán chính trong Python và MySQL, tôi đã tạo ra một hệ thống để đạt được điều này. Ngoài ra, chúng ta có thể sử dụng mã đơn giản này để lấy dữ liệu Yahoo Finance trực tiếp và đưa nó trực tiếp vào một Panda DataFrame. Ở cuối kịch bản này, tôi đã tạo ra một hàm để tính tỷ lệ Sharpe hàng năm dựa trên một luồng thời gian trả về:
import datetime
import numpy as np
import pandas as pd
import urllib2
def get_historic_data(ticker,
start_date=(2000,1,1),
end_date=datetime.date.today().timetuple()[0:3]):
"""
Obtains data from Yahoo Finance and adds it to a pandas DataFrame object.
ticker: Yahoo Finance ticker symbol, e.g. "GOOG" for Google, Inc.
start_date: Start date in (YYYY, M, D) format
end_date: End date in (YYYY, M, D) format
"""
# Construct the Yahoo URL with the correct integer query parameters
# for start and end dates. Note that some parameters are zero-based!
yahoo_url = "http://ichart.finance.yahoo.com/table.csv?s=%s&a=%s&b=%s&c=%s&d=%s&e=%s&f=%s" % \
(ticker, start_date[1] - 1, start_date[2], start_date[0], end_date[1] - 1, end_date[2], end_date[0])
# Try connecting to Yahoo Finance and obtaining the data
# On failure, print an error message
try:
yf_data = urllib2.urlopen(yahoo_url).readlines()
except Exception, e:
print "Could not download Yahoo data: %s" % e
# Create the (temporary) Python data structures to store
# the historical data
date_list = []
hist_data = [[] for i in range(6)]
# Format and copy the raw text data into datetime objects
# and floating point values (still in native Python lists)
for day in yf_data[1:]: # Avoid the header line in the CSV
headers = day.rstrip().split(',')
date_list.append(datetime.datetime.strptime(headers[0],'%Y-%m-%d'))
for i, header in enumerate(headers[1:]):
hist_data[i].append(float(header))
# Create a Python dictionary of the lists and then use that to
# form a sorted Pandas DataFrame of the historical data
hist_data = dict(zip(['open', 'high', 'low', 'close', 'volume', 'adj_close'], hist_data))
pdf = pd.DataFrame(hist_data, index=pd.Index(date_list)).sort()
return pdf
def annualised_sharpe(returns, N=252):
"""
Calculate the annualised Sharpe ratio of a returns stream
based on a number of trading periods, N. N defaults to 252,
which then assumes a stream of daily returns.
The function assumes that the returns are the excess of
those compared to a benchmark.
"""
return np.sqrt(N) * returns.mean() / returns.std()
Bây giờ chúng ta có khả năng lấy dữ liệu từ Yahoo Finance và đơn giản tính tỷ lệ Sharpe hàng năm, chúng ta có thể thử một chiến lược mua và giữ cho hai cổ phiếu. Chúng ta sẽ sử dụng Google (GOOG) và Goldman Sachs (GS) từ ngày 1 tháng 1 năm 2000 đến ngày 29 tháng 5 năm 2013 (khi tôi viết bài viết này!).
Chúng ta có thể tạo một chức năng trợ giúp bổ sung cho phép chúng ta nhanh chóng xem mua và giữ Sharpe trên nhiều cổ phiếu cho cùng một giai đoạn (được mã hóa):
def equity_sharpe(ticker):
"""
Calculates the annualised Sharpe ratio based on the daily
returns of an equity ticker symbol listed in Yahoo Finance.
The dates have been hardcoded here for the QuantStart article
on Sharpe ratios.
"""
# Obtain the equities daily historic data for the desired time period
# and add to a pandas DataFrame
pdf = get_historic_data(ticker, start_date=(2000,1,1), end_date=(2013,5,29))
# Use the percentage change method to easily calculate daily returns
pdf['daily_ret'] = pdf['adj_close'].pct_change()
# Assume an average annual risk-free rate over the period of 5%
pdf['excess_daily_ret'] = pdf['daily_ret'] - 0.05/252
# Return the annualised Sharpe ratio based on the excess daily returns
return annualised_sharpe(pdf['excess_daily_ret'])
Đối với Google, tỷ lệ Sharpe cho mua và giữ là 0,7501.
equity_sharpe ((
equity_sharpe ((
Bây giờ chúng ta có thể thử cùng một tính toán cho một chiến lược trung lập thị trường. Mục tiêu của chiến lược này là để cô lập hoàn toàn hiệu suất của một cổ phiếu cụ thể từ thị trường nói chung. Cách đơn giản nhất để đạt được điều này là đi ngắn một số tiền bằng nhau (trong đô la) của một Quỹ giao dịch trao đổi (ETF) được thiết kế để theo dõi một thị trường như vậy. Lựa chọn rõ ràng nhất cho thị trường chứng khoán vốn hóa lớn của Hoa Kỳ là chỉ số S & P500, được theo dõi bởi SPDR ETF, với dấu hiệu SPY.
Để tính tỷ lệ Sharpe hàng năm của một chiến lược như vậy, chúng ta sẽ lấy giá lịch sử cho SPY và tính tỷ lệ phần trăm lợi nhuận theo cách tương tự như các cổ phiếu trước đó, ngoại trừ việc chúng ta sẽ không sử dụng chỉ số chuẩn không rủi ro. Chúng ta sẽ tính lợi nhuận hàng ngày ròng đòi hỏi phải trừ đi sự khác biệt giữa lợi nhuận dài và ngắn và sau đó chia cho 2, vì bây giờ chúng ta có gấp đôi vốn giao dịch. Đây là mã Python / panda để thực hiện điều này:
def market_neutral_sharpe(ticker, benchmark):
"""
Calculates the annualised Sharpe ratio of a market
neutral long/short strategy inolving the long of 'ticker'
with a corresponding short of the 'benchmark'.
"""
# Get historic data for both a symbol/ticker and a benchmark ticker
# The dates have been hardcoded, but you can modify them as you see fit!
tick = get_historic_data(ticker, start_date=(2000,1,1), end_date=(2013,5,29))
bench = get_historic_data(benchmark, start_date=(2000,1,1), end_date=(2013,5,29))
# Calculate the percentage returns on each of the time series
tick['daily_ret'] = tick['adj_close'].pct_change()
bench['daily_ret'] = bench['adj_close'].pct_change()
# Create a new DataFrame to store the strategy information
# The net returns are (long - short)/2, since there is twice
# trading capital for this strategy
strat = pd.DataFrame(index=tick.index)
strat['net_ret'] = (tick['daily_ret'] - bench['daily_ret'])/2.0
# Return the annualised Sharpe ratio for this strategy
return annualised_sharpe(strat['net_ret'])
Đối với Google, tỷ lệ Sharpe cho chiến lược trung lập thị trường dài / ngắn là 0,7597.
thị trường_neutral_sharpe ((
thị trường_trung_thực ((