Performance Analysis with tidyquant

Performance Analysis with tidyquant

tidyquant 的最后一个小品文了!感觉 tidyquant 对于中国用户并不友好,我在考虑是否可以通过对 cran/Tushare进行修改使其能够纳入 tidyquant 分析框架中。

获取三只股票的数据

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
library(tidyquant)
(ra <- c("000001.SZ", "000002.SZ", "000004.SZ") %>%
tq_get(get = "stock.prices",
from = "2010-01-01",
to = "2015-12-31") %>%
group_by(symbol) %>%
tq_transmute(
select = adjusted,
mutate_fun = periodReturn,
period = "monthly",
col_rename = "ra"
))
#> # A tibble: 215 x 3
#> # Groups: symbol [3]
#> symbol date ra
#> <chr> <date> <dbl>
#> 1 000001.SZ 2010-01-29 -0.0848
#> 2 000001.SZ 2010-02-26 0.0346
#> 3 000001.SZ 2010-03-31 0.0334
#> 4 000001.SZ 2010-04-30 -0.114
#> 5 000001.SZ 2010-05-31 -0.148
#> 6 000001.SZ 2010-06-30 0
#> 7 000001.SZ 2010-07-30 0
#> 8 000001.SZ 2010-08-31 0
#> 9 000001.SZ 2010-09-30 -0.0737
#> 10 000001.SZ 2010-10-29 0.135
#> # … with 205 more rows

使用深证 100R 指数作为基准

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
library(Tushare)
api = pro_api('fd65bf1ee56215d0ce1a95d1fa3b453d97a1779438aca26c4b7937d1')
(rb <- api(api_name = "index_daily",
ts_code = "399004.SZ",
start_date = "20100101",
end_date = "20151231") %>%
as_tibble() %>%
transmute(
date = ymd(trade_date),
symbol = as.character(ts_code),
close = as.numeric(close)
) %>%
tq_transmute(
select = close,
mutate_fun = periodReturn,
period = "monthly",
col_rename = "rb"
))
#> # A tibble: 72 x 2
#> date rb
#> <date> <dbl>
#> 1 2010-01-29 -0.205
#> 2 2010-02-26 0.0849
#> 3 2010-03-31 0.0179
#> 4 2010-04-30 -0.199
#> 5 2010-05-31 -0.106
#> 6 2010-06-30 -0.325
#> 7 2010-07-30 0.600
#> 8 2010-08-31 0.0671
#> 9 2010-09-30 0.0516
#> 10 2010-10-29 0.381
#> # … with 62 more rows

合并两个数据集

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(rarb <- left_join(ra, rb, by = "date"))
#> # A tibble: 215 x 4
#> # Groups: symbol [3]
#> symbol date ra rb
#> <chr> <date> <dbl> <dbl>
#> 1 000001.SZ 2010-01-29 -0.0848 -0.205
#> 2 000001.SZ 2010-02-26 0.0346 0.0849
#> 3 000001.SZ 2010-03-31 0.0334 0.0179
#> 4 000001.SZ 2010-04-30 -0.114 -0.199
#> 5 000001.SZ 2010-05-31 -0.148 -0.106
#> 6 000001.SZ 2010-06-30 0 -0.325
#> 7 000001.SZ 2010-07-30 0 0.600
#> 8 000001.SZ 2010-08-31 0 0.0671
#> 9 000001.SZ 2010-09-30 -0.0737 0.0516
#> 10 000001.SZ 2010-10-29 0.135 0.381
#> # … with 205 more rows

使用 tq_performance 运行 CAPM 模型

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
(rarb_capm <- rarb %>%
tq_performance(
Ra = ra,
Rb = rb,
performance_fun = table.CAPM
))
#> # A tibble: 3 x 13
#> # Groups: symbol [3]
#> symbol ActivePremium Alpha AnnualizedAlpha Beta `Beta-` `Beta+` Correlation `Correlationp-v… InformationRatio `R-squared`
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 00000… 0.0201 0.0041 0.0501 0.0039 0.0566 0.0031 0.306 0.009 0.0007 0.0934
#> 2 00000… 0.138 0.0167 0.220 0.00240 -0.0689 0.0014 0.159 0.184 0.005 0.0254
#> 3 00000… 0.248 0.0287 0.404 0.0018 0.114 0.0005 0.114 0.346 0.0089 0.0129
#> # … with 2 more variables: TrackingError <dbl>, TreynorRatio <dbl>

