foliolp.cpp |
/********************************************************
Xpress BCL C++ Example Problems
===============================
file foliolp.cpp
````````````````
Modeling a small LP problem
to perform portfolio optimization.
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Aug. 2003, rev. Mar. 2011
********************************************************/
#include <iostream>
#include "xprb_cpp.h"
using namespace std;
using namespace ::dashoptimization;
#define NSHARES 10 // Number of shares
#define NRISK 5 // Number of high-risk shares
#define NNA 4 // Number of North-American shares
double RET[] = {5,17,26,12,8,9,7,6,31,21}; // Estimated return in investment
int RISK[] = {1,2,3,8,9}; // High-risk values among shares
int NA[] = {0,1,2,3}; // Shares issued in N.-America
int main(int argc, char **argv)
{
int s;
XPRBprob p("FolioLP"); // Initialize a new problem in BCL
XPRBexpr Risk,Na,Return,Cap;
XPRBvar frac[NSHARES]; // Fraction of capital used per share
// Create the decision variables
for(s=0;s<NSHARES;s++) frac[s] = p.newVar("frac"); //, XPRB_PL, 0, 0.3);
// Objective: total return
for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s];
p.setObj(Return); // Set the objective function
// Limit the percentage of high-risk values
for(s=0;s<NRISK;s++) Risk += frac[RISK[s]];
p.newCtr("Risk", Risk <= 1.0/3);
/* Equivalent:
XPRBctr CRisk;
CRisk = p.newCtr("Risk");
for(s=0;s<NRISK;s++) CRisk.addTerm(frac[RISK[s]], 1);
CRisk.setType(XPRB_L);
CRisk.addTerm(1.0/3);
*/
// Minimum amount of North-American values
for(s=0;s<NNA;s++) Na += frac[NA[s]];
p.newCtr("NA", Na >= 0.5);
// Spend all the capital
for(s=0;s<NSHARES;s++) Cap += frac[s];
p.newCtr("Cap", Cap == 1);
// Upper bounds on the investment per share
for(s=0;s<NSHARES;s++) frac[s].setUB(0.3);
// Export matrix to a file
/* p.exportProb(XPRB_MPS, "Folio");
p.setSense(XPRB_MAXIM);
p.exportProb(XPRB_LP, "Folio");
*/
// Disable all BCL and Optimizer message printing, except error messages
// p.setMsgLevel(1);
// Solve the problem
p.setSense(XPRB_MAXIM);
p.lpOptimize("");
char *LPSTATUS[] = {"not loaded", "optimal", "infeasible",
"worse than cutoff", "unfinished", "unbounded", "cutoff in dual",
"unsolved", "nonconvex"};
cout << "Problem status: " << LPSTATUS[p.getLPStat()] << endl;
// Solution printing
cout << "Total return: " << p.getObjVal() << endl;
for(s=0;s<NSHARES;s++)
cout << s << ": " << frac[s].getSol()*100 << "%" << endl;
return 0;
}
|
|
folioinit.cpp |
/********************************************************
Xpress BCL C++ Example Problems
===============================
file folioinit.cpp
``````````````````
Modeling a small LP problem
to perform portfolio optimization.
Explicit initialization.
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Aug. 2003, rev. Mar. 2011
********************************************************/
#include <iostream>
#include "xprb_cpp.h"
using namespace std;
using namespace ::dashoptimization;
#define NSHARES 10 // Number of shares
#define NRISK 5 // Number of high-risk shares
#define NNA 4 // Number of North-American shares
double RET[] = {5,17,26,12,8,9,7,6,31,21}; // Estimated return in investment
int RISK[] = {1,2,3,8,9}; // High-risk values among shares
int NA[] = {0,1,2,3}; // Shares issued in N.-America
void solveProb()
{
int s;
XPRBprob p("FolioLP"); // Initialize a new problem in BCL
XPRBexpr Risk,Na,Return,Cap;
XPRBvar frac[NSHARES]; // Fraction of capital used per share
// Create the decision variables
for(s=0;s<NSHARES;s++) frac[s] = p.newVar("frac");
// Objective: total return
for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s];
p.setObj(Return); // Set the objective function
// Limit the percentage of high-risk values
for(s=0;s<NRISK;s++) Risk += frac[RISK[s]];
p.newCtr("Risk", Risk <= 1.0/3);
// Minimum amount of North-American values
for(s=0;s<NNA;s++) Na += frac[NA[s]];
p.newCtr("NA", Na >= 0.5);
// Spend all the capital
for(s=0;s<NSHARES;s++) Cap += frac[s];
p.newCtr("Cap", Cap == 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("");
char *LPSTATUS[] = {"not loaded", "optimal", "infeasible",
"worse than cutoff", "unfinished", "unbounded", "cutoff in dual",
"unsolved", "nonconvex"};
cout << "Problem status: " << LPSTATUS[p.getLPStat()] << endl;
// Solution printing
cout << "Total return: " << p.getObjVal() << endl;
for(s=0;s<NSHARES;s++)
cout << s << ": " << frac[s].getSol()*100 << "%" << endl;
}
int main(int argc, char **argv)
{
if(XPRB::init() != 0)
{
cout << "Initialization failed." << endl;
return 1;
}
solveProb();
return 0;
}
|
|
foliodata.cpp |
/********************************************************
Xpress BCL C++ Example Problems
===============================
file foliodata.cpp
``````````````````
Modeling a small LP problem
to perform portfolio optimization.
-- Data input from file --
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Aug. 2003, rev. Mar. 2011
********************************************************/
#include <iostream>
#include <cstdio>
#include "xprb_cpp.h"
using namespace std;
using namespace ::dashoptimization;
#define DATAFILE "foliocpplp.dat"
#define NSHARES 10 // Number of shares
#define NRISK 5 // Number of high-risk shares
#define NNA 4 // Number of North-American shares
double RET[NSHARES]; // Estimated return in investment
char RISK[][100] = {"hardware", "theater", "telecom", "software",
"electronics"}; // High-risk values among shares
char NA[][100] = {"treasury", "hardware", "theater", "telecom"};
// Shares issued in N.-America
XPRBindexSet SHARES; // Set of shares
XPRBprob p("FolioLP"); // Initialize a new problem in BCL
void readData(void)
{
double value;
int s;
FILE *datafile;
char name[100];
SHARES=p.newIndexSet("Shares",NSHARES); // Create the `SHARES' index set
// Read `RET' data from file
datafile=fopen(DATAFILE,"r");
for(s=0;s<NSHARES;s++)
{
XPRBreadlinecb(XPRB_FGETS, datafile, 200, "T g", name, &value);
RET[SHARES+=name]=value;
}
fclose(datafile);
SHARES.print(); // Print out the set contents
}
int main(int argc, char **argv)
{
int s;
XPRBexpr Risk,Na,Return,Cap;
XPRBvar frac[NSHARES]; // Fraction of capital used per share
// Read data from file
readData();
// Create the decision variables
for(s=0;s<NSHARES;s++) frac[s] = p.newVar("frac");
// Objective: total return
for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s];
p.setObj(Return); // Set the objective function
// Limit the percentage of high-risk values
for(s=0;s<NRISK;s++) Risk += frac[SHARES[RISK[s]]];
p.newCtr("Risk", Risk <= 1.0/3);
// Minimum amount of North-American values
for(s=0;s<NNA;s++) Na += frac[SHARES[NA[s]]];
p.newCtr("NA", Na >= 0.5);
// Spend all the capital
for(s=0;s<NSHARES;s++) Cap += frac[s];
p.newCtr("Cap", Cap == 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("");
// Solution printing
cout << "Total return: " << p.getObjVal() << endl;
for(s=0;s<NSHARES;s++)
cout << SHARES[s] << ": " << frac[s].getSol()*100 << "%" << endl;
return 0;
}
|
|
foliomip1.cpp |
/********************************************************
Xpress BCL C++ Example Problems
===============================
file foliomip1.cpp
``````````````````
Modeling a small MIP problem
to perform portfolio optimization.
-- Limiting the total number of assets --
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Aug. 2003, rev. Mar. 2011
********************************************************/
#include <iostream>
#include "xprb_cpp.h"
using namespace std;
using namespace ::dashoptimization;
#define MAXNUM 4 // Max. number of different assets
#define NSHARES 10 // Number of shares
#define NRISK 5 // Number of high-risk shares
#define NNA 4 // Number of North-American shares
double RET[] = {5,17,26,12,8,9,7,6,31,21}; // Estimated return in investment
int RISK[] = {1,2,3,8,9}; // High-risk values among shares
int NA[] = {0,1,2,3}; // Shares issued in N.-America
int main(int argc, char **argv)
{
int s;
XPRBprob p("FolioMIP1"); // Initialize a new problem in BCL
XPRBexpr Risk,Na,Return,Cap,Num;
XPRBvar frac[NSHARES]; // Fraction of capital used per share
XPRBvar buy[NSHARES]; // 1 if asset is in portfolio, 0 otherwise
// Create the decision variables (including upper bounds for `frac')
for(s=0;s<NSHARES;s++)
{
frac[s] = p.newVar("frac", XPRB_PL, 0, 0.3);
buy[s] = p.newVar("buy", XPRB_BV);
}
// Objective: total return
for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s];
p.setObj(Return); // Set the objective function
// Limit the percentage of high-risk values
for(s=0;s<NRISK;s++) Risk += frac[RISK[s]];
p.newCtr(Risk <= 1.0/3);
// Minimum amount of North-American values
for(s=0;s<NNA;s++) Na += frac[NA[s]];
p.newCtr(Na >= 0.5);
// Spend all the capital
for(s=0;s<NSHARES;s++) Cap += frac[s];
p.newCtr(Cap == 1);
// Limit the total number of assets
for(s=0;s<NSHARES;s++) Num += buy[s];
p.newCtr(Num <= MAXNUM);
// Linking the variables
for(s=0;s<NSHARES;s++) p.newCtr(frac[s] <= buy[s]);
// Solve the problem
p.setSense(XPRB_MAXIM);
p.mipOptimize("");
char *MIPSTATUS[] = {"not loaded", "not optimized", "LP optimized",
"unfinished (no solution)",
"unfinished (solution found)", "infeasible", "optimal",
"unbounded"};
cout << "Problem status: " << MIPSTATUS[p.getMIPStat()] << endl;
// Solution printing
cout << "Total return: " << p.getObjVal() << endl;
for(s=0;s<NSHARES;s++)
cout << s << ": " << frac[s].getSol()*100 << "% (" << buy[s].getSol()
<< ")" << endl;
return 0;
}
|
|
foliomip2.cpp |
/********************************************************
Xpress BCL C++ Example Problems
===============================
file foliomip2.cpp
``````````````````
Modeling a small MIP problem
to perform portfolio optimization.
-- Imposing a minimum investment per share --
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Aug. 2003, rev. Mar. 2011
********************************************************/
#include <iostream>
#include "xprb_cpp.h"
using namespace std;
using namespace ::dashoptimization;
#define NSHARES 10 // Number of shares
#define NRISK 5 // Number of high-risk shares
#define NNA 4 // Number of North-American shares
double RET[] = {5,17,26,12,8,9,7,6,31,21}; // Estimated return in investment
int RISK[] = {1,2,3,8,9}; // High-risk values among shares
int NA[] = {0,1,2,3}; // Shares issued in N.-America
int main(int argc, char **argv)
{
int s;
XPRBprob p("FolioSC"); // Initialize a new problem in BCL
XPRBexpr Risk,Na,Return,Cap;
XPRBvar frac[NSHARES]; // Fraction of capital used per share
// Create the decision variables
for(s=0;s<NSHARES;s++)
{
frac[s] = p.newVar("frac", XPRB_SC, 0, 0.3);
frac[s].setLim(0.1);
}
// Objective: total return
for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s];
p.setObj(Return); // Set the objective function
// Limit the percentage of high-risk values
for(s=0;s<NRISK;s++) Risk += frac[RISK[s]];
p.newCtr(Risk <= 1.0/3);
// Minimum amount of North-American values
for(s=0;s<NNA;s++) Na += frac[NA[s]];
p.newCtr(Na >= 0.5);
// Spend all the capital
for(s=0;s<NSHARES;s++) Cap += frac[s];
p.newCtr(Cap == 1);
// Solve the problem
p.setSense(XPRB_MAXIM);
p.mipOptimize("");
// Solution printing
cout << "Total return: " << p.getObjVal() << endl;
for(s=0;s<NSHARES;s++)
cout << s << ": " << frac[s].getSol()*100 << "%" << endl;
return 0;
}
|
|
folioqp.cpp |
/********************************************************
Xpress BCL C++ Example Problems
===============================
file folioqp.cpp
````````````````
Modeling a small QP problem
to perform portfolio optimization.
-- 1. QP: minimize variance
2. MIQP: limited number of assets ---
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Aug. 2003, rev. Mar. 2011
********************************************************/
#include <iostream>
#include <cstdio>
#include "xprb_cpp.h"
using namespace std;
using namespace ::dashoptimization;
#define DATAFILE "foliocppqp.dat"
#define TARGET 9 // Target yield
#define MAXNUM 4 // Max. number of different assets
#define NSHARES 10 // Number of shares
#define NNA 4 // Number of North-American shares
double RET[] = {5,17,26,12,8,9,7,6,31,21}; // Estimated return in investment
int NA[] = {0,1,2,3}; // Shares issued in N.-America
double VAR[NSHARES][NSHARES]; // Variance/covariance matrix of
// estimated returns
int main(int argc, char **argv)
{
int s,t;
XPRBprob p("FolioQP"); // Initialize a new problem in BCL
XPRBexpr Na,Return,Cap,Num,Variance;
XPRBvar frac[NSHARES]; // Fraction of capital used per share
XPRBvar buy[NSHARES]; // 1 if asset is in portfolio, 0 otherwise
FILE *datafile;
// Read `VAR' data from file
datafile=fopen(DATAFILE,"r");
for(s=0;s<NSHARES;s++)
XPRBreadarrlinecb(XPRB_FGETS, datafile, 200, "g ", VAR[s], NSHARES);
fclose(datafile);
// **** First problem: unlimited number of assets ****
// Create the decision variables
for(s=0;s<NSHARES;s++)
frac[s] = p.newVar(XPRBnewname("frac(%d)",s+1), XPRB_PL, 0, 0.3);
// Objective: mean variance
for(s=0;s<NSHARES;s++)
for(t=0;t<NSHARES;t++) Variance += VAR[s][t]*frac[s]*frac[t];
p.setObj(Variance); // Set the objective function
// Minimum amount of North-American values
for(s=0;s<NNA;s++) Na += frac[NA[s]];
p.newCtr(Na >= 0.5);
// Spend all the capital
for(s=0;s<NSHARES;s++) Cap += frac[s];
p.newCtr(Cap == 1);
// Target yield
for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s];
p.newCtr(Return >= TARGET);
// Solve the problem
p.setSense(XPRB_MINIM);
p.lpOptimize("");
// Solution printing
cout << "With a target of " << TARGET << " minimum variance is " <<
p.getObjVal() << endl;
for(s=0;s<NSHARES;s++)
cout << s << ": " << frac[s].getSol()*100 << "%" << endl;
// **** Second problem: limit total number of assets ****
// Create the decision variables
for(s=0;s<NSHARES;s++)
buy[s] = p.newVar(XPRBnewname("buy(%d)",s+1), XPRB_BV);
// Limit the total number of assets
for(s=0;s<NSHARES;s++) Num += buy[s];
p.newCtr(Num <= MAXNUM);
// Linking the variables
for(s=0;s<NSHARES;s++) p.newCtr(frac[s] <= buy[s]);
// Solve the problem
p.mipOptimize("");
// Solution printing
cout << "With a target of " << TARGET << " and at most " << MAXNUM <<
" assets, minimum variance is " << p.getObjVal() << endl;
for(s=0;s<NSHARES;s++)
cout << s << ": " << frac[s].getSol()*100 << "% (" << buy[s].getSol()
<< ")" << endl;
return 0;
}
|
|
folioheur.cpp |
/********************************************************
Xpress BCL C++ Example Problems
===============================
file folioheur.cpp
``````````````````
Modeling a small MIP problem
to perform portfolio optimization.
-- Heuristic solution --
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Aug. 2003, rev. Mar. 2011
********************************************************/
#include <iostream>
#include "xprb_cpp.h"
#include "xprs.h"
using namespace std;
using namespace ::dashoptimization;
#define MAXNUM 4 // Max. number of shares to be selected
#define NSHARES 10 // Number of shares
#define NRISK 5 // Number of high-risk shares
#define NNA 4 // Number of North-American shares
void solveHeur();
double RET[] = {5,17,26,12,8,9,7,6,31,21}; // Estimated return in investment
int RISK[] = {1,2,3,8,9}; // High-risk values among shares
int NA[] = {0,1,2,3}; // Shares issued in N.-America
XPRBprob p("FolioMIPHeur"); // Initialize a new problem in BCL
XPRBvar frac[NSHARES]; // Fraction of capital used per share
XPRBvar buy[NSHARES]; // 1 if asset is in portfolio, 0 otherwise
int main(int argc, char **argv)
{
int s;
XPRBexpr Risk,Na,Return,Cap,Num;
// Create the decision variables (including upper bounds for `frac')
for(s=0;s<NSHARES;s++)
{
frac[s] = p.newVar("frac", XPRB_PL, 0, 0.3);
buy[s] = p.newVar("buy", XPRB_BV);
}
// Objective: total return
for(s=0;s<NSHARES;s++) Return += RET[s]*frac[s];
p.setObj(Return); // Set the objective function
// Limit the percentage of high-risk values
for(s=0;s<NRISK;s++) Risk += frac[RISK[s]];
p.newCtr(Risk <= 1.0/3);
// Minimum amount of North-American values
for(s=0;s<NNA;s++) Na += frac[NA[s]];
p.newCtr(Na >= 0.5);
// Spend all the capital
for(s=0;s<NSHARES;s++) Cap += frac[s];
p.newCtr(Cap == 1);
// Limit the total number of assets
for(s=0;s<NSHARES;s++) Num += buy[s];
p.newCtr(Num <= MAXNUM);
// Linking the variables
for(s=0;s<NSHARES;s++) p.newCtr(frac[s] <= buy[s]);
// Solve problem heuristically
p.setSense(XPRB_MAXIM);
solveHeur();
// Solve the problem
p.mipOptimize("");
// Solution printing
if(p.getMIPStat()==XPRB_MIP_SOLUTION || p.getMIPStat()==XPRB_MIP_OPTIMAL)
{
cout << "Exact solution: Total return: " << p.getObjVal() << endl;
for(s=0;s<NSHARES;s++)
cout << s << ": " << frac[s].getSol()*100 << "%" << endl;
}
else
cout << "Heuristic solution is optimal." << endl;
return 0;
}
void solveHeur()
{
XPRBbasis basis;
int s, ifgsol;
double solval, fsol[NSHARES],TOL;
XPRSsetintcontrol(p.getXPRSprob(), XPRS_CUTSTRATEGY, 0);
// Disable automatic cuts
XPRSsetintcontrol(p.getXPRSprob(), XPRS_PRESOLVE, 0);
// Switch presolve off
XPRSgetdblcontrol(p.getXPRSprob(), XPRS_FEASTOL, &TOL);
// Get feasibility tolerance
p.mipOptimize("l"); // Solve the LP-relaxation
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++)
{
fsol[s]=frac[s].getSol(); // Get the solution values of `frac'
if(fsol[s] < TOL) buy[s].setUB(0);
else if(fsol[s] > 0.2-TOL) buy[s].setLB(1);
}
p.mipOptimize("c"); // Solve the MIP-problem
ifgsol=0;
if(p.getMIPStat()==XPRB_MIP_SOLUTION || p.getMIPStat()==XPRB_MIP_OPTIMAL)
{ // If an integer feas. solution was found
ifgsol=1;
solval=p.getObjVal(); // Get the value of the best solution
cout << "Heuristic solution: Total return: " << p.getObjVal() << endl;
for(s=0;s<NSHARES;s++)
cout << s << ": " << frac[s].getSol()*100 << "%" << endl;
}
// XPRSpostsolve(p.getXPRSprob()); // Re-initialize the global 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);
}
p.loadBasis(basis); /* 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 */
basis.reset(); // No need to store the saved basis any longer
if(ifgsol==1)
XPRSsetdblcontrol(p.getXPRSprob(), XPRS_MIPABSCUTOFF, solval+TOL);
// Set the cutoff to the best known solution
}
|
|