Functions
PortfolioAnalytics.asset_return
PortfolioAnalytics.cumulative_return
PortfolioAnalytics.drawdowns
PortfolioAnalytics.es
PortfolioAnalytics.mean_return
PortfolioAnalytics.moments
PortfolioAnalytics.portfolio_optimize
PortfolioAnalytics.portfolio_return
PortfolioAnalytics.sharpe
PortfolioAnalytics.stddev
PortfolioAnalytics.value_at_risk
using PortfolioAnalytics
using Dates
using TSFrames
dates = Date(2020, 12, 31):Month(1):Date(2021, 12, 31)
TSLA = [235.22,264.51,225.16,222.64,236.48,208.40,226.56,229.06,245.24,258.49,371.33,381.58,352.26]
NFLX = [540.73,532.39,538.85,521.66,513.47,502.81,528.21,517.57,569.19,610.34,690.31,641.90,602.44]
MSFT = [222.42,231.96,232.38,235.77,252.18,249.68,270.90,284.91,301.88,281.92,331.62,330.59,336.32]
prices_ts = TSFrame([TSLA NFLX MSFT], dates, colnames=[:TSLA, :NFLX, :MSFT])
13×3 TSFrame with Date Index
Index TSLA NFLX MSFT
Date Float64 Float64 Float64
───────────────────────────────────────
2020-12-31 235.22 540.73 222.42
2021-01-31 264.51 532.39 231.96
2021-02-28 225.16 538.85 232.38
2021-03-31 222.64 521.66 235.77
2021-04-30 236.48 513.47 252.18
2021-05-31 208.4 502.81 249.68
2021-06-30 226.56 528.21 270.9
2021-07-31 229.06 517.57 284.91
2021-08-31 245.24 569.19 301.88
2021-09-30 258.49 610.34 281.92
2021-10-31 371.33 690.31 331.62
2021-11-30 381.58 641.9 330.59
2021-12-31 352.26 602.44 336.32
weights = [0.4, 0.4, 0.2]
3-element Vector{Float64}:
0.4
0.4
0.2
PortfolioAnalytics.asset_return
— Functionasset_return(price::TSFrame, period::Int=1; method::String="simple")
Calculates returns
form asset prices
.
Arguments:
price::TSFrame
: column(s) of TSFrame object of asset pricesperiod::Int=1
: return periodmethod::String="simple"
: return method, available methods;"simple"
and"log"
Example
julia> returns = asset_return(prices_ts)
12×3 TSFrame with Date Index
Index TSLA NFLX MSFT
Date Float64? Float64? Float64?
─────────────────────────────────────────────────
2021-01-31 0.124522 -0.0154236 0.0428918
2021-02-28 -0.148766 0.012134 0.00181066
2021-03-31 -0.011192 -0.0319013 0.0145882
2021-04-30 0.0621631 -0.0156999 0.0696017
2021-05-31 -0.118742 -0.0207607 -0.00991355
2021-06-30 0.0871401 0.0505161 0.0849888
2021-07-31 0.0110346 -0.0201435 0.0517165
2021-08-31 0.0706365 0.0997353 0.0595627
2021-09-30 0.0540287 0.0722957 -0.066119
2021-10-31 0.436535 0.131025 0.176291
2021-11-30 0.0276035 -0.0701279 -0.00310596
2021-12-31 -0.0768384 -0.0614737 0.0173326
julia> log_returns = asset_return(prices_ts, method = "log")
12×3 TSFrame with Date Index
Index TSLA NFLX MSFT
Date Float64? Float64? Float64?
─────────────────────────────────────────────────
2021-01-31 0.117358 -0.0155438 0.0419975
2021-02-28 -0.161068 0.0120609 0.00180902
2021-03-31 -0.0112551 -0.0324212 0.0144828
2021-04-30 0.0603075 -0.0158244 0.0672864
2021-05-31 -0.126404 -0.0209792 -0.00996302
2021-06-30 0.0835505 0.0492816 0.0815697
2021-07-31 0.0109742 -0.0203492 0.0504236
2021-08-31 0.0682533 0.0950695 0.0578562
2021-09-30 0.0526197 0.0698019 -0.0684062
2021-10-31 0.362234 0.123125 0.162366
2021-11-30 0.0272294 -0.0727082 -0.0031108
2021-12-31 -0.079951 -0.0634445 0.0171842
Notes:
missing
resulting from the function is automatically removed
PortfolioAnalytics.portfolio_return
— Functionportfolio_return(price::TSFrame, weights::Vector{<:Number}; period::Int=1, method::String="simple", colname::String="PORT")
Calculates portfolio return
from asset prices
and given weights
.
Arguments:
price::TSFrame
: column(s) of TSFrame object of asset pricesweights::Vector{<:Number}
: weights of assetsperiod::Int=1
: return periodmethod::String="simple"
: return method, available methods;"simple"
and"log"
colname::String="PORT"
: name of the column of portfolio return
Example
julia> preturns = portfolio_return(prices_ts, weights)
12×1 TSFrame with Date Index
Index PORT
Date Float64?
─────────────────────────
2021-01-31 0.0522176
2021-02-28 -0.0542905
2021-03-31 -0.0143197
2021-04-30 0.0325056
2021-05-31 -0.0577836
2021-06-30 0.0720602
2021-07-31 0.00669974
2021-08-31 0.0800613
2021-09-30 0.037306
2021-10-31 0.262282
2021-11-30 -0.017631
2021-12-31 -0.0518583
julia> log_preturns = portfolio_return(prices_ts, weights, method = "log")
12×1 TSFrame with Date Index
Index PORT
Date Float64?
─────────────────────────
2021-01-31 0.0491251
2021-02-28 -0.0592409
2021-03-31 -0.014574
2021-04-30 0.0312505
2021-05-31 -0.060946
2021-06-30 0.0694468
2021-07-31 0.00633473
2021-08-31 0.0769004
2021-09-30 0.0352874
2021-10-31 0.226617
2021-11-30 -0.0188137
2021-12-31 -0.0539213
Notes:
missing
resulting from the function is automatically removed.
julia> all_returns = TSFrames.join(returns, preturns)
12×4 TSFrame with Date Index
Index TSLA NFLX MSFT PORT
Date Float64? Float64? Float64? Float64?
──────────────────────────────────────────────────────────────
2021-01-31 0.124522 -0.0154236 0.0428918 0.0522176
2021-02-28 -0.148766 0.012134 0.00181066 -0.0542905
2021-03-31 -0.011192 -0.0319013 0.0145882 -0.0143197
2021-04-30 0.0621631 -0.0156999 0.0696017 0.0325056
2021-05-31 -0.118742 -0.0207607 -0.00991355 -0.0577836
2021-06-30 0.0871401 0.0505161 0.0849888 0.0720602
2021-07-31 0.0110346 -0.0201435 0.0517165 0.00669974
2021-08-31 0.0706365 0.0997353 0.0595627 0.0800613
2021-09-30 0.0540287 0.0722957 -0.066119 0.037306
2021-10-31 0.436535 0.131025 0.176291 0.262282
2021-11-30 0.0276035 -0.0701279 -0.00310596 -0.017631
2021-12-31 -0.0768384 -0.0614737 0.0173326 -0.0518583
PortfolioAnalytics.sharpe
— Functionsharpe(R::TSFrame, Rf::Number=0)
Calculates Sharpe Ratio
from asset returns
. Output is a NamedArray
.
Arguments:
R::TSFrame
: column(s) of TSFrame object of asset returnsRf::Number=0
: Risk-free rate
Example
julia> sharpe = sharpe(returns)
4-element Named Vector{Float64}
Sharpe Ratio (Rf=0) │
─────────────────────┼─────────
TSLA │ 0.288602
NFLX │ 0.170242
MSFT │ 0.606824
PortfolioAnalytics.mean_return
— Functionmean_return(R::TSFrame; geometric::Bool=true)
Calculates the mean return
from asset returns
. Output is a NamedArray
.
Arguments:
R::TSFrame
: column(s) of TSFrame object of asset returnsgeometric::Bool=true
: if true, calculates geometric mean
Example
julia> mean_return(returns)
4-element Named Vector{Float64}
μ │
─────┼───────────
TSLA │ 0.0342267
NFLX │ 0.00904634
MSFT │ 0.0350585
julia> mean_return(returns, geometric=false)
4-element Named Vector{Float64}
μ │
─────┼──────────
TSLA │ 0.0431772
NFLX │ 0.010848
MSFT │ 0.0366371
using Plots
# plotting mean return of stocks and portfolio
bar(names(mreturn), mreturn, labels = false)
PortfolioAnalytics.stddev
— Functionstddev(R::TSFrame)
Calculates the standard deviation
of asset returns
. Output is a NamedArray
.
Example
julia> stddev(returns)
4-element Named Vector{Float64}
σ │
─────┼──────────
TSLA │ 0.149608
NFLX │ 0.0637211
MSFT │ 0.0603753
PortfolioAnalytics.moments
— Functionmoments(R::TSFrame)
Calculates the (statistical) moments
of asset returns
. Output is a NamedArray
.
Example
julia> pmoments = moments(returns)
4×4 Named Matrix{Float64}
Tickers ╲ Moments │ Mean Std Skewness Kurtosis
──────────────────┼───────────────────────────────────────────
TSLA │ 0.0431772 0.149608 1.36882 2.19682
NFLX │ 0.010848 0.0637211 0.604374 -0.808401
MSFT │ 0.0366371 0.0603753 0.681468 0.790701
Output:
NamedArray
; rows:tickers
, columns:moments
Notes:
Kurtosis
:excess kurtosis
PortfolioAnalytics.value_at_risk
— Functionvalue_at_risk(R::TSFrame, p::Number=0.95; method::String="historical")
Calculates Value-at-Risk(VaR)
from asset returns
. Output is a NamedArray
.
Arguments:
R::TSFrame
: column(s) of TSFrame object of asset returnsp::Number=0.95
: confidence levelmethod::String="historical"
: method of VaR calculation, available methods;"historical"
and"parametric"
Example
julia> var_historical = value_at_risk(returns)
4-element Named Vector{Float64}
95% historical VaR │
────────────────────┼───────────
TSLA │ -0.132252
NFLX │ -0.0653681
MSFT │ -0.035206
julia> var_parametric = value_at_risk(returns, 0.90, method = "parametric")
4-element Named Vector{Float64}
90% parametric VaR │
────────────────────┼───────────
TSLA │ -0.148553
NFLX │ -0.0708139
MSFT │ -0.0407369
PortfolioAnalytics.es
— Functiones(R::TSFrame, p::Number=0.95; method::String="historical")
Calculates Expected Shortfall (Conditional Value at Risk)
from asset returns
. Output is a NamedArray
.
Arguments:
R::TSFrame
: column(s) of TSFrame object of asset returnsp::Number=0.95
: confidence levelmethod::String="historical"
: method of Expected Shortfall calculation
Example
julia> ES = es(returns)
4-element Named Vector{Any}
95% historical ES │
───────────────────┼───────────
TSLA │ -0.148766
NFLX │ -0.0701279
MSFT │ -0.066119
Notes:
- Available methods:
"historical"
and"parametric"
- Monte Carlo method will be implemented as part of the next release
PortfolioAnalytics.portfolio_optimize
— Functionportfolio_optimize(R::TSFrame, objective::String = "minumum variance"; target = Nothing, Rf::Number = 0)
Calculates the optimal Portfolio weights
for a given objective
and target
return.
Arguments:
R::TSFrame
: columns of TSFrame object of asset returnsobjective::String = "minumum variance"
: portfolio objective, minimizes the standard deviation for the portfolio. Available objecives;"minumum variance"
and"maximum sharpe"
target = Nothing
: target portfolio mean return for a chosen objective. It allows to move accross the efficient frontierRf::Number = 0
: risk-free rate, used withmaximum sharpe
Example
julia> opt1 = portfolio_optimize(returns, "minumum variance")
julia> opt_weights = opt1.pweights
3-element Named Vector{Float64}
Optimal Weights │
─────────────────┼───────
TSLA │ -0.0
NFLX │ 0.4438
MSFT │ 0.5562
# plotting efficient frontier and decision space
julia> opt1.plt
Optimize minumum-variance portfolio with a minumum return target of 4%
julia> opt2 = portfolio_optimize(returns, "minumum variance", target = 0.04)
# optimal portfolio weights for a chosen objective and target return
julia> opt2.pweights
3-element Named Vector{Float64}
Optimal Weights │
─────────────────┼───────
TSLA │ 0.5142
NFLX │ 0.0
MSFT │ 0.4858
Optimization of maximum sharpe portfolio
julia> opt3 = portfolio_optimize(returns, "maximum sharpe")
julia> opt3.pweights
3-element Named Vector{Float64}
Optimal Weights │
─────────────────┼─────
TSLA │ -0.0
NFLX │ 0.0
MSFT │ 1.0
julia> opt3.plt
Optimization of maximum sharpe portfolio with target return of at least 4%
julia> opt4 = portfolio_optimize(returns, "maximum sharpe", target = 0.04)
julia> opt4.pweights
3-element Named Vector{Float64}
Optimal Weights │
─────────────────┼───────
TSLA │ 0.5142
NFLX │ -0.0
MSFT │ 0.4858
Output:
Named Tuple
- 1,
preturn
: portfolio mean return - 2,
prisk
: portfolio standard deviation - 3,
psharpe
: portfolio sharpe ratio - 4,
pweights
: optimal portfolio weights for chosenobjective
and definedtarget
- 5,
plt
: plot of theefficient frontier
anddecision space
- 6,
pm
: list ofexpected returns
per each solution - 7,
po
: list of objective values per portfolio. If the objective isminimum-variance
, then standard deviations of each optimal portfolio. If the objective is set to themaximum-sharpe
, then the Sharpe Ratios of each portfolio. - 8,
pw
: list ofweights
per each solution
Example
bond = [0.06276629, 0.03958098, 0.08456482,0.02759821,0.09584956,0.06363253,0.02874502,0.02707264,0.08776449,0.02950032]
stock = [0.1759782,0.20386651,0.21993588,0.3090001,0.17365969,0.10465274,0.07888138,0.13220847,0.28409742,0.14343067]
R = TSFrame([bond stock], colnames = [:bond, :stock])
Minumum variance portfolio.
opt = portfolio_optimize(R, "minumum variance")
opt.pweights
2-element Named Vector{Float64}
Optimal Weights │
─────────────────┼───────
bond │ 0.9463
stock │ 0.0537
Minumum variance portfolio with 10% target return.
opt1 = portfolio_optimize(R, "minumum variance", target = 0.1)
opt1.plt
Maximum Sharpe portfolio with 15% target return.
opt2 = portfolio_optimize(R, "maximum sharpe", target = 0.15)
opt2.plt
using Plots
# plotting optimal weights for maximum sharpe portfolio with 15% return target
bar(names(opt2.pweights), opt2.pweights, labels = false)
PortfolioAnalytics.cumulative_return
— Functioncumulative_return(R::TSFrame; geometric::Bool=true, verbose=false)
Calculates the cumulative asset returns.
Arguments:
R::TSFrame
: column(s) of TSFrame object of asset returnsgeometric::Bool=true
: if true, calculates geometric returnsverbose=false
: if true, returns a TSFrame object of cumulaitve asset returns for data history
Example
julia> cumulative_return(returns)
3-element Named Vector{Float64}
Cumulative Return │
───────────────────┼─────────
TSLA │ 0.497577
NFLX │ 0.114123
MSFT │ 0.512094
julia> cumulative_return(returns, verbose=true)
12×3 TSFrame with Date Index
Index TSLA NFLX MSFT
Date Float64 Float64 Float64
─────────────────────────────────────────
2021-01-31 1.12452 0.984576 1.04289
2021-02-28 0.957232 0.996523 1.04478
2021-03-31 0.946518 0.964733 1.06002
2021-04-30 1.00536 0.949587 1.1338
2021-05-31 0.885979 0.929873 1.12256
2021-06-30 0.963183 0.976846 1.21797
2021-07-31 0.973812 0.957169 1.28095
2021-08-31 1.0426 1.05263 1.35725
2021-09-30 1.09893 1.12873 1.26751
2021-10-31 1.57865 1.27663 1.49096
2021-11-30 1.62223 1.1871 1.48633
2021-12-31 1.49758 1.11412 1.51209
julia> cumulative_return(returns, geometric=false)
3-element Named Vector{Float64}
Cumulative Return │
───────────────────┼─────────
TSLA │ 0.518126
NFLX │ 0.130176
MSFT │ 0.439646
PortfolioAnalytics.drawdowns
— Functiondrawdowns(R::TSFrame; geometric::Bool=true, max_drawdown::Bool=false)
Calculates the drawdowns of asset or portfolio returns. Output is a TSFrame object of drawdowns.
Arguments:
R::TSFrame
: column(s) of TSFrame object of asset returnsgeometric::Bool=true
: if true, calculates drawdowns from the geometric returnsmax_drawdown::Bool=false
: if true, returns maximum drawdown for asset(s) or a portfolio
Example
julia> drawdowns(returns)
12×3 TSFrame with Date Index
Index TSLA NFLX MSFT
Date Float64 Float64 Float64
─────────────────────────────────────────────────
2021-01-31 0.0 0.0 0.0
2021-02-28 -0.148766 0.0 0.0
2021-03-31 -0.158293 -0.0319013 0.0
2021-04-30 -0.10597 -0.0471003 0.0
2021-05-31 -0.212128 -0.0668832 -0.00991355
2021-06-30 -0.143473 -0.0197458 0.0
2021-07-31 -0.134021 -0.0394915 0.0
2021-08-31 -0.0728517 0.0 0.0
2021-09-30 -0.0227591 0.0 -0.066119
2021-10-31 0.0 0.0 0.0
2021-11-30 0.0 -0.0701279 -0.00310596
2021-12-31 -0.0768384 -0.127291 0.0
julia> drawdowns(returns, geometric=false)
12×3 TSFrame with Date Index
Index TSLA NFLX MSFT
Date Float64 Float64 Float64
──────────────────────────────────────────────────
2021-01-31 0.0 -0.0154236 0.0
2021-02-28 -0.132292 -0.00328963 0.0
2021-03-31 -0.142245 -0.0351909 0.0
2021-04-30 -0.0869655 -0.0508908 0.0
2021-05-31 -0.192558 -0.0716515 -0.00878166
2021-06-30 -0.115068 -0.0211354 0.0
2021-07-31 -0.105255 -0.0412789 0.0
2021-08-31 -0.0424401 0.0 0.0
2021-09-30 0.0 0.0 -0.0502712
2021-10-31 0.0 0.0 0.0
2021-11-30 0.0 -0.0555787 -0.00217898
2021-12-31 -0.0481756 -0.104299 0.0
julia> drawdowns(returns, max_drawdown=true)
3-element Named Vector{Float64}
Maximum Drawdown │
──────────────────┼──────────
TSLA │ -0.212128
NFLX │ -0.127291
MSFT │ -0.066119
julia> drawdowns(returns, geometric=false, max_drawdown=true)
3-element Named Vector{Float64}
Maximum Drawdown │
──────────────────┼───────────
TSLA │ -0.192558
NFLX │ -0.104299
MSFT │ -0.0502712