我们比较关心增长测度和风险测度:

R
1
2
3
4
5
6
7
8
9
10
rarb_capm %>%
dplyr::select(Alpha, Beta)

#> # A tibble: 3 x 3
#> # Groups: symbol [3]
#> symbol Alpha Beta
#> <chr> <dbl> <dbl>
#> 1 000001.SZ 0.0041 0.0039
#> 2 000002.SZ 0.0167 0.00240
#> 3 000004.SZ 0.0287 0.0018

tidyquant 的工作流程

单独资产分析

R
1
2
3
4
5
# 查看 SharpeRatio 函数的参数:
args(SharpeRatio)
#> function (R, Rf = 0, p = 0.95, FUN = c("StdDev", "VaR", "ES"),
#> weights = NULL, annualize = FALSE, ...)
#> NULL

Step 1: 获取股票数据

R
1
2
3
4
5
6
(stock_prices <- c("000001.SZ", "000002.SZ", "000004.SZ") %>%
tq_get(
get = "stock.prices",
from = "2010-01-01",
to = "2015-12-31"
))

Step2: 计算收益率

R
1
2
3
4
5
6
7
8
(stock_returns_monthly <- stock_prices %>%
group_by(symbol) %>%
tq_transmute(
select = adjusted,
mutate_fun = periodReturn,
period = "monthly",
col_rename = "ra"
))

Step3: 绩效分析

R
1
2
3
4
5
6
7
8
9
10
11
stock_returns_monthly %>%
tq_performance(Ra = ra,
Rb = NULL,
performance_fun = SharpeRatio)
#> # A tibble: 3 x 4
#> # Groups: symbol [3]
#> symbol `ESSharpe(Rf=0%,p=95%)` `StdDevSharpe(Rf=0%,p=95%)` `VaRSharpe(Rf=0%,p=95%)`
#> <chr> <dbl> <dbl> <dbl>
#> 1 000001.SZ 0.0495 0.0780 0.0605
#> 2 000002.SZ 0.0754 0.167 0.240
#> 3 000004.SZ 0.125 0.238 0.167

修改无风险利率和置信水平:

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
stock_returns_monthly %>%
tq_performance(
Ra = ra,
Rb = NULL,
performance_fun = SharpeRatio,
Rf = 0.03 / 12,
p = 0.99
)
#> # A tibble: 3 x 4
#> # Groups: symbol [3]
#> symbol `ESSharpe(Rf=0.2%,p=99%)` `StdDevSharpe(Rf=0.2%,p=99%)` `VaRSharpe(Rf=0.2%,p=99%)`
#> <chr> <dbl> <dbl> <dbl>
#> 1 000001.SZ 0.0332 0.0538 0.0332
#> 2 000002.SZ 0.132 0.145 0.132
#> 3 000004.SZ 0.0839 0.219 0.0999

资产组合的分析

组合资产

方法 1: 使用权重向量

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
wts <- c(0.5, 0, 0.5)
(portfolio_returns_monthly <- stock_returns_monthly %>%
tq_portfolio(
assets_col = symbol,
returns_col = ra,
weights = wts,
col_rename = "ra"
))

#> # A tibble: 73 x 2
#> date ra
#> <date> <dbl>
#> 1 2010-01-29 -0.0424
#> 2 2010-02-26 0.0638
#> 3 2010-03-31 0.0682
#> 4 2010-04-30 -0.100
#> 5 2010-05-31 -0.139
#> 6 2010-06-30 -0.0356
#> 7 2010-07-30 0.0777
#> 8 2010-08-31 0.101
#> 9 2010-09-30 -0.0238
#> 10 2010-10-29 0.0837
#> # … with 63 more rows

方法 2: 使用资产 + 权重 数据框

R
1
2
3
4
5
6
7
8
9
10
(wts_map <- tibble(
symbols = c('000001.SZ', '000004.SZ'),
weights = c(0.5, 0.5)
))

#> # A tibble: 2 x 2
#> symbols weights
#> <chr> <dbl>
#> 1 000001.SZ 0.5
#> 2 000004.SZ 0.5
R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
stock_returns_monthly %>%
tq_portfolio(
assets_col = symbol,
returns_col = ra,
weights = wts_map,
col_rename = "ra_using_wts_map"
)

