class AssetReportServlet
{
public:
AssetReportServlet() { }
virtual ~AssetReportServlet() { }protected:
void doPost(HttpRequest& request, HttpResponse& response);private:
StringDecimal groupTotal;
// Store positions for all assets
StringDecimal positions;
BigDecimal allPositions; // Risks for all assets
StringDecimal m_hmRiskTable;
StringString assetToGroup;
RiskAssessorPtr assessor; std::list<std::string> sortedList();
};// This constructor initializes the servlet
void AssetReportServlet::doPost(HttpRequest& request, HttpResponse& response)
{
RecordSet& records = (RecordSet&)request.getAttribute("queryResult");
ServletOutputStream& writer = response.getWriter();
for (int row = 0; row < records.getRowCount(); row++)
{
BigDecimal pos;
BigDecimal r;
string issue = records.getItem(row, "ISSUE_NAME");
string family = records.getItem(row, "ISSUE_FAMILY");
transform(family.begin(), family.end(), family.begin(), ::toupper); if (family.find("FUND") == 0)
{
// TODO: Check with Betty on this
// pos = (quantity * market) - total price(TERM_ONE)
BigDecimal perItem = records.getDecimal(row, "MARKET_PRICE").subtract(records.getDecimal(row,"TERM_ONE")).setScale(2,BigDecimal::ROUND_HALF_UP);
pos = perItem.multiply(records.getDecimal(row, "QUANTITY")).setScale(2,BigDecimal::ROUND_HALF_UP);
BigDecimal riskCoefficient = assessor->getRiskCoefficient(records.getItem(row, "ISSUE_FAMILY"), records
.getDecimal(row, "TERM_TWO"));
BigDecimal product = riskCoefficient.multiply(pos);
r = product.divide(BigDecimal(100.0),2,BigDecimal::ROUND_HALF_UP);
positions[issue] = pos;
}
else
{
// pos = (quantity * market) - total price[TERM_ONE]
pos = records.getDecimal(row, "QUANTITY").multiply(records.getDecimal(row, "MARKET_PRICE")).setScale(2,BigDecimal::ROUND_HALF_UP);
pos = pos.subtract(records.getDecimal(row, "TERM_ONE"));
BigDecimal product = records.getDecimal(row, "TERM_TWO").multiply(pos).setScale(2,BigDecimal::ROUND_HALF_UP);
r = product.divide(BigDecimal(100.0),2,BigDecimal::ROUND_HALF_UP);
positions[issue] = pos;
}
// else {
// pos = records.getDecimal(row, "POSITION");
// risk = records.getDecimal(row, "POSITION").multiply(
// BigDecimal(0.10));
// } allPositions = allPositions.add(positions[issue]).setScale(2,BigDecimal::ROUND_HALF_UP); string group = records.getItem(row, "ISSUE_GROUP");
string name = records.getItem(row, "ISSUE_NAME");
assetToGroup[name] = group;
BigDecimal value("0.00");
StringDecimal::iterator t = groupTotal.find(group);
if (t != groupTotal.end())
value = value.add(t->second).setScale(2,BigDecimal::ROUND_HALF_UP);
value = value.add(positions[issue]).setScale(2,BigDecimal::ROUND_HALF_UP);
groupTotal[group] = value;
m_hmRiskTable[issue] = r;
} writer << "<groups>" << endl;
// groups in sorted order
StringDecimal::iterator g;
for (g = groupTotal.begin();g != groupTotal.end(); g++)
{
string grp = (*g).first;
BigDecimal position = (*g).second;
BigDecimal product = position.multiply(BigDecimal(100.0)).setScale(2,BigDecimal::ROUND_HALF_UP);
BigDecimal weight = product.divide(allPositions,2,BigDecimal::ROUND_HALF_UP);
writer << "\t<group position='" << position.toString();
writer << "' weight='" << weight.toString();
writer << "'>" << endl;
writer << "\t\t" << grp << endl; bool notFirstOne = false;
StringDecimal::iterator i;
for (i = positions.begin();i != positions.end(); i++)
{
string asset = (*i).first;
// Output asset only if it belongs in group
if (assetToGroup[asset]== grp)
{
// add newline only if it's not first one
if (notFirstOne)
writer << endl;
writer << "\t\t<asset position='" << positions[asset].toString() << "' ";
BigDecimal p = positions[asset];
BigDecimal weight1 = p.multiply(BigDecimal(100.0)).divide(position,2,BigDecimal::ROUND_HALF_UP);
// output weight and risk
writer << "weight='" << weight1.toString() << "' risk='" << m_hmRiskTable[asset].toString() << "'>" << endl;
writer << "\t\t\t" << asset << endl;
writer << "\t\t</asset>";
notFirstOne = true;
}
}
writer << endl << "\t</group>" << endl;
}
writer << "</groups>" <<endl;
writer.flush();
}