The PortfolioAnalytics.jl aims to provide users with functionality for performing quantitative portfolio analytics. The package is under heavy development, and new functionalities will be added as part of ongoing releases.
Read the documentation to get started with PortfolioAnalytics.jl.
The following functions are available in the stable version:
- asset_return( )
- portfolio_return( )
- sharpe( )
- value_at_risk( )
- portfolio_optimize( )
- mean_return( )
- stddev( )
- moments( )
- es( )
- cumulative_return( )
- drawdowns( )
We greatly value contributions of any kind. Contributions could include but are not limited to documentation improvements, bug reports, new or improved code, scientific and technical code reviews, infrastructure improvements, mailing lists, chat participation, community help/building, education, and outreach.
Please report any issues via the GitHub issue tracker. All kinds of issues are welcome and encouraged; this includes bug reports, documentation typos, feature requests, etc.
The package is inspired by PerformanceAnalytics and PortfolioAnalytics packages in R and pyfolio in Python.
Please read the release notes for more information on releases.
The package is under development, and the dev version may differ from the stable version.
julia> using Pkg
julia> Pkg.add(url="https://github.com/doganmehmet/PortfolioAnalytics.jl")
julia> using Pkg
julia> Pkg.add("PortfolioAnalytics")
julia> using Pkg
julia> Pkg.update("PortfolioAnalytics")
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
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
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
You can join TSFrame objects with join( ) function from TSFrames package.
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
julia> sharpe = sharpe(returns)
4-element Named Vector{Float64}
Sharpe Ratio (Rf=0) │
─────────────────────┼─────────
TSLA │ 0.288602
NFLX │ 0.170242
MSFT │ 0.606824
julia> mreturn = 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
julia> stddev(returns)
4-element Named Vector{Float64}
σ │
─────┼──────────
TSLA │ 0.149608
NFLX │ 0.0637211
MSFT │ 0.0603753
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
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
julia> ES = es(returns)
4-element Named Vector{Any}
95% historical ES │
───────────────────┼───────────
TSLA │ -0.148766
NFLX │ -0.0701279
MSFT │ -0.066119
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
# Maximum-Sharpe portfolios
julia> opt3 = portfolio_optimize(returns, "maximum sharpe")
# Optimal weights for maximum-sharpe portfolio
julia> opt3.pweights
3-element Named Vector{Float64}
Optimal Weights │
─────────────────┼─────
TSLA │ -0.0
NFLX │ 0.0
MSFT │ 1.0
# Plot the efficient frontier and decision space
julia> opt3.plt
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> 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, max_drawdown=true)
3-element Named Vector{Float64}
Maximum Drawdown │
──────────────────┼──────────
TSLA │ -0.212128
NFLX │ -0.127291
MSFT │ -0.066119