#> # A tibble: 73 x 2
#> date ra_using_wts_map
#> <date> <dbl>
#> 1 2010-01-29 -0.0424
#> 2 2010-02-26 0.0638
#> 3 2010-03-31 0.0682
#> 4 2010-04-30 -0.100
#> 5 2010-05-31 -0.139
#> 6 2010-06-30 -0.0356
#> 7 2010-07-30 0.0777
#> 8 2010-08-31 0.101
#> 9 2010-09-30 -0.0238
#> 10 2010-10-29 0.0837
#> # … with 63 more rows

合并 ra 和 rb

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(rarb_single_portfolio <- left_join(
portfolio_returns_monthly,
rb,
by = "date")
)
#> # A tibble: 73 x 3
#> date ra rb
#> <date> <dbl> <dbl>
#> 1 2010-01-29 -0.0424 -0.205
#> 2 2010-02-26 0.0638 0.0849
#> 3 2010-03-31 0.0682 0.0179
#> 4 2010-04-30 -0.100 -0.199
#> 5 2010-05-31 -0.139 -0.106
#> 6 2010-06-30 -0.0356 -0.325
#> 7 2010-07-30 0.0777 0.600
#> 8 2010-08-31 0.101 0.0671
#> 9 2010-09-30 -0.0238 0.0516
#> 10 2010-10-29 0.0837 0.381
#> # … with 63 more rows

计算 CAPM 模型

R
1
2
3
4
5
6
7
8
9
10
11
rarb_single_portfolio %>%
tq_performance(
Ra = ra,
Rb = rb,
performance_fun = table.CAPM
)
# # A tibble: 1 x 12
# ActivePremium Alpha AnnualizedAlpha Beta `Beta-` `Beta+` Correlation `Correlationp-v… InformationRatio `R-squared` TrackingError
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 0.186 0.0176 0.233 0.0027 0.0935 0.0016 0.219 0.0644 0.0068 0.048 27.4
# # … with 1 more variable: TreynorRatio <dbl>

多个资产组合

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
(stock_returns_monthly_multi <- stock_returns_monthly %>%
tq_repeat_df(n = 3))

#> # A tibble: 645 x 4
#> # Groups: portfolio [3]
#> portfolio symbol date ra
#> <int> <chr> <date> <dbl>
#> 1 1 000001.SZ 2010-01-29 -0.0848
#> 2 1 000001.SZ 2010-02-26 0.0346
#> 3 1 000001.SZ 2010-03-31 0.0334
#> 4 1 000001.SZ 2010-04-30 -0.114
#> 5 1 000001.SZ 2010-05-31 -0.148
#> 6 1 000001.SZ 2010-06-30 0
#> 7 1 000001.SZ 2010-07-30 0
#> 8 1 000001.SZ 2010-08-31 0
#> 9 1 000001.SZ 2010-09-30 -0.0737
#> 10 1 000001.SZ 2010-10-29 0.135
#> # … with 635 more rows

weights <- c(
0.5, 0.25, 0.25,
0.25, 0.5, 0.25,
0.25, 0.25, 0.5
)
stocks = c('000001.SZ', '000002.SZ', '000004.SZ')
(weights_table <- tibble(stocks) %>%
tq_repeat_df(3) %>%
bind_cols(tibble(weights)) %>%
group_by(portfolio))

#> # A tibble: 9 x 3
#> # Groups: portfolio [3]
#> portfolio stocks weights
#> <int> <chr> <dbl>
#> 1 1 000001.SZ 0.5
#> 2 1 000002.SZ 0.25
#> 3 1 000004.SZ 0.25
#> 4 2 000001.SZ 0.25
#> 5 2 000002.SZ 0.5
#> 6 2 000004.SZ 0.25
#> 7 3 000001.SZ 0.25
#> 8 3 000002.SZ 0.25
#> 9 3 000004.SZ 0.5
R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(portfolio_returns_monthly_multi <- stock_returns_monthly_multi %>%
tq_portfolio(assets_col = symbol,
returns_col = ra,
weights = weights_table,
col_rename = 'ra'))

