FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious example

Folio - Examples from 'Getting Started'

Description
Different versions of a portfolio optimization problem.

Basic modelling and solving tasks:
  • modeling and solving a small LP problem (foliolp)
  • performing explicit initialization (folioinit*)
  • data input from file, index sets (foliodata, requires foliocpplp.dat)
  • modeling and solving a small MIP problem with binary variables (foliomip1)
  • modeling and solving a small MIP problem with semi-continuous variables (foliomip2)
  • modeling and solving QP and MIQP problems (folioqp, requires foliocppqp.dat)
  • modeling and solving QCQP problems (folioqc, requires foliocppqp.dat)
  • heuristic solution of a MIP problem (folioheur)
Advanced modeling and solving tasks:
  • enlarged version of the basic MIP model (foliomip3, to be used with data sets folio5.cdat, folio10.cdat)
  • defining an integer solution callback (foliocb)
  • using the MIP solution pool (foliosolpool)
  • using the solution enumerator (folioenumsol)
  • handling infeasibility through deviation variables (folioinfeas)
  • retrieving IIS (folioiis, foliomiis)
  • using the built-in infeasibility repair functionality (foliorep)
Further explanation of this example: 'Getting Started with BCL' for the basic modelling and solving tasks; 'Advanced Evaluators Guide' for solution enumeration and infeasibilit handling

xbfoliojava.zip[download all files]

Source Files

Data Files





foliodata.java

/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file foliodata.java
  ```````````````````
  Modeling a small LP problem
  to perform portfolio optimization.
  -- Data input from file --

  (c) 2008-2024 Fair Isaac Corporation
      author: S.Heipcke, 2003, rev. June 2008, rev. Dec. 2011
********************************************************/

import com.dashoptimization.*;
import java.io.*;
import java.lang.*;

public class foliodata {
    static final String DATAFILE = System.getProperty("XPRBDATA") +
        "/GS/foliocpplp.dat";

    static final int NSHARES = 10;     /* Number of shares */
    static final int NRISK = 5;        /* Number of high-risk shares */
    static final int NNA = 4;          /* Number of North-American shares */

    static double[] RET;               /* Estimated return in investment  */
    static final String[] RISK = {"hardware", "theater", "telecom", "software",
                                  "electronics"};  /* High-risk values among shares */
    static final String[] NA = {"treasury", "hardware", "theater", "telecom"};
    /* Shares issued in N.-America */

    static final String[] LPSTATUS = {"not loaded", "optimal", "infeasible",
                                      "worse than cutoff", "unfinished", "unbounded", "cutoff in dual",
                                      "unsolved", "nonconvex"};

    static XPRBindexSet SHARES;        /* Set of shares */

    private static void readData(XPRBprob p) throws IOException {
        int s;
        FileReader datafile=null;
        StreamTokenizer st=null;

        SHARES=p.newIndexSet("Shares",NSHARES);  /* Create the `SHARES' index set */
        RET = new double[NSHARES];

        /* Read `RET' data from file */
        datafile=new FileReader(DATAFILE);   /* Open the data file */
        st=new StreamTokenizer(datafile); /* Initialize the stream tokenizer */
        st.commentChar('!');              /* Use the character '!' for comments */
        st.eolIsSignificant(true);        /* Return end-of-line character */
        st.parseNumbers();                /* Read numbers as numbers (not strings) */

        do {                                 /* Read data file and fill the index sets */
            do {
                st.nextToken();
            } while(st.ttype==st.TT_EOL);    /* Skip empty lines and comment lines */
            if(st.ttype != st.TT_WORD && st.ttype != '"') break;
            s=SHARES.addElement(st.sval);
            if(st.nextToken() != st.TT_NUMBER) break;
            RET[s] = st.nval;
        } while( st.nextToken() == st.TT_EOL );

        datafile.close();

        SHARES.print();                   /* Print out the set contents */
    }

    public static void main(String[] args) throws Exception {
        int s;
        XPRBexpr Risk,Na,Return,Cap;
        XPRBvar[] frac;                   /* Fraction of capital used per share */

        try (XPRBprob p = new XPRBprob("FolioLP")) { /* Initialize BCL and create a new problem */

            readData(p);                     /* Read data from file */

            /* Create the decision variables */
            frac = new XPRBvar[NSHARES];
            for(s=0;s<NSHARES;s++) frac[s] = p.newVar("frac");

            /* Objective: total return */
            Return = new XPRBexpr();
            for(s=0;s<NSHARES;s++) Return.add(frac[s].mul(RET[s]));
            p.setObj(Return);                  /* Set the objective function */

            /* Limit the percentage of high-risk values */
            Risk = new XPRBexpr();
            for(s=0;s<NRISK;s++) Risk.add(frac[SHARES.getIndex(RISK[s])]);
            p.newCtr("Risk", Risk.lEql(1.0/3) );

            /* Minimum amount of North-American values */
            Na = new XPRBexpr();
            for(s=0;s<NNA;s++) Na.add(frac[SHARES.getIndex(NA[s])]);
            p.newCtr("NA", Na.gEql(0.5) );

            /* Spend all the capital */
            Cap = new XPRBexpr();
            for(s=0;s<NSHARES;s++) Cap.add(frac[s]);
            p.newCtr(Cap.eql(1));

            /* Upper bounds on the investment per share */
            for(s=0;s<NSHARES;s++) frac[s].setUB(0.3);

            /* Solve the problem */
            p.setSense(XPRB.MAXIM);
            p.lpOptimize("");

            System.out.println("Problem status: " + LPSTATUS[p.getLPStat()]);

            /* Solution printing */
            System.out.println("Total return: " + p.getObjVal());
            for(s=0;s<NSHARES;s++)
                System.out.println(/*SHARES.getIndexName(s) +*/ ": " + frac[s].getSol()*100 + "%");

        }
    }
}

Back to examples browserPrevious example