| |||||||||
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 foliomip3.cs /******************************************************** Xpress-BCL Java Example Problems ================================ file foliomip3.java ``````````````````` Modeling a MIP problem to perform portfolio optimization. -- Extending the problem with constraints on the geographical and sectorial distributions -- -- Working with a larger data set -- (c) 2009-2024 Fair Isaac Corporation author: S.Heipcke, Y.Colombani, rev. Mar. 2011 ********************************************************/ using System; using System.Collections; using System.Text; using System.IO; using BCL; namespace Examples { public class TestUGFolioMip2 { const String DATAFILE = "folio10.cdat"; const int MAXNUM = 7; /* Max. number of different assets */ const double MAXRISK = 1.0/3; /* Max. investment into high-risk values */ const double MINREG = 0.2; /* Min. investment per geogr. region */ const double MAXREG = 0.5; /* Max. investment per geogr. region */ const double MAXSEC = 0.25; /* Max. investment per ind. sector */ const double MAXVAL = 0.2; /* Max. investment per share */ const double MINVAL = 0.1; /* Min. investment per share */ static double[] RET; /* Estimated return in investment */ static int[] RISK; /* High-risk values among shares */ static bool[][] LOC; /* Geogr. region of shares */ static bool[][] SEC; /* Industry sector of shares */ static String[] SHARES_n; static String[] REGIONS_n; static String[] TYPES_n; static readonly String[] MIPSTATUS = {"not loaded", "not optimized", "LP optimized", "unfinished (no solution)", "unfinished (solution found)", "infeasible", "optimal", "unbounded"}; public static void Main() { try { readData(); /* Read data from file */ } catch (Exception exc){ Console.Error.WriteLine(exc); Console.Error.WriteLine(Environment.StackTrace); return; } XPRB.init(); /* Initialize BCL */ XPRBprob p = new XPRBprob("FolioMIP3"); /* Create a new problem in BCL */ /* Create the decision variables */ XPRBvar[] frac = new XPRBvar[SHARES_n.Length]; /* Fraction of capital used per share */ XPRBvar[] buy = new XPRBvar[SHARES_n.Length]; /* 1 if asset is in portfolio, 0 otherwise */ for(int s=0; s<SHARES_n.Length; s++) { frac[s] = p.newVar("frac", BCLconstant.XPRB_PL, 0, MAXVAL); buy[s] = p.newVar("buy", BCLconstant.XPRB_BV); } /* Objective: total return */ XPRBexpr Return = new XPRBexpr(); for(int s=0;s<SHARES_n.Length;s++) Return.add(frac[s] * RET[s]); p.setObj(Return); /* Set the objective function */ /* Limit the percentage of high-risk values */ XPRBexpr Risk = new XPRBexpr(); for(int s=0;s<RISK.Length;s++) Risk.add(frac[RISK[s]]); p.newCtr(Risk <= MAXRISK); /* Limits on geographical distribution */ XPRBexpr[] MinReg = new XPRBexpr[REGIONS_n.Length]; XPRBexpr[] MaxReg = new XPRBexpr[REGIONS_n.Length]; for(int r=0;r<REGIONS_n.Length;r++) { MinReg[r] = new XPRBexpr(); MaxReg[r] = new XPRBexpr(); for(int s=0;s<SHARES_n.Length;s++) if(LOC[r][s]) { MinReg[r].add(frac[s]); MaxReg[r].add(frac[s]); } p.newCtr(MinReg[r] >= MINREG); p.newCtr(MaxReg[r] <= MAXREG); } /* Diversification across industry sectors */ XPRBexpr[] LimSec = new XPRBexpr[TYPES_n.Length]; for(int t=0;t<TYPES_n.Length;t++) { LimSec[t] = new XPRBexpr(); for(int s=0;s<SHARES_n.Length;s++) if(SEC[t][s]) LimSec[t].add(frac[s]); p.newCtr(LimSec[t] <= MAXSEC); } /* Spend all the capital */ XPRBexpr Cap = new XPRBexpr(); for(int s=0;s<SHARES_n.Length;s++) Cap.add(frac[s]); p.newCtr(Cap == 1.0); /* Limit the total number of assets */ XPRBexpr Num = new XPRBexpr(); for(int s=0;s<SHARES_n.Length;s++) Num.add(buy[s]); p.newCtr(Num <= MAXNUM); /* Linking the variables */ for(int s=0;s<SHARES_n.Length;s++) p.newCtr(frac[s] <= buy[s] * MAXVAL); for(int s=0;s<SHARES_n.Length;s++) p.newCtr(frac[s] >= buy[s] * MINVAL); p.exportProb(BCLconstant.XPRB_LP, "dnetmat.lp"); /* Solve the problem */ p.setSense(BCLconstant.XPRB_MAXIM); p.mipOptimize(); Console.WriteLine("Problem status: " + MIPSTATUS[p.getMIPStat()]); /* Solution printing */ Console.WriteLine("Total return: " + p.getObjVal()); for(int s=0;s<SHARES_n.Length;s++) if(buy[s].getSol()>0.5) Console.WriteLine(" " + s + ": " + frac[s].getSol()*100 + "% (" + buy[s].getSol() + ")"); } /***********************Data input routines***************************/ /***************************/ /* Input a list of strings */ /***************************/ private static String[] read_str_list(String data) { return data.Split(); } private static Array read_list(String data, Type ty) { ArrayList li = new ArrayList(); foreach(String s in data.Split()) { if (s == null || s == "") { continue; } Object value = Convert.ChangeType(s, ty); li.Add(value); } return li.ToArray(ty); } /************************/ /* Input a list of ints */ /************************/ private static int[] read_int_list(String data) { return (int[])read_list(data, typeof(int)); } /****************************/ /* Input a table of doubles */ /****************************/ private static double[] read_dbl_list(String data) { return (double[])read_list(data, typeof(double)); } private static bool[] read_bool_list(String data, int len) { bool[] bools = new bool[len]; int[] trues = read_int_list(data); foreach(int t in trues) { bools[t] = true; } return bools; } /************************************/ /* Input a sparse table of bools */ /************************************/ private static bool[][] read_bool_table(StreamReader r, int nrows, int ncols) { bool[][] lists = new bool[nrows][]; for (int i = 0; i < nrows; i++) { lists[i] = new bool[ncols]; } for (int i = 0; i < nrows; i++) { String line = r.ReadLine(); if (line == null) { break; } LineData ld = new LineData(line); if (ld.data == "") { break; } bool[] row = read_bool_list(ld.data, ncols); lists[i] = row; } return lists; } private class LineData { internal String name; internal String data; internal LineData(String line) { name = ""; data = ""; line = line.Trim(); String[] split = line.Split(new char[] {'!'}, 2); // the comment char if (split.Length == 0) { return; } line = split[0].Trim(); // chop into name:data pair split = line.Split(new char[]{':'}, 2); if (split.Length == 0) { return; } if (split.Length > 1) { name = split[0].Trim(); } // lose trailing ';' data = split[split.Length - 1].Trim().TrimEnd(';').Trim(); } } private static void readData() { using (StreamReader r = new StreamReader(DATAFILE)) { for(;;) { String line = r.ReadLine(); if (line == null) { break; } LineData ld = new LineData(line); if (ld.name == "SHARES" && SHARES_n == null) { SHARES_n = read_str_list(ld.data); } else if (ld.name == "REGIONS" && REGIONS_n == null) { REGIONS_n = read_str_list(ld.data); } else if (ld.name == "TYPES" && TYPES_n == null) { TYPES_n = read_str_list(ld.data); } else if (ld.name == "RISK" && RISK == null) { RISK = read_int_list(ld.data); } else if (ld.name == "RET" && RET == null) { RET = read_dbl_list(ld.data); } else if (ld.name == "LOC" && SHARES_n != null && REGIONS_n != null) { LOC = read_bool_table(r, REGIONS_n.Length, SHARES_n.Length); } else if (ld.name == "SEC" && SHARES_n != null && REGIONS_n != null) { SEC = read_bool_table(r, TYPES_n.Length, SHARES_n.Length); } } } } } } | |||||||||
© Copyright 2023 Fair Isaac Corporation. |