| |||||||||
Folio - Examples from 'Getting Started' Description Different versions of a portfolio optimization problem. Basic modelling and solving tasks:
Source Files By clicking on a file name, a preview is opened at the bottom of this page. Data Files folioheur.cs /******************************************************** Xpress-BCL C# Example Problems ============================== file folioheur.cs ````````````````` Modeling a small MIP problem to perform portfolio optimization. -- Heuristic solution -- (c) 2008-2024 Fair Isaac Corporation authors: S.Heipcke, D.Brett. ********************************************************/ using System; using System.Text; using System.IO; using Optimizer; using BCL; namespace Examples { public class TestUGFolioHeur { const int MAXNUM = 4; // Max. number of shares to be selected const int NSHARES = 10; // Number of shares const int NRISK = 5; // Number of high-risk shares const int NNA = 4; // Number of North-American shares // Estimated return in investment double[] RET = {5,17,26,12,8,9,7,6,31,21}; // High-risk values among shares int[] RISK = {1,2,3,8,9}; // Shares issued in N.-America int[] NA = {0,1,2,3}; // Initialize a new problem in BCL XPRBprob p = new XPRBprob("FolioMIPHeur"); // Fraction of capital used per share XPRBvar[] frac = new XPRBvar[NSHARES]; // 1 if asset is in portfolio, 0 otherwise XPRBvar[] buy = new XPRBvar[NSHARES]; public static void Main() { XPRB.init(); int s; XPRBexpr Risk,Na,Return,Cap,Num; TestUGFolioHeur TestInstance = new TestUGFolioHeur(); // Create decision variables (including upper bounds for `frac') for(s=0;s<NSHARES;s++) { TestInstance.frac[s] = TestInstance.p.newVar("frac", BCLconstant.XPRB_PL, 0, 0.3); TestInstance.buy[s] = TestInstance.p.newVar("buy", BCLconstant.XPRB_BV); } // Objective: total return Return = new XPRBexpr(); for (s = 0; s < NSHARES; s++) Return += TestInstance.RET[s] * TestInstance.frac[s]; // Set the objective function TestInstance.p.setObj(TestInstance.p.newCtr("Objective", Return)); // Limit the percentage of high-risk values Risk = new XPRBexpr(); for (s = 0; s < NRISK; s++) Risk += TestInstance.frac[TestInstance.RISK[s]]; TestInstance.p.newCtr(Risk <= 1.0 / 3); // Minimum amount of North-American values Na = new XPRBexpr(); for (s = 0; s < NNA; s++) Na += TestInstance.frac[TestInstance.NA[s]]; TestInstance.p.newCtr(Na >= 0.5); // Spend all the capital Cap = new XPRBexpr(); for (s = 0; s < NSHARES; s++) Cap += TestInstance.frac[s]; TestInstance.p.newCtr(Cap == 1); // Limit the total number of assets Num = new XPRBexpr(); for (s = 0; s < NSHARES; s++) Num += TestInstance.buy[s]; TestInstance.p.newCtr(Num <= MAXNUM); // Linking the variables for (s = 0; s < NSHARES; s++) TestInstance.p.newCtr(TestInstance.frac[s] <= TestInstance.buy[s]); // Solve problem heuristically TestInstance.solveHeur(); // Solve the problem TestInstance.p.setSense(BCLconstant.XPRB_MAXIM); TestInstance.p.mipOptimize(); /* Solve the LP-problem */ // Solution printing if (TestInstance.p.getMIPStat() == 4 || TestInstance.p.getMIPStat() == 6) { System.Console.WriteLine("Exact solution: Total return: " + TestInstance.p.getObjVal()); for(s=0;s<NSHARES;s++) System.Console.WriteLine(s + ": " + TestInstance.frac[s].getSol() * 100 + "%"); } else System.Console.WriteLine("Heuristic solution is optimal."); return; } void solveHeur() { XPRBbasis basis; int s, ifmipsol; double solval=0, TOL; double[] fsol = new double[NSHARES]; XPRSprob xprsp = p.getXPRSprob(); xprsp.CutStrategy = 0; // Disable automatic cuts xprsp.Presolve = 0; // Switch presolve off TOL = xprsp.FeasTol; // Get feasibility tolerance p.setSense(BCLconstant.XPRB_MAXIM); p.lpOptimize(); /* Solve the LP-problem */ basis=p.saveBasis(); // Save the current basis // Fix all variables `buy' for which `frac' is at 0 or at a // relatively large value for(s=0;s<NSHARES;s++) { // Get the solution values of `frac' fsol[s]=frac[s].getSol(); if(fsol[s] < TOL) buy[s].setUB(0); else if(fsol[s] > 0.2-TOL) buy[s].setLB(1); } p.mipOptimize(); // Solve the MIP-problem // If an integer feas. solution was found... ifmipsol=0; if(p.getMIPStat()==4 || p.getMIPStat()==6) { ifmipsol=1; // ...get the value of the best solution solval=p.getObjVal(); System.Console.WriteLine("Heuristic solution: Total return: " + p.getObjVal()); for(s=0;s<NSHARES;s++) System.Console.WriteLine(s + ": " + frac[s].getSol()*100 + "%"); } xprsp.PostSolve();// Re-initialize the MIP search // Reset variables to their original bounds for(s=0;s<NSHARES;s++) if((fsol[s] < TOL) || (fsol[s] > 0.2-TOL)) { buy[s].setLB(0); buy[s].setUB(1); } /* Load the saved basis: bound changes are immediately passed on from BCL to the Optimizer if the problem has not been modified in any other way, so that there is no need to reload the matrix */ p.loadBasis(basis); // No need to store the saved basis any longer basis.reset(); // Set the cutoff to the best known solution if (ifmipsol == 1) xprsp.MIPAbsCutoff = solval + TOL; } } } | |||||||||
© Copyright 2023 Fair Isaac Corporation. |