-
Notifications
You must be signed in to change notification settings - Fork 0
More Examples
All these examples are available with the package, taking from https://github.com/PharosAbad/EfficientFrontier.jl/tree/main/examples
Markowitz and Todd (2000, chapter 13, pp.337) computes the model
the CLA in Markowitz and Todd (2000) assumes either one IN or one OUT (if and only if one asset changes state). Our code handles two or more IN and/or OUT (allow any number of changes concurrently).
Solving the no short-sale problem:
Here are the examples: compare CLA (via CLA plugin Markowitz.jl ) to Status-Segment Method
- no short-sale: To run this example, download the CLA plugin Markowitz.jl and save it to the same path.
-
SP500: the S&P 500 data comes from R,
using RData
to import the data into Julia
general model with lower and upper bounds, inequality constraints, and equality constraints
Noting that
Do NOT convert
an example shows why the Critical Line Algorithm (CLA) fails
For advance users, or developers only!
cbCL!
: compute one or all (oneCL=false
) the Critical Line Segments by enumerating (combinations of Status)
E, V = EfficientFrontier.EVdata(:Ungil, false)
E = [0.1 0.7 0.8 2.3 2.2 1.9 5.6 5.6 7.2 1.3 7.2 -0.1 4.1 7.2] #最高期望收益有多个
P = Problem(E, V)
aCLs = sCL(P)
cbCL!(aCLs, P; oneCL=false, K=2)
sort!(aCLs, by=x -> x.L1, rev=true)
display(aCLs)
Play big (forget it, unless you have a latest CPU)
E, V = EfficientFrontier.EVdata(:Ungil, false)
A = [1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0]
b = [1.0; 0.25]
G = [0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0]
G[1, :] = -G[1, :]
g = [-0.3; 0.6]
d = vec([-0.0 -0.0 -0.0 -0.0 -0.0 -0.0 -0.0 -0.0 -0.0 -0.0 -0.1 -0.1 -0.1 -0.1])
u = vec([0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.1 0.1 0.1 0.3 0.3 0.3 0.3])
Pb = Problem(E, V, u, d, G, g, A, b)
aCLb = sCL(Pb)
ts = @elapsed cbCL!(aCLb, Pb; oneCL=false, K=Pb.M)
sort!(aCLb, by=x -> x.L1, rev=true)
display(aCLb)
println("Full search: ", ts, " seconds") #500 seconds
#aCLb = EfficientFrontier.ECL(Pb) #0.0005 seconds
One CL may be found luckily, such as from a simplify model, a quick rule, or a combinatorial search. Then, ECL!
will give us the entire frontier. Let us use the Pb
from the previous example
#E, V = EfficientFrontier.EVdata(:Ungil, false)
aCL1 = sCL(Pb)
ts = @elapsed cbCL!(aCL1, Pb; K=5)
println("search one CL: ", ts, " seconds") #0.8 seconds
nS = Settings(Pb)
ECL!(aCL1, Pb; numSettings=nS, incL=true) #increasing L
ECL!(aCL1, Pb; numSettings=nS) #decreasing L
display(aCL1)
E[4]=1.12, but BigFloat("1.12")-E[4] is: -1.065814103640150278806686401367187500000000000000000000000000027635739376302223e-16
now convert the raw data to BigFloat to improve precision (raw data to BigFloat, not raw data to Float64 then to BigFloat)
Assets 2 and 10 go IN at the same time, NOT the case that ONE at each time
2-element Vector{Event{BigFloat}}:
Event{BigFloat}(UP, IN, 2, 2.494839663636363636363636363636363636363636363636363636363636363636363636363613)
Event{BigFloat}(DN, IN, 10, 2.494839663636363636363636363636363636363636363636363636363636363636363636365064)
using BigFloat, the difference on L: -1.450876317255866697064907112950467127947488061225295272683982182988323422931288e-75
Float64
is enough thus the default
equilibrate
may improve precision if range of non-zeros in abs.(E)
or abs.(V)
is too large
BigFloat
can be tens (30 to 70), even more than 200 times slow.
If precision is a problem, Float64+equilibrate
is recommended. It is better (fast and stable) most of the time, but not always. (Due to the truncation of floating number, e.g., 1/60*50-50/60 = 0
, but if scaled down the data by 10, 1/6*5-5/6 = 1.1102230246251565e-16
)
to find the Status of first CL (the default Simplex method is the best: Faster speed and better accuracy), you can try
- Clarabel plugin uClarabel.jl: using Clarabel, an interior point numerical solver
- ASQP plugin ASQP.jl: an inertia-controlling active-set solver
This working example also test Critical Line Algorithm (CLA), the CLA plugin Markowitz.jl is needed also.