import%20marimo%0A%0A__generated_with%20%3D%20%220.18.3%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20!%5BMOSEK%20ApS%5D(https%3A%2F%2Fwww.mosek.com%2Fstatic%2Fimages%2Fbranding%2Fwebgraphmoseklogocolor.png%20)%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Imports%20and%20configuration%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20import%20sys%2C%20os%2C%20re%2C%20glob%0A%20%20%20%20import%20datetime%20as%20dt%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20matplotlib%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20from%20matplotlib.colors%20import%20LinearSegmentedColormap%0A%0A%20%20%20%20from%20mosek.fusion%20import%20Model%2C%20Domain%2C%20Expr%2C%20ObjectiveSense%2C%20Matrix%2C%20Var%2C%20SolutionStatus%0A%20%20%20%20import%20mosek.fusion.pythonic%20%20%20%20%23%20Requires%20MOSEK%20%3E%3D%2010.2%0A%0A%20%20%20%20%23%20Options%0A%20%20%20%20np.set_printoptions(precision%3D5%2C%20linewidth%3D120%2C%20suppress%3DTrue)%0A%20%20%20%20pd.set_option(%22display.max_rows%22%2C%20None)%0A%20%20%20%20plt.rcParams%5B%22figure.figsize%22%5D%20%3D%20%5B12%2C%208%5D%0A%0A%20%20%20%20%23%20Diagnostic%0A%20%20%20%20print(f%22Python%3A%20%7Bsys.version%7D%22)%0A%20%20%20%20print(f%22marimo%3A%20%7Bmo.__version__%7D%2C%20matplotlib%3A%20%7Bmatplotlib.__version__%7D%2C%20pandas%3A%20%7Bpd.__version__%7D%2C%20numpy%3A%20%7Bnp.__version__%7D%2C%20mosek%3A%20%7BModel.getVersion()%7D%22)%0A%20%20%20%20return%20Domain%2C%20Expr%2C%20Model%2C%20ObjectiveSense%2C%20SolutionStatus%2C%20np%2C%20sys%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Prepare%20input%20data%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20In%20this%20example%2C%20the%20input%20data%20is%20given.%20It%20consists%20of%20the%20vector%20%24%5Cmu%24%20of%20expected%20returns%2C%20and%20the%20covariance%20matrix%20%24%5CSigma%24.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(np)%3A%0A%20%20%20%20%23%20Linear%20return%20statistics%20on%20the%20investment%20horizon%0A%20%20%20%20mu%20%3D%20np.array(%5B0.07197349%2C%200.15518171%2C%200.17535435%2C%200.0898094%20%2C%200.42895777%2C%200.39291844%2C%200.32170722%2C%200.18378628%5D)%0A%20%20%20%20Sigma%20%3D%20np.array(%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.09460323%2C%200.03735969%2C%200.03488376%2C%200.03483838%2C%200.05420885%2C%200.03682539%2C%200.03209623%2C%200.03271886%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.03735969%2C%200.07746293%2C%200.03868215%2C%200.03670678%2C%200.03816653%2C%200.03634422%2C%200.0356449%20%2C%200.03422235%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.03488376%2C%200.03868215%2C%200.06241065%2C%200.03364444%2C%200.03949475%2C%200.03690811%2C%200.03383847%2C%200.02433733%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.03483838%2C%200.03670678%2C%200.03364444%2C%200.06824955%2C%200.04017978%2C%200.03348263%2C%200.04360484%2C%200.03713009%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.05420885%2C%200.03816653%2C%200.03949475%2C%200.04017978%2C%200.17243352%2C%200.07886889%2C%200.06999607%2C%200.05010711%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.03682539%2C%200.03634422%2C%200.03690811%2C%200.03348263%2C%200.07886889%2C%200.09093307%2C%200.05364518%2C%200.04489357%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.03209623%2C%200.0356449%20%2C%200.03383847%2C%200.04360484%2C%200.06999607%2C%200.05364518%2C%200.09649728%2C%200.04419974%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.03271886%2C%200.03422235%2C%200.02433733%2C%200.03713009%2C%200.05010711%2C%200.04489357%2C%200.04419974%2C%200.08159633%5D%0A%20%20%20%20%20%20%20%20%20%20%5D)%0A%20%20%20%20return%20Sigma%2C%20mu%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Define%20the%20optimization%20model%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20The%20optimization%20problem%20we%20would%20like%20to%20solve%20is%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cbegin%7Barray%7D%7Blrcl%7D%0A%20%20%20%20%5Ctext%7Bmaximize%7D%20%20%20%26%20%5Cboldsymbol%7B%5Cmu%7D%5E%5Cmathsf%7BT%7D%5Cmathbf%7Bx%7D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%26%20%20%20%20%20%20%20%20%26%5C%5C%0A%20%20%20%20%5Ctext%7Bsubject%20to%7D%20%26%20%5Cleft(%5Cgamma%5E2%2C%20%5Cfrac%7B1%7D%7B2%7D%2C%20%5Cmathbf%7BG%7D%5E%5Cmathsf%7BT%7D%5Cmathbf%7Bx%7D%5Cright)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%26%20%5Cin%20%20%20%20%26%20%5Cmathcal%7BQ%7D_%5Cmathrm%7Br%7D%5E%7BN%2B2%7D%2C%5C%5C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%26%20%5Cmathbf%7B1%7D%5E%5Cmathsf%7BT%7D%5Cmathbf%7Bx%7D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%26%20%3D%20%20%20%20%20%20%26%201%2C%5C%5C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%26%20%5Cmathbf%7Bx%7D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%26%20%5Cgeq%20%20%20%26%200.%0A%20%20%20%20%5Cend%7Barray%7D%0A%20%20%20%20%24%24%0A%0A%0A%20%20%20%20Here%20we%20define%20this%20model%20in%20MOSEK%20Fusion.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Domain%2C%20Expr%2C%20Model%2C%20ObjectiveSense%2C%20SolutionStatus%2C%20sys)%3A%0A%20%20%20%20%23%20Define%20function%20solving%20the%20optimization%20model%0A%20%20%20%20def%20Markowitz(N%2C%20m%2C%20G%2C%20gamma2)%3A%0A%20%20%20%20%20%20%20%20with%20Model(%22markowitz%22)%20as%20M%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Settings%0A%20%20%20%20%20%20%20%20%20%20%20%20M.setLogHandler(sys.stdout)%20%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Decision%20variable%20(fraction%20of%20holdings%20in%20each%20security)%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20The%20variable%20x%20is%20restricted%20to%20be%20positive%2C%20which%20imposes%20the%20constraint%20of%20no%20short-selling.%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20x%20%3D%20M.variable(%22x%22%2C%20N%2C%20Domain.greaterThan(0.0))%20%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Budget%20constraint%0A%20%20%20%20%20%20%20%20%20%20%20%20M.constraint('budget'%2C%20Expr.sum(x)%20%3D%3D%201)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Objective%20%0A%20%20%20%20%20%20%20%20%20%20%20%20M.objective('obj'%2C%20ObjectiveSense.Maximize%2C%20x.T%20%40%20m)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Imposes%20a%20bound%20on%20the%20risk%0A%20%20%20%20%20%20%20%20%20%20%20%20M.constraint('risk'%2C%20Expr.vstack(gamma2%2C%200.5%2C%20G.T%20%40%20x)%2C%20Domain.inRotatedQCone())%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Solve%20optimization%0A%20%20%20%20%20%20%20%20%20%20%20%20M.solve()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Check%20if%20the%20solution%20is%20an%20optimal%20point%0A%20%20%20%20%20%20%20%20%20%20%20%20solsta%20%3D%20M.getPrimalSolutionStatus()%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(solsta%20!%3D%20SolutionStatus.Optimal)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20See%20https%3A%2F%2Fdocs.mosek.com%2Flatest%2Fpythonfusion%2Faccessing-solution.html%20about%20handling%20solution%20statuses.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20raise%20Exception(%22Unexpected%20solution%20status!%22)%20%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20returns%20%3D%20M.primalObjValue()%0A%20%20%20%20%20%20%20%20%20%20%20%20portfolio%20%3D%20x.level()%0A%0A%20%20%20%20%20%20%20%20return%20returns%2C%20portfolio%0A%20%20%20%20return%20(Markowitz%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Run%20the%20optimization%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Define%20the%20parameters%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20The%20problem%20parameters%20are%20the%20number%20of%20securities%20%24N%24%20and%20the%20risk%20limit%20%24%5Cgamma%5E2%24.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mu)%3A%0A%20%20%20%20N%20%3D%20mu.shape%5B0%5D%20%20%23%20Number%20of%20securities%0A%20%20%20%20gamma2%20%3D%200.05%20%20%20%23%20Risk%20limit%20(variance)%0A%20%20%20%20return%20N%2C%20gamma2%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Factorize%20the%20covariance%20matrix%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Here%20we%20factorize%20%24%5CSigma%24%20because%20the%20model%20is%20defined%20in%20conic%20form%2C%20and%20it%20expects%20a%20matrix%20%24G%24%20such%20that%20%24%5CSigma%20%3D%20GG%5E%5Cmathsf%7BT%7D%24.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Sigma%2C%20np)%3A%0A%20%20%20%20G%20%3D%20np.linalg.cholesky(Sigma)%20%20%23%20Cholesky%20factor%20of%20S%20to%20use%20in%20conic%20risk%20constraint%0A%20%20%20%20return%20(G%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Solve%20the%20optimization%20problem%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Next%20we%20call%20the%20function%20that%20defines%20the%20Fusion%20model%20and%20runs%20the%20optimization.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(G%2C%20Markowitz%2C%20N%2C%20gamma2%2C%20mu%2C%20np)%3A%0A%20%20%20%20%23%20Run%20optimization%20%0A%20%20%20%20f%2C%20x%20%3D%20Markowitz(N%2C%20mu%2C%20G%2C%20gamma2)%0A%20%20%20%20print(%22%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%5Cn%22)%0A%20%20%20%20print(%22RESULTS%3A%22)%0A%20%20%20%20print(f%22Optimal%20expected%20portfolio%20return%3A%20%7Bf*100%3A.4f%7D%25%22)%0A%20%20%20%20print(f%22Optimal%20portfolio%20weights%3A%20%7Bx%7D%22)%0A%20%20%20%20print(f%22Sum%20of%20weights%3A%20%7Bnp.sum(x)%7D%22)%0A%20%20%20%20return%20(x%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Test%20result%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(np%2C%20x)%3A%0A%20%20%20%20expected_x%20%3D%20np.array(%5B0.%2C%200.09126%2C%200.26911%2C%200.%2C%200.02531%2C%200.32162%2C%200.17652%2C%200.11618%5D)%0A%20%20%20%20diff%20%3D%20np.sum(np.abs(expected_x%20-%20x))%0A%20%20%20%20assert%20diff%20%3C%201e-4%2C%20f%22Resulting%20portfolio%20does%20not%20match%20expected%20one.%20Difference%20is%20%7Bdiff%7D%22%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20return%20(mo%2C)%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
a0555637c3b16343aac806609fc89545