评估数据源是否回溯_IAI Trade:蒙特卡洛模拟在回溯检验中的应用
IAI Trade致力于降低量化交易門檻,在IAI Trade用戶可以使用“可視化策略生成器”0代碼生成EA策略,并一鍵接通模擬交易及真實交易。
蒙特卡洛模擬和回溯檢驗
考慮一個隨機過程,它會產生不同的結果,研究員想知道不同結果發生的可能性,以幫助解決實際問題,蒙特卡洛模擬就是常用的概率分析方法。
在開發策略的過程中,通過優化參數得到“最優”模型是否意味著回溯檢驗的結束?答案毫無疑問是否定的,這僅僅是第一階段的結束,接下來需要對交易記錄和凈值曲線進行深度分析,主要目的是評估模型的預測能力,我們必須回答一個問題:回溯檢驗的優秀表現能否在交易中重現?
蒙特卡洛模擬可以評估策略運行面臨的潛在風險,不管如何小心謹慎地優化參數,都不可避免地挖掘了樣本數據,一旦部署策略,真實回撤可能顯著大于回溯檢驗的結果,如何能夠判斷潛在回撤的概率分布?蒙特卡洛模擬解決了這個問題。首先我們要準備交易紀錄,即每一筆交易的pnl,然后進行重復抽樣,既可以有放回抽樣,也可以是不放回抽樣,然后計算每一條模擬的凈值曲線的樣本統計量,如最大回撤和年化收益率,根據中心極限定理,年化收益率的抽樣分布漸進服從正態分布。最后進行概率推斷,如計算抽樣分布的置信區間,這些信息有助于判斷策略運行的潛在風險。
案例分析
library(tidyverse)
library(quantmod)
library(PerformanceAnalytics)
library(Quandl)
從Quandl下載標普500指數期貨的歷史價格,計算日收益率。假設使用買入并持有策略。這里把日收益率作為日pnl。
stock <- Quandl("CHRIS/CME_ES1/6", type = "xts", collapse = "daily")
rets <- stock/lag.xts(stock) - 1
colnames(rets) <- "returns"
head(rets)
## returns
## 1997-09-09 NA
## 1997-09-10 -0.020342612
## 1997-09-11 -0.007650273
## 1997-09-12 0.017621145
## 1997-09-15 -0.002164502
## 1997-09-16 0.027114967
筆者創建了一個自定義函數:monte_carlo_simulation,接受3個參數:
- pnl: 要求是xts對象,代表pnl,很容易擴展到普通的數值向量,之所以使用xts,是因為筆者想使用PerformanceAnalytics包計算常用業績指標
- n:正整數,模擬次數,默認值為100
- replace: 布爾值,TRUE代表有放回抽樣,FALSE代表不放回抽樣,不放回抽樣會導致相同的收益率,因為只是對交易順序重新排列,只有最大回撤是不同的,有放回抽樣是一種更加嚴格的檢驗,因為只抽取了部分交易,收益率和最大回撤都不同。
monte_carlo_simulation計算了5個常用的業績指標:累積收益率,年化收益率,年化標準差,年化夏普比率和最大回撤。返回結果是一個列表,方便后續計算。
monte_carlo_simulation <- function(pnl, n = 100, replace = FALSE) {
# pnl: xts, trading results
# n: positive integer, number of simulations
# replace: logical, sampling with replacement or without replacement
if(!is.xts(pnl)) {
stop("pnl must be xts object")
}
ex_na <- na.omit(pnl)
dt <- index(ex_na)
x <- coredata(ex_na)
size <- length(x)
if(factorial(size) < n) {
stop("n exceeds limit of possible sampling size")
}
m <- replicate(n = n, sample(x, replace = replace))
m_ts <- xts(m, order.by = dt)
equity_curve <- xts(apply(m, 2, function(x) cumprod(1 + x) - 1), order.by = dt)
cum_rets <- Return.cumulative(m_ts)[1, ] # result is matrix, need to convert it to numeric vector
ann_rets <- Return.annualized(m_ts, scale = 252)[1, ] # change frequency if needed
ann_stds <- StdDev.annualized(m_ts, scale = 252)[1, ]
ann_sharpe <- SharpeRatio.annualized(m_ts, scale = 252)[1, ]
mdd <- maxDrawdown(m_ts)[1, ]
out <- list(equity_curve = equity_curve, cum_rets = cum_rets,
ann_rets = ann_rets, ann_stds = ann_stds,
ann_sharpe = ann_sharpe, mdd = mdd)
return(out)
}
sim_results <- monte_carlo_simulation(pnl = rets, n = 500, replace = TRUE)
## Warning in factorial(size): 'gammafn'里的值在范圍外
這里進行了500次不放回抽樣,出于示范目的,500次已經足夠,在計算能力充足的情況下可以進行500-10000次模擬。部分研究員指出,1000次模擬的結果已經非常逼近正態分布。讓我們繪制500條模擬的凈值曲線的波動軌跡。
plot(sim_results$equity_curve, main = "Simulations of Equity Curve")
接下來看業績指標的抽樣分布,首先看年化收益率。
ar <- sim_results$ann_rets
ggplot(NULL, aes(x = ar, y = ..density..)) +
geom_histogram(bins = 30) +
geom_line(aes(x = ar, y = dnorm(ar, mean = mean(ar), sd = sd(ar))), col = "red",
size = 1.0) +
labs(title = "Sampling Distribution of Annualized Returns",
x = "annualized returns", y = "density") +
theme_bw()
年化標準差。
as <- sim_results$ann_stds
ggplot(NULL, aes(x = as, y = ..density..)) +
geom_histogram(bins = 30) +
geom_line(aes(x = as, y = dnorm(as, mean = mean(as), sd = sd(as))), col = "red",
size = 1.0) +
labs(title = "Sampling Distribution of Annualized Standard Deviations",
x = "annualized stdev", y = "density") +
theme_bw()
年化夏普比率。
sr <- sim_results$ann_sharpe
ggplot(NULL, aes(x = sr, y = ..density..)) +
geom_histogram(bins = 30) +
geom_line(aes(x = sr, y = dnorm(sr, mean = mean(sr), sd = sd(sr))), col = "red",
size = 1.0) +
labs(title = "Sampling Distribution of Annualized Sharpe Ratio",
x = "annualized sharpe ratio", y = "density") +
theme_bw()
最大回撤。
mdd <- sim_results$mdd
ggplot(NULL, aes(x = mdd, y = ..density..)) +
geom_histogram(bins = 30) +
geom_line(aes(x = mdd, y = dnorm(mdd, mean = mean(mdd), sd = sd(mdd))), col = "red",
size = 1.0) +
labs(title = "Sampling Distribution of Maximum Drawdown",
x = "max drawdown", y = "density") +
theme_bw()
除了最大回撤外,年化收益率,年化標準差和年化夏普比率都非常接近正態分布。最大回撤呈現溫和右偏分布,有極大值的存在。
接下來計算樣本統計量的置信區間。
sim_results[[1]] <- NULL
ci <- sapply(sim_results, function(x) quantile(x, probs = c(0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 1.0)))
stats <- data.frame(cum_rets = Return.cumulative(rets)[1, ],
ann_rets = Return.annualized(rets, 252)[1, ],
ann_stds = StdDev.annualized(rets, 252)[1, ],
ann_sharpe = SharpeRatio.annualized(rets, scale = 252)[1, ],
mdd = maxDrawdown(rets))
rownames(stats) <- "backtest"
rbind(stats, ci)
## cum_rets ann_rets ann_stds ann_sharpe mdd
## backtest 1.941649 0.05332191 0.1959935 0.2720595 0.5711340
## 50% 1.982086 0.05401410 0.1958034 0.2768144 0.5077284
## 60% 2.674193 0.06465941 0.1972487 0.3253984 0.5367205
## 70% 3.768695 0.07810906 0.1986608 0.3964761 0.5748254
## 80% 5.176337 0.09161906 0.2000416 0.4645394 0.6277824
## 90% 7.060499 0.10569998 0.2025783 0.5500235 0.6940598
## 95% 9.670987 0.12073953 0.2042243 0.6174111 0.7312092
## 99% 21.347121 0.16134220 0.2071967 0.8207452 0.8178700
## 100% 45.884982 0.20352417 0.2098272 1.0446744 0.8918892
結果顯示,有95%的可能性年化收益率會小于等于13.1%,有95%的可能性最大回撤會小于等于71.6%,顯著高于回溯結果的57%。蒙特卡洛模擬更多用于評估潛在風險,所以我們應該更多地關注最大回撤和類似的風險度量指標,一般情況下,最大回撤的95%置信上限不應該超過原始策略的2倍,否則認為策略無法通過檢驗,當然這僅僅是經驗之談,并不是客觀準則。
總結
以上是生活随笔為你收集整理的评估数据源是否回溯_IAI Trade:蒙特卡洛模拟在回溯检验中的应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汇顶科技生产什么产品 别只知道指纹识别
- 下一篇: 自动续保钱怎么追回