#> # A tibble: 219 x 3
#> # Groups: portfolio [3]
#> portfolio date ra
#> <int> <date> <dbl>
#> 1 1 2010-01-29 -0.0721
#> 2 1 2010-02-26 0.0437
#> 3 1 2010-03-31 0.0458
#> 4 1 2010-04-30 -0.121
#> 5 1 2010-05-31 -0.126
#> 6 1 2010-06-30 -0.0325
#> 7 1 2010-07-30 0.0898
#> 8 1 2010-08-31 0.0577
#> 9 1 2010-09-30 -0.0295
#> 10 1 2010-10-29 0.111
#> # … with 209 more rows
R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(rarb_multi_portfolio <- left_join(
portfolio_returns_monthly_multi, rb,
by = "date"
))

#> # A tibble: 219 x 4
#> # Groups: portfolio [3]
#> portfolio date ra rb
#> <int> <date> <dbl> <dbl>
#> 1 1 2010-01-29 -0.0721 -0.205
#> 2 1 2010-02-26 0.0437 0.0849
#> 3 1 2010-03-31 0.0458 0.0179
#> 4 1 2010-04-30 -0.121 -0.199
#> 5 1 2010-05-31 -0.126 -0.106
#> 6 1 2010-06-30 -0.0325 -0.325
#> 7 1 2010-07-30 0.0898 0.600
#> 8 1 2010-08-31 0.0577 0.0671
#> 9 1 2010-09-30 -0.0295 0.0516
#> 10 1 2010-10-29 0.111 0.381
#> # … with 209 more rows

CAPM 模型

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
rarb_multi_portfolio %>%
tq_performance(
Ra = ra,
Rb = rb,
performance_fun = table.CAPM
)

#> # A tibble: 3 x 13
#> # Groups: portfolio [3]
#> portfolio ActivePremium Alpha AnnualizedAlpha Beta `Beta-` `Beta+` Correlation `Correlationp-v… InformationRatio `R-squared`
#> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 0.145 0.0133 0.172 0.00290 0.05 0.0018 0.267 0.0236 0.0053 0.0711
#> 2 2 0.168 0.0153 0.200 0.0025 0.0242 0.0015 0.232 0.0496 0.0061 0.0539
#> 3 3 0.206 0.019 0.254 0.00240 0.0692 0.0013 0.199 0.0944 0.0075 0.0394
#> # … with 2 more variables: TrackingError <dbl>, TreynorRatio <dbl>

夏普比率

R
1
2
3
4
5
6
7
8
9
10
11
12
13
rarb_multi_portfolio %>%
tq_performance(
Ra = ra,
Rb = NULL,
performance_fun = SharpeRatio
)
#> # A tibble: 3 x 4
#> # Groups: portfolio [3]
#> portfolio `ESSharpe(Rf=0%,p=95%)` `StdDevSharpe(Rf=0%,p=95%)` `VaRSharpe(Rf=0%,p=95%)`
#> <int> <dbl> <dbl> <dbl>
#> 1 1 0.106 0.189 0.134
#> 2 2 0.127 0.208 0.161
#> 3 3 0.127 0.223 0.158

查看所有可以使用的函数

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
tq_performance_fun_options()
#> $table.funs
#> [1] "table.AnnualizedReturns" "table.Arbitrary" "table.Autocorrelation" "table.CAPM" "table.CaptureRatios"
#> [6] "table.Correlation" "table.Distributions" "table.DownsideRisk" "table.DownsideRiskRatio" "table.DrawdownsRatio"
#> [11] "table.HigherMoments" "table.InformationRatio" "table.RollingPeriods" "table.SFM" "table.SpecificRisk"
#> [16] "table.Stats" "table.TrailingPeriods" "table.UpDownRatios" "table.Variability" #>

#> $CAPM.funs
#> [1] "CAPM.alpha" "CAPM.beta" "CAPM.beta.bear" "CAPM.beta.bull" "CAPM.CML" "CAPM.CML.slope"
#> [7] "CAPM.dynamic" "CAPM.epsilon" "CAPM.jensenAlpha" "CAPM.RiskPremium" "CAPM.SML.slope" "TimingRatio"
#> [13] "MarketTiming" #>

#> $SFM.funs
#> [1] "SFM.alpha" "SFM.beta" "SFM.CML" "SFM.CML.slope" "SFM.dynamic" "SFM.epsilon" "SFM.jensenAlpha"#>

