I'm new to mongoDB and am having difficulty getting my head around aggregation pipelines.
I have created a database that holds information regarding my stock trading. In a cut down version one document from my portfolio collection looks a bit like this
{
"date" : 2015-12-31T15:50:00.000Z,
"time" : 1550,
"aum" : 1000000,
"basket" :[
{
"_id" : "Microsoft",
"shares" : 10,
"price" : 56.53,
"fx" : 1.0
},
.
.
.
{
"_id" : "GOOG.N",
"shares" : 20,
"price" : 759.69,
"fx" : 1.0
}
]
So, for each day, I keep track of my assets under management (aum) and a list of all the positions I hold with the current price. What I need to do is to calculate the daily net and gross exposure for the portfolio as a percentage of aum. Net exposure is simply:
sum(shares*price*fx)/aum
over all the stocks. Gross exposure is:
abs(shares*price*fx)/aum
(a negative position means a short position). I need to do this as a single query using the aggregation framework. I have tried numbers of queries but none seem to work so clearly I'm just wandering around in the dark. Can anyone give some guidance?
My query looks like this
db.strategy.aggregate(
// Pipeline
[
// Stage 1
{
$project: {
"_id": 0,
"date":1,
"time":1,
"aum":1,
"strategyName":1,
"gExposure": {$divide: ["$grossExposure","$aum"]}
}
},
// Stage 2
{
$group: {
_id :{ date:"$date",time:"$time",strategyName:"$strategyName"},
grossExposure: { $sum: { $abs: {$multiply: [ "$basket.sysCurShares","$basket.price","$basket.fx" ] } }}
}
},
// Stage 3
{
$sort: {
"_id.date": 1, "_id.time": 1, "_id.strategyName": 1
}
}
]
);
The query runs but the calculated value is zero. My projection isn't working as I'd expect either as I would like all the data flattened to a two dimensional table.
Since the basket field is an array, you need to flatten it using $unwind
before running the $group
aggregate operation. Also, create a new field in the $project
that holds the exposure before the $group
pipeline. Continuing from your previous attempt, you could try the following pipeline:
db.strategy.aggregate([
{ "$unwind": "$basket" },
{
"$project": {
"date": 1,
"time": 1,
"strategyName": 1,
"exposure": {
"$multiply": ["$basket.sysCurShares", "$basket.price", "$basket.fx"]
}
}
},
{
"$group": {
"_id": {
"date": "$date",
"time": "$time",
"strategyName": "$strategyName"
},
"totalExposure": { "$sum": "$exposure" },
"aum": { "$first": "$aum" }
}
},
{
"$project": {
"_id": 0,
"date": "$_id.date",
"time": "$_id.time",
"strategyName": "$_id.strategyName",
"netExposure": { "$divide": ["$totalExposure", "$aum"] },
"grossExposure": {
"$abs": { "$divide": ["$totalExposure", "$aum"] }
}
}
},
{ "$sort": { "date": 1, "time": 1, "strategyName": 1 } }
]);