Skip to content

Commit

Permalink
investment: add sector
Browse files Browse the repository at this point in the history
  • Loading branch information
ge0ffrey committed Jul 16, 2015
1 parent d07c869 commit a8e8fc8
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 16 deletions.
Binary file modified optaplanner-examples/data/investment/import/de_smet_1.xlsx
Binary file not shown.
Binary file modified optaplanner-examples/data/investment/import/irrinki_1.xlsx
Binary file not shown.
Expand Up @@ -170,6 +170,7 @@ public enum HeaderColumnKey {
HEADER_COLUMN_EXTRA_PROPERTY_2,
HEADER_COLUMN_EXTRA_PROPERTY_3,
HEADER_COLUMN_EXTRA_PROPERTY_4,
HEADER_COLUMN_EXTRA_PROPERTY_5,
TRAILING_HEADER_COLUMN;
}

Expand Down
Expand Up @@ -27,6 +27,7 @@ public class AssetClass extends AbstractPersistable {

private String name;
private Region region;
private Sector sector;
private long expectedReturnMillis; // In milli's (so multiplied by 1000)
private long standardDeviationRiskMillis; // In milli's (so multiplied by 1000)

Expand All @@ -48,6 +49,14 @@ public void setRegion(Region region) {
this.region = region;
}

public Sector getSector() {
return sector;
}

public void setSector(Sector sector) {
this.sector = sector;
}

public long getExpectedReturnMillis() {
return expectedReturnMillis;
}
Expand Down
Expand Up @@ -40,6 +40,7 @@ public class InvestmentSolution extends AbstractPersistable implements Solution<

private InvestmentParametrization parametrization;
private List<Region> regionList;
private List<Sector> sectorList;
private List<AssetClass> assetClassList;

private List<AssetClassAllocation> assetClassAllocationList;
Expand All @@ -63,6 +64,14 @@ public void setRegionList(List<Region> regionList) {
this.regionList = regionList;
}

public List<Sector> getSectorList() {
return sectorList;
}

public void setSectorList(List<Sector> sectorList) {
this.sectorList = sectorList;
}

public List<AssetClass> getAssetClassList() {
return assetClassList;
}
Expand Down Expand Up @@ -101,6 +110,7 @@ public Collection<? extends Object> getProblemFacts() {
List<Object> facts = new ArrayList<Object>();
facts.add(parametrization);
facts.addAll(regionList);
facts.addAll(sectorList);
facts.addAll(assetClassList);
// Do not add the planning entity's (assetClassAllocationList) because that will be done automatically
return facts;
Expand Down
Expand Up @@ -48,7 +48,7 @@ public void setQuantityMillisMaximum(Long quantityMillisMaximum) {
// Complex methods
// ************************************************************************

public String getquantityMaximumLabel() {
public String getQuantityMaximumLabel() {
return InvestmentNumericUtil.formatMillisAsPercentage(quantityMillisMaximum);
}

Expand Down
@@ -0,0 +1,58 @@
/*
* Copyright 2015 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.optaplanner.examples.investment.domain;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import org.optaplanner.examples.common.domain.AbstractPersistable;
import org.optaplanner.examples.investment.domain.util.InvestmentNumericUtil;

@XStreamAlias("Sector")
public class Sector extends AbstractPersistable {

private String name;
private Long quantityMillisMaximum; // In milli's (so multiplied by 1000)

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Long getQuantityMillisMaximum() {
return quantityMillisMaximum;
}

public void setQuantityMillisMaximum(Long quantityMillisMaximum) {
this.quantityMillisMaximum = quantityMillisMaximum;
}

// ************************************************************************
// Complex methods
// ************************************************************************

public String getQuantityMaximumLabel() {
return InvestmentNumericUtil.formatMillisAsPercentage(quantityMillisMaximum);
}

@Override
public String toString() {
return name;
}

}
Expand Up @@ -33,12 +33,14 @@
import org.optaplanner.examples.investment.domain.InvestmentSolution;
import org.optaplanner.examples.investment.domain.InvestmentParametrization;
import org.optaplanner.examples.investment.domain.Region;
import org.optaplanner.examples.investment.domain.Sector;

public class InvestmentImporter extends AbstractXlsxSolutionImporter {

public static void main(String[] args) {
InvestmentImporter importer = new InvestmentImporter();
importer.convert("irrinki_1.xlsx", "irrinki_1.xml");
importer.convert("de_smet_1.xlsx", "de_smet_1.xml");
}

public InvestmentImporter() {
Expand All @@ -59,12 +61,14 @@ public static class InvestmentAllocationInputBuilder extends XslxInputBuilder {
private InvestmentSolution solution;

private Map<String, Region> regionMap;
private Map<String, Sector> sectorMap;

public Solution readSolution() throws IOException {
solution = new InvestmentSolution();
solution.setId(0L);
readParametrization();
readRegionList();
readSectorList();
readAssetClassList();
createAssetClassAllocationList();

Expand Down Expand Up @@ -106,18 +110,42 @@ private void readRegionList() throws IOException {
solution.setRegionList(regionList);
}

private void readSectorList() throws IOException {
Sheet sheet = readSheet(2, "Sectors");
Row headerRow = sheet.getRow(0);
assertCellConstant(headerRow.getCell(0), "Name");
assertCellConstant(headerRow.getCell(1), "Quantity maximum");
List<Sector> sectorList = new ArrayList<Sector>();
sectorMap = new LinkedHashMap<String, Sector>();
long id = 0L;
for (Row row : sheet) {
if (row.getRowNum() < 1) {
continue;
}
Sector sector = new Sector();
sector.setId(id);
id++;
sector.setName(readStringCell(row.getCell(0)));
sector.setQuantityMillisMaximum(parsePercentageMillis(readDoubleCell(row.getCell(1))));
sectorList.add(sector);
sectorMap.put(sector.getName(), sector);
}
solution.setSectorList(sectorList);
}

private void readAssetClassList() throws IOException {
Sheet sheet = readSheet(2, "AssetClasses");
final int ASSET_CLASS_PROPERTIES_COUNT = 5;
Sheet sheet = readSheet(3, "AssetClasses");
final int ASSET_CLASS_PROPERTIES_COUNT = 6;
Row groupHeaderRow = sheet.getRow(0);
assertCellConstant(groupHeaderRow.getCell(0), "Asset class");
assertCellConstant(groupHeaderRow.getCell(ASSET_CLASS_PROPERTIES_COUNT), "Correlation");
Row headerRow = sheet.getRow(1);
assertCellConstant(headerRow.getCell(0), "ID");
assertCellConstant(headerRow.getCell(1), "Name");
assertCellConstant(headerRow.getCell(2), "Region");
assertCellConstant(headerRow.getCell(3), "Expected return");
assertCellConstant(headerRow.getCell(4), "Standard deviation");
assertCellConstant(headerRow.getCell(3), "Sector");
assertCellConstant(headerRow.getCell(4), "Expected return");
assertCellConstant(headerRow.getCell(5), "Standard deviation");

int assetClassListSize = headerRow.getPhysicalNumberOfCells() - ASSET_CLASS_PROPERTIES_COUNT;
List<AssetClass> assetClassList = new ArrayList<AssetClass>(assetClassListSize);
Expand Down Expand Up @@ -154,8 +182,15 @@ private void readAssetClassList() throws IOException {
+ ") has a region (" + regionName + ") that is not in the regions sheet.");
}
assetClass.setRegion(region);
assetClass.setExpectedReturnMillis(parsePercentageMillis(readDoubleCell(row.getCell(3))));
assetClass.setStandardDeviationRiskMillis(parsePercentageMillis(readDoubleCell(row.getCell(4))));
String sectorName = readStringCell(row.getCell(3));
Sector sector = sectorMap.get(sectorName);
if (sector == null) {
throw new IllegalStateException("The row (" + row.getRowNum()
+ ") has a sector (" + sectorName + ") that is not in the sectors sheet.");
}
assetClass.setSector(sector);
assetClass.setExpectedReturnMillis(parsePercentageMillis(readDoubleCell(row.getCell(4))));
assetClass.setStandardDeviationRiskMillis(parsePercentageMillis(readDoubleCell(row.getCell(5))));
Map<AssetClass, Long> correlationMillisMap = new LinkedHashMap<AssetClass, Long>(assetClassListSize);
for (int i = 0; i < assetClassListSize; i++) {
AssetClass other = assetClassList.get(i);
Expand Down
Expand Up @@ -43,6 +43,7 @@
import org.optaplanner.examples.investment.domain.InvestmentSolution;
import org.optaplanner.examples.investment.domain.InvestmentParametrization;
import org.optaplanner.examples.investment.domain.Region;
import org.optaplanner.examples.investment.domain.Sector;
import org.optaplanner.examples.investment.domain.util.InvestmentNumericUtil;

import static org.optaplanner.examples.common.swingui.timetable.TimeTablePanel.HeaderColumnKey.*;
Expand All @@ -54,6 +55,7 @@ public class InvestmentPanel extends SolutionPanel {

private final TimeTablePanel<AssetClass, AssetClass> assetClassPanel;
private final TimeTablePanel<Void, Region> regionPanel;
private final TimeTablePanel<Void, Sector> sectorPanel;
private JSpinner standardDeviationMaximumField;

private boolean ignoreChangeEvents = false;
Expand All @@ -66,6 +68,8 @@ public InvestmentPanel() {
tabbedPane.add("Asset classes", new JScrollPane(assetClassPanel));
regionPanel = new TimeTablePanel<Void, Region>();
tabbedPane.add("Regions", new JScrollPane(regionPanel));
sectorPanel = new TimeTablePanel<Void, Sector>();
tabbedPane.add("Sectors", new JScrollPane(sectorPanel));
add(tabbedPane, BorderLayout.CENTER);
setPreferredSize(PREFERRED_SCROLLABLE_VIEWPORT_SIZE);
}
Expand Down Expand Up @@ -107,6 +111,7 @@ private InvestmentSolution getInvestmentSolution() {
public void resetPanel(Solution s) {
assetClassPanel.reset();
regionPanel.reset();
sectorPanel.reset();
InvestmentSolution solution = (InvestmentSolution) s;
InvestmentParametrization parametrization = solution.getParametrization();
ignoreChangeEvents = true;
Expand All @@ -127,6 +132,7 @@ private void defineGrid(InvestmentSolution solution) {
assetClassPanel.defineColumnHeaderByKey(HEADER_COLUMN_EXTRA_PROPERTY_2);
assetClassPanel.defineColumnHeaderByKey(HEADER_COLUMN_EXTRA_PROPERTY_3);
assetClassPanel.defineColumnHeaderByKey(HEADER_COLUMN_EXTRA_PROPERTY_4);
assetClassPanel.defineColumnHeaderByKey(HEADER_COLUMN_EXTRA_PROPERTY_5);
for (AssetClass assetClass : solution.getAssetClassList()) {
assetClassPanel.defineColumnHeader(assetClass, footprintWidth);
}
Expand All @@ -144,6 +150,13 @@ private void defineGrid(InvestmentSolution solution) {
for (Region region : solution.getRegionList()) {
regionPanel.defineRowHeader(region);
}

sectorPanel.defineColumnHeaderByKey(HEADER_COLUMN);
sectorPanel.defineColumnHeaderByKey(HEADER_COLUMN_EXTRA_PROPERTY_1);
sectorPanel.defineRowHeaderByKey(HEADER_ROW);
for (Sector sector : solution.getSectorList()) {
sectorPanel.defineRowHeader(sector);
}
}

private void fillCells(InvestmentSolution solution) {
Expand All @@ -152,12 +165,14 @@ private void fillCells(InvestmentSolution solution) {
assetClassPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_1, HEADER_ROW,
createTableHeader(new JLabel("Region"), null));
assetClassPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_2, HEADER_ROW,
createTableHeader(new JLabel("Expected return"), null));
createTableHeader(new JLabel("Sector"), null));
assetClassPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_3, HEADER_ROW,
createTableHeader(new JLabel("Expected return"), null));
assetClassPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_4, HEADER_ROW,
createTableHeader(new JLabel("Standard deviation risk"), null));
JLabel quantityHeaderLabel = new JLabel("Quantity");
quantityHeaderLabel.setForeground(TangoColorFactory.ORANGE_3);
assetClassPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_4, HEADER_ROW,
assetClassPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_5, HEADER_ROW,
createTableHeader(quantityHeaderLabel, null));
assetClassPanel.addColumnHeader(assetClassList.get(0), HEADER_ROW_GROUP1,
assetClassList.get(assetClassList.size() - 1), HEADER_ROW_GROUP1,
Expand Down Expand Up @@ -189,35 +204,44 @@ private void fillCells(InvestmentSolution solution) {
assetClassPanel.addRowHeader(HEADER_COLUMN_EXTRA_PROPERTY_1, allocation.getAssetClass(),
new JLabel(allocation.getAssetClass().getRegion().getName()));
assetClassPanel.addRowHeader(HEADER_COLUMN_EXTRA_PROPERTY_2, allocation.getAssetClass(),
new JLabel(allocation.getAssetClass().getExpectedReturnLabel(), SwingConstants.RIGHT));
new JLabel(allocation.getAssetClass().getSector().getName()));
assetClassPanel.addRowHeader(HEADER_COLUMN_EXTRA_PROPERTY_3, allocation.getAssetClass(),
new JLabel(allocation.getAssetClass().getExpectedReturnLabel(), SwingConstants.RIGHT));
assetClassPanel.addRowHeader(HEADER_COLUMN_EXTRA_PROPERTY_4, allocation.getAssetClass(),
new JLabel(allocation.getAssetClass().getStandardDeviationRiskLabel(), SwingConstants.RIGHT));
JLabel quantityLabel = new JLabel(allocation.getQuantityLabel(), SwingConstants.RIGHT);
quantityLabel.setForeground(TangoColorFactory.ORANGE_3);
assetClassPanel.addRowHeader(HEADER_COLUMN_EXTRA_PROPERTY_4, allocation.getAssetClass(),
assetClassPanel.addRowHeader(HEADER_COLUMN_EXTRA_PROPERTY_5, allocation.getAssetClass(),
quantityLabel);
}
JLabel expectedReturnLabel = new JLabel(InvestmentNumericUtil.formatMicrosAsPercentage(solution.calculateExpectedReturnMicros()), SwingConstants.RIGHT);
assetClassPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_2, TRAILING_HEADER_ROW,
assetClassPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_3, TRAILING_HEADER_ROW,
expectedReturnLabel);
long standardDeviationMicros = solution.calculateStandardDeviationMicros();
JLabel standardDeviationLabel = new JLabel(InvestmentNumericUtil.formatMicrosAsPercentage(standardDeviationMicros), SwingConstants.RIGHT);
if (standardDeviationMicros > solution.getParametrization().getStandardDeviationMillisMaximum() * 1000L) {
standardDeviationLabel.setForeground(TangoColorFactory.SCARLET_3);
}
assetClassPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_3, TRAILING_HEADER_ROW,
assetClassPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_4, TRAILING_HEADER_ROW,
standardDeviationLabel);
JLabel quantityTotalLabel = new JLabel(InvestmentNumericUtil.formatMillisAsPercentage(quantityTotalMillis), SwingConstants.RIGHT);
quantityTotalLabel.setForeground(TangoColorFactory.ORANGE_3);
assetClassPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_4, TRAILING_HEADER_ROW, quantityTotalLabel);

assetClassPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_5, TRAILING_HEADER_ROW, quantityTotalLabel);

regionPanel.addCornerHeader(HEADER_COLUMN, HEADER_ROW, createTableHeader(new JLabel("Region"), null));
regionPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_1, HEADER_ROW, createTableHeader(new JLabel("Quantity maximum"), null));
for (Region region : solution.getRegionList()) {
regionPanel.addRowHeader(HEADER_COLUMN, region, new JLabel(region.getName()));
regionPanel.addRowHeader(HEADER_COLUMN_EXTRA_PROPERTY_1, region,
new JLabel(region.getquantityMaximumLabel(), SwingConstants.RIGHT));
new JLabel(region.getQuantityMaximumLabel(), SwingConstants.RIGHT));
}

sectorPanel.addCornerHeader(HEADER_COLUMN, HEADER_ROW, createTableHeader(new JLabel("Sector"), null));
sectorPanel.addCornerHeader(HEADER_COLUMN_EXTRA_PROPERTY_1, HEADER_ROW, createTableHeader(new JLabel("Quantity maximum"), null));
for (Sector sector : solution.getSectorList()) {
sectorPanel.addRowHeader(HEADER_COLUMN, sector, new JLabel(sector.getName()));
sectorPanel.addRowHeader(HEADER_COLUMN_EXTRA_PROPERTY_1, sector,
new JLabel(sector.getQuantityMaximumLabel(), SwingConstants.RIGHT));
}
}

Expand Down

0 comments on commit a8e8fc8

Please sign in to comment.