Reputation: 9
I have a nested JSON file of financial portfolios. I need to grab the security_type from each holding for all portfolios_accounts (in the sample JSON there will only be one), as well as the summed up net worth from every individual holding, on a per-portfolio basis, all in a loop.
Eventually, I am trying to use this information to display in a pie chart that is separated based on net worth of security type.
JSON file:
{
"id": 1,
"username": "Test",
"portfolio_accounts": [
{
"id": 1,
"user": 1,
"username": "Test",
"account_type": "IRA",
"name": "MyTestAccount",
"description": "Just a Test",
"balance": 100.00,
"holdings": [
{
"id": 1,
"portfolio_id": 2,
"security_type": "Stock",
"ticker": "GOOG",
"price": 1000.50,
"shares": 20,
"purchase_date": "02-20-2021",
"cost_basis": 800.50
},
{
"id": 2,
"portfolio_id": 2,
"security_type": "Bond",
"ticker": "AMZN",
"price": 100.99,
"shares": 4,
"purchase_date": "02-20-2021",
"cost_basis": 60.65
}
]
},
{
"id": 2,
"user": 1,
"username": "Test",
"account_type": "IRA",
"name": "MyTestAccount2 - Electric Boogaloo",
"description": "Repeat",
"balance": 100.00,
"holdings": [
{
"id": 3,
"portfolio_id": 3,
"security_type": "Bond",
"ticker": "GNMA",
"price": 530.50,
"shares": 2,
"purchase_date": "02-20-2021",
"cost_basis": 40.20
}
]
}
]
}
Example of the expected pie chart output of this JSON:
A pie chart with one color for bonds ($1,464.96) and one for stocks ($20,010) filled in proportionally. If there were other security types, like crypto, I will need to do the same thing and add in a third color automatically (and so on and so forth).
Upvotes: 0
Views: 49
Reputation: 2181
Big fan of flexible solutions, so here is one using object-scan
// const objectScan = require('object-scan');
const data = { id: 1, username: 'Test', portfolio_accounts: [{ id: 1, user: 1, username: 'Test', account_type: 'IRA', name: 'MyTestAccount', description: 'Just a Test', balance: 100.00, holdings: [{ id: 1, portfolio_id: 2, security_type: 'Stock', ticker: 'GOOG', price: 1000.50, shares: 20, purchase_date: '02-20-2021', cost_basis: 800.50 }, { id: 2, portfolio_id: 2, security_type: 'Bond', ticker: 'AMZN', price: 100.99, shares: 4, purchase_date: '02-20-2021', cost_basis: 60.65 }] }, { id: 2, user: 1, username: 'Test', account_type: 'IRA', name: 'MyTestAccount2 - Electric Boogaloo', description: 'Repeat', balance: 100.00, holdings: [{ id: 3, portfolio_id: 3, security_type: 'Bond', ticker: 'GNMA', price: 530.50, shares: 2, purchase_date: '02-20-2021', cost_basis: 40.20 }] }] };
const r = objectScan(['portfolio_accounts[*].holdings[*]'], {
reverse: false,
filterFn: ({
value: { shares, price, security_type: securityType },
context: { holdings, totals }
}) => {
const netWorth = shares * price;
holdings.push({ [securityType]: netWorth });
if (!(securityType in totals)) {
totals[securityType] = 0;
}
totals[securityType] += netWorth;
}
})(data, {
holdings: [],
totals: {}
});
console.log(r);
/* =>
{
holdings: [ { Stock: 20010 }, { Bond: 403.96 }, { Bond: 1061 } ],
totals: { Stock: 20010, Bond: 1464.96 }
}
*/
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>
Disclaimer: I'm the author of object-scan
Upvotes: 0
Reputation: 22320
const data =
{ id : 1
, username : 'Test'
, portfolio_accounts:
[ { id : 1
, user : 1
, username : 'Test'
, account_type : 'IRA'
, name : 'MyTestAccount'
, description : 'Just a Test'
, balance : 100.00
, holdings:
[ { id : 1
, portfolio_id : 2
, security_type : 'Stock'
, ticker : 'GOOG'
, price : 1000.50
, shares : 20
, purchase_date : '02-20-2021'
, cost_basis : 800.50
}
, { id : 2
, portfolio_id : 2
, security_type : 'Bond'
, ticker : 'AMZN'
, price : 100.99
, shares : 4
, purchase_date : '02-20-2021'
, cost_basis : 60.65
} ] }
, { id : 2
, user : 1
, username : 'Test'
, account_type : 'IRA'
, name : 'MyTestAccount2 - Electric Boogaloo'
, description : 'Repeat'
, balance : 100.00
, holdings:
[ { id : 3
, portfolio_id : 3
, security_type : 'Bond'
, ticker : 'GNMA'
, price : 530.50
, shares : 2
, purchase_date : '02-20-2021'
, cost_basis : 40.20
} ] } ] }
, security_types = { Stock : 0, Bond : 0 }
;
for(let ptfAcc of data.portfolio_accounts )
for(let hld of ptfAcc.holdings )
security_types[hld.security_type] += (hld.price * hld.shares)
;
console.log( security_types )
Upvotes: 1
Reputation: 5201
You could create an object with all the possible security types set to 0, then sum there every holding, e.g.:
let data = {
"id": 1,
"username": "Test",
"portfolio_accounts": [
{
"id": 1,
"user": 1,
"username": "Test",
"account_type": "IRA",
"name": "MyTestAccount",
"description": "Just a Test",
"balance": 100.00,
"holdings": [
{
"id": 1,
"portfolio_id": 2,
"security_type": "Stock",
"ticker": "GOOG",
"price": 1000.50,
"shares": 20,
"purchase_date": "02-20-2021",
"cost_basis": 800.50
},
{
"id": 2,
"portfolio_id": 2,
"security_type": "Bond",
"ticker": "AMZN",
"price": 100.99,
"shares": 4,
"purchase_date": "02-20-2021",
"cost_basis": 60.65
}
]
},
{
"id": 2,
"user": 1,
"username": "Test",
"account_type": "IRA",
"name": "MyTestAccount2 - Electric Boogaloo",
"description": "Repeat",
"balance": 100.00,
"holdings": [
{
"id": 3,
"portfolio_id": 3,
"security_type": "Bond",
"ticker": "GNMA",
"price": 530.50,
"shares": 2,
"purchase_date": "02-20-2021",
"cost_basis": 40.20
}
]
}
]
};
let security_types = {
Bond: 0,
Stock: 0,
Crypto: 0
};
data.portfolio_accounts.forEach(portfolio_account => {
portfolio_account.holdings.forEach(holding => {
security_types[holding.security_type] += holding.price * holding.shares;
});
});
console.log(security_types);
Upvotes: 0