#> $descriptive.funs
#> [1] "mean" "sd" "min" "max" "cor" "mean.geometric" "mean.stderr"
#> [8] "mean.LCL" "mean.UCL" #>

#> $annualized.funs
#> [1] "Return.annualized" "Return.annualized.excess" "sd.annualized" "SharpeRatio.annualized" #>

#> $VaR.funs
#> [1] "VaR" "ES" "ETL" "CDD" "CVaR"#>

#> $moment.funs
#> [1] "var" "cov" "skewness" "kurtosis" "CoVariance" "CoSkewness"
#> [7] "CoSkewnessMatrix" "CoKurtosis" "CoKurtosisMatrix" "M3.MM" "M4.MM" "BetaCoVariance"
#> [13] "BetaCoSkewness" "BetaCoKurtosis" #>

#> $drawdown.funs
#> [1] "AverageDrawdown" "AverageLength" "AverageRecovery" "DrawdownDeviation" "DrawdownPeak" "maxDrawdown" #>

#> $Bacon.risk.funs
#> [1] "MeanAbsoluteDeviation" "Frequency" "SharpeRatio" "MSquared" "MSquaredExcess"
#> [6] "HurstIndex" #>

#> $Bacon.regression.funs
#> [1] "CAPM.alpha" "CAPM.beta" "CAPM.epsilon" "CAPM.jensenAlpha" "SystematicRisk" "SpecificRisk"
#> [7] "TotalRisk" "TreynorRatio" "AppraisalRatio" "FamaBeta" "Selectivity" "NetSelectivity" #>

#> $Bacon.relative.risk.funs
#> [1] "ActivePremium" "ActiveReturn" "TrackingError" "InformationRatio"#>

#> $Bacon.drawdown.funs
#> [1] "PainIndex" "PainRatio" "CalmarRatio" "SterlingRatio" "BurkeRatio" "MartinRatio" "UlcerIndex" #>

#> $Bacon.downside.risk.funs
#> [1] "DownsideDeviation" "DownsidePotential" "DownsideFrequency" "SemiDeviation" "SemiVariance"
#> [6] "UpsideRisk" "UpsidePotentialRatio" "UpsideFrequency" "BernardoLedoitRatio" "DRatio"
#> [11] "Omega" "OmegaSharpeRatio" "OmegaExcessReturn" "SortinoRatio" "M2Sortino"
#> [16] "Kappa" "VolatilitySkewness" "AdjustedSharpeRatio" "SkewnessKurtosisRatio" "ProspectRatio" #>

#> $misc.funs
#> [1] "KellyRatio" "Modigliani" "UpDownRatios"

table.Stats

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 返回基本统计量
rarb_multi_portfolio %>%
tq_performance(
Ra = ra,
Rb = NULL,
performance_fun = table.Stats
)
#> # A tibble: 3 x 17
#> # Groups: portfolio [3]
#> portfolio ArithmeticMean GeometricMean Kurtosis `LCLMean(0.95)` Maximum Median Minimum NAs Observations Quartile1 Quartile3 SEMean
#> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 0.0161 0.0126 -0.0171 -0.0038 0.230 0.0142 -0.190 0 73 -0.0366 0.0609 0.01
#> 2 2 0.018 0.0144 0.768 -0.0022 0.310 0.0164 -0.180 0 73 -0.0416 0.0684 0.0102
#> 3 3 0.0213 0.0169 -0.361 -0.001 0.217 0.0212 -0.190 0 73 -0.0401 0.0877 0.0112
#> # … with 4 more variables: Skewness <dbl>, Stdev <dbl>, `UCLMean(0.95)` <dbl>, Variance <dbl>

table.CAPM

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 返回与CAPM相关的度量
rarb_multi_portfolio %>%
tq_performance(
Ra = ra,
Rb = rb,
performance_fun = table.CAPM
)
#> # A tibble: 3 x 13
#> # Groups: portfolio [3]
#> portfolio ActivePremium Alpha AnnualizedAlpha Beta `Beta-` `Beta+` Correlation `Correlationp-v… InformationRatio `R-squared`
#> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 0.145 0.0133 0.172 0.00290 0.05 0.0018 0.267 0.0236 0.0053 0.0711
#> 2 2 0.168 0.0153 0.200 0.0025 0.0242 0.0015 0.232 0.0496 0.0061 0.0539
#> 3 3 0.206 0.019 0.254 0.00240 0.0692 0.0013 0.199 0.0944 0.0075 0.0394
#> # … with 2 more variables: TrackingError <dbl>, TreynorRatio <dbl>

