I'm designing a system designed to calculate various metrics on a set of holdings based on an initial day's holding and a feed of new trades and price ticks. The initial information comes from a WCF service with events for new trades and price updates.
The metrics required include market value (MV) that also needs to be aggregated into a hierarchy in various ways.
On the initial load we get a set of objects which look like:
Position [ Qty:double, Security:Security, Account:Account, Strategy:Strategy ]
Security [ Price:Money, Country:Country, Currency:CCY ]
Account [ Name:string, Fund:Fund, Manager:Manager, Currency:CCY ]
Strategy [Name:string]
Fund [Name:string]
Manager [Name:string]
The multiplicity looks like this:
- Manager (1) -manages-> (1..*) Account
- Fund (1) -is made up of-> (1..*) Account
- Account (1) -contains-> (1..*) Position
- Security (1) -can be in-> (1..*) Position
- Strategy (1) -contains-> (1..*) Position
- Strategy (1) -can exist in-> (1..*) Account
There are also a number of things that will happen during the day:
- Security price change - price of security changes from a -> b
- New position - There has been a trade
- Remove position - A trade has been cancelled
From the front end - we need to be able to view the data on a Manager/Fund level i.e.
- Manager 1
- Total MV = $4800
- Biggest country exposure = 43% UK
- Total % MV = 100%
- Components : List>
- Countries : List>
- Manager 2
- Total MV = $1200
- Biggest country exposure = 90% USA
- Total % MV = 100%
- Components : List>
- Countries : List>
- Fund2
- Total MV = $1200
- Biggest country exposure = 90% USA
- Total % MV = 100%
- Components : List>
- Countries : List>
Or at a security level
- Sec 1
- MV = $1000
- % of Manager 1 = 67%
- % of Fund 1 = 48%
- Sec 2
- MV = $2000
- % of Manager 3 = 12%
- % of Fund 2 = 4% ...
Entities will be loading in an identity map to ensure they exist only once in the system and so a change to a security's price will be reflected in the relevant positions.
I've look at various way's to represent this, conceptually event sourcing (http://martinfowler.com/eaaDev/EventSourcing.html) looked promising although we only need to look at the current state so is probably overkill.
My current line of thinking is to represent Manager, Fund and Account as Portfolio object:
And to use the composite pattern (Portfolio : Component, Position : Component) + visitor patterns to encapsulate hierarchy + calculation logic respectively.
Portfolio [ object: Represents, Components: ListOfComponents, Accept(Visitor v) : state ]
Component also has MV (in $) (these can be calculated using a visitor)
Let MV [position] = *Qty * Security.Price*
Let MV [portfolio] = sum of all MV of positions below.
So we have the following composite structure:
- Portfolio (Represents: Fund A, MV: 500)
- Portfolio (Represents: Account A, MV: 500)
- Position1 (MV: 300)
- Position2 (MV: 200)
- Portfolio (Represents: Account A, MV: 500)
- Portfolio (Represents: Fund B, MV 1600)
- Portfolio (Represents: Account B, MV: 1000)
- Position3 (MV: 800)
- Position4 (MV: 200)
- Portfolio (Represents: Account C, MV: 600)
- Position5 (MV: 200)
- Position6 (MV: 400)
- Portfolio (Represents: Account B, MV: 1000)
My first problem is with the representation of various levels of percentage - the system needs to be able to represent what percentage of Fund B and Account C does Position 5 make up?
Position 5 MV / Account C MV = 200 / 600 = 33%
Position 5 MV / Fund B MV = 200 / 1600 = 12.5%
The values can be calculated using the visitor but where do we store the results of the calculation?
In a dictionary in the Position 5 like so: Dictionary percentMV = {[Fund B, 12.5%], [Account C, 33%]}
Or in the relevant portfolios in which case, all of the individual positions would need to be referenced by Fund B? We would also need Position 5 in terms of the Manager that manages it.
The other concept I'm having difficulty with is country exposure metric - each security represents a certain amount of risk associated with a country. So with a portfolio of two positions: - MV of $100, Security Country = UK - MV of $300, Country = USA
The portfolio has a Country exposure of - 100/400 =25% UK, and 300/400 = 75% USA.
What's the best way to generalize this concept into the design i.e. where's the best place store the data?