table.AnnualizedReturns

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 返回年度回报、标准差和夏普比率
rarb_multi_portfolio %>%
tq_performance(
Ra = ra,
Rb = NULL,
performance_fun = table.AnnualizedReturns
)
#> # A tibble: 3 x 4
#> # Groups: portfolio [3]
#> portfolio AnnualizedReturn `AnnualizedSharpe(Rf=0%)` AnnualizedStdDev
#> <int> <dbl> <dbl> <dbl>
#> 1 1 0.162 0.547 0.296
#> 2 2 0.188 0.623 0.301
#> 3 3 0.222 0.670 0.332

table.Correlation

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 返回与基准收益的回报率
rarb_multi_portfolio %>%
tq_performance(
Ra = ra,
Rb = rb,
performance_fun = table.Correlation
)
#> # A tibble: 3 x 5
#> # Groups: portfolio [3]
#> portfolio `p-value` `Lower CI` `Upper CI` torb
#> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 1 0.0236 0.0372 0.469 0.267
#> 2 2 0.0496 0.000599 0.440 0.232
#> 3 3 0.0944 -0.0347 0.411 0.199

table.DownsideRisk

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 返回下行风险表,以便在多个工具或基金之间进行比较
rarb_multi_portfolio %>%
tq_performance(
Ra = ra,
Rb = rb,
performance_fun = table.DownsideRisk
)
#> # A tibble: 3 x 12
#> # Groups: portfolio [3]
#> portfolio `DownsideDeviat… `DownsideDeviat… `DownsideDeviat… GainDeviation `HistoricalES(9… `HistoricalVaR(… LossDeviation
#> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 0.05 0.0544 0.05 0.0581 -0.152 -0.123 0.0472
#> 2 2 0.0485 0.0529 0.0485 0.0635 -0.145 -0.118 0.0461
#> 3 3 0.0553 0.0596 0.0553 0.0636 -0.169 -0.132 0.0527
#> # … with 4 more variables: MaximumDrawdown <dbl>, `ModifiedES(95%)` <dbl>, `ModifiedVaR(95%)` <dbl>, SemiDeviation <dbl>

table.DownsideRiskRatio

R
1
2
3
4
5
6
7
8
9
10
11
12
# 返回每月下行风险、年度下行风险等指标
rarb_multi_portfolio %>%
tq_performance(Ra = ra,
Rb = NULL,
performance_fun = table.DownsideRiskRatio)
#> # A tibble: 3 x 9
#> # Groups: portfolio [3]
#> portfolio Annualiseddownsid… Downsidepotential Monthlydownsider… Omega `Omega-sharpera… Sortinoratio Upsidepotential Upsidepotentialr…
#> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 0.173 0.0259 0.05 1.62 0.622 0.323 0.0421 0.954
#> 2 2 0.168 0.0247 0.0485 1.73 0.729 0.371 0.0428 0.921
#> 3 3 0.192 0.0281 0.0553 1.76 0.759 0.386 0.0494 0.935

table.HigherMoments

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 返回分布的高阶矩和协矩
rarb_multi_portfolio %>%
tq_performance(
Ra = ra,
Rb = rb,
performance_fun = table.HigherMoments
)
#> # A tibble: 3 x 6
#> # Groups: portfolio [3]
#> portfolio BetaCoKurtosis BetaCoSkewness BetaCoVariance CoKurtosis CoSkewness
#> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 0.0026 0.0026 0.00290 710. 10.6
#> 2 2 0.0022 0.0022 0.0025 619. 9.22
#> 3 3 0.0021 0.0021 0.00240 576. 8.58

table.InformationRatio

R
1
2
3
4
5
6
7
8
9
10
11
12
# 返回追踪误差表、年度追踪误差和信息比率
rarb_multi_portfolio %>%
tq_performance(Ra = ra,
Rb = rb,
performance_fun = table.InformationRatio)
#> # A tibble: 3 x 4
#> # Groups: portfolio [3]
#> portfolio AnnualisedTrackingError InformationRatio TrackingError
#> <int> <dbl> <dbl> <dbl>
#> 1 1 27.4 0.0053 7.92
#> 2 2 27.5 0.0061 7.92
#> 3 3 27.5 0.0075 7.93

table.Variability

R
1
2
3
4
5
6
7
8
9
10
11
12
# 返回平均绝对差异、月标准差和年标准差
rarb_multi_portfolio %>%
tq_performance(Ra = ra,
Rb = NULL,
performance_fun = table.Variability)
#> # A tibble: 3 x 4
#> # Groups: portfolio [3]
#> portfolio AnnualizedStdDev MeanAbsolutedeviation MonthlyStdDev
#> <int> <dbl> <dbl> <dbl>
#> 1 1 0.296 0.067 0.0855
#> 2 2 0.301 0.0654 0.0868
#> 3 3 0.332 0.0756 0.0957

在险值

R
1
2
3
4
5
6
7
8
9
10
11
12
13
rarb_multi_portfolio %>%
tq_performance(
Ra = ra,
Rb = NULL,
performance_fun = VaR
)
#> # A tibble: 3 x 2
#> # Groups: portfolio [3]
#> portfolio VaR
#> <int> <dbl>
#> 1 1 -0.120
#> 2 2 -0.112
#> 3 3 -0.135

夏普比率

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
rarb_multi_portfolio %>%
tq_performance(
Ra = ra,
Rb = NULL,
performance_fun = SharpeRatio
)

#> # A tibble: 3 x 4
#> # Groups: portfolio [3]
#> portfolio `ESSharpe(Rf=0%,p=95%)` `StdDevSharpe(Rf=0%,p=95%)` `VaRSharpe(Rf=0%,p=95%)`
#> <int> <dbl> <dbl> <dbl>
#> 1 1 0.106 0.189 0.134
#> 2 2 0.127 0.208 0.161
#> 3 3 0.127 0.223 0.158

自定义 tq_portfolio

单个投资组合的增长情况

R
1
2
3
4
5
6
7
8
9
10
11
portfolio_returns_monthly %>%
ggplot(aes(x = date, y = ra)) +
geom_bar(stat = "identity", fill = palette_light()[[3]],
width = 20) +
labs(title = "Portfolio Returns",
caption = "Shows an above-zero trend meaning positive returns",
x = "", y = "Monthly Returns") +
geom_smooth(method = "lm") +
theme_tq(base_family = enfont) +
scale_color_tq() +
scale_y_continuous(labels = scales::percent)

使用 wealth.index = TRUE 参数,我们可以观察 10000 元是如何增长的:

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
wts <- c(0.5, 0, 0.5)
portfolio_growth_monthly <- stock_returns_monthly %>%
tq_portfolio(
assets_col = symbol,
returns_col = ra,
weights = wts,
col_rename = "investment.growth",
wealth.index = TRUE
) %>%
mutate(investment.growth = investment.growth * 10000)
portfolio_growth_monthly %>%
ggplot(aes(x = date, y = investment.growth)) +
geom_line(size = 1, color = palette_light()[3]) +
labs(x = "", y = "Portfolio Value",
title = "Portfolio Growth",
caption = "Now we can really visualize performance!") +
geom_smooth(method = "loess") +
theme_tq(base_family = enfont) +
scale_color_tq() +
scale_y_continuous(labels = scales::dollar)

三个投资组合的增长情况

R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
portfolio_growth_monthly_multi <- stock_returns_monthly_multi %>%
tq_portfolio(
assets_col = symbol,
returns_col = ra,
weights = weights_table,
col_rename = "investment.growth",
wealth.index = TRUE
) %>%
mutate(investment.growth = investment.growth * 10000)
portfolio_growth_monthly_multi %>%
ggplot(aes(x = date, y = investment.growth, color = factor(portfolio))) +
geom_line(size = 2) +
labs(title = "Portfolio Growth",
subtitle = "Comparing Multiple Portfolios",
caption = "Portfolio 3 is a Standout!",
x = "",
y = "Portfolio Value",
color = "Portfolio") +
geom_smooth(method = "loess") +
theme_tq(base_family = enfont) +
scale_color_tq() +
scale_y_continuous(labels = scales::dollar)

# R

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×