Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Key Principles

Principle

Decision / Discussion

Status

Flexible aggregation over time

  • The reporting engine should be flexible to aggregate (cumulate) returns over time

Statuscolour
GreentitleSpecified

Scope one Portfolio

  • the inteface should always deliver data on the scope of a single portfolio (or consolidation)

status
colourGreen
titleSpecified

Benchmark Data

  • Benchmark data should be included

  • No returns should be delivered if there is only benchmark-data (see below about gaps)

StatuscolourGreentitleSpecified

Frequency

  • The standard return data granularity is monthly (optionally/additionally deliver daily data) so we can

be sure
  • assure to show the correct monthly

return

Status
colourGreen
titleSpecified

  • returns

Calendar Days

  • the field "day" is referring to a calendar day, e.g. day 5 in month 1 in year 2018 is referring to January 5th 2018.

StatuscolourGreentitle
Specified

Period Definitions

  • Periods are defined by start and end dates

  • The semantics of the start date is BOD (00:00:00) while the end date means EOD (23:59:59)

StatuscolourGreentitleSpecified

Return Types

  • Gross:

(approximated)
  • return without portfolio level fees (but including transaction fees)

  • Net:

(approxmated)
  • return including portfolio level fees

Status
colourGreen
titleSpecified

  • BM: return of the benchmark

  • Other return types (secondary benchmark, other flavours of fee recognition)

Completeness &
Ultimo-Data

  • Daily return data can have gaps (e.g. weekends) but there

is
  • should be no daily return entry without both gross/net values.

  • Monthly data have are interpreted to be

available by
  • valid for the calendar ultimo of the month

(so ordering a file on April 1 for reportingDate March 31st should contain monthly index values for March)
  • Daily data does not have to be artificially completed with a month end record (so March 31st can be missing in daily if this was a weekend)

if
  • If an order requests data for a period before the performanceMeasurementStartDate) no valid response should be returned

if
  • If an order requests data for a period reaching into the future (with respect to the most current data available) no valid response should be returned

Status
colourYellow
titleProposed

  • As the end of the performance history of a portfolio is (currently) not defined in masterdata, all month till the endDate are expected to be contained in the response

Incomplete month periods

if
  • If a portfolio starts it's performance history in the middle of a month, the

first month's index values always start at
  • initial index value is interpreted for the performanceMeasurementStartDate

if
  • If the endDate of a request lies in the middle of a month, the last

month's index values reflect the index at this endDate
  • daily index value previous to the endDate is interpreted (the endDate can be missing in the daily records)

as the end of the performance history of a portfolio is not defined in masterdata, the last month is always expected to end at the endDate as provided in the request

Status
colourYellow
titleProposed

Interface "PortfolioReturns"

Status

Status
colourGreen
titleimplemented

Usage & Contents

  • Query performance / return data on portfolio level for a given period used to produce

    • PO001: Performance Overview - reporting frequency & YTD

    • PO005: Performance Overivew - rolling

    • PO003: Cumulated performance chart

    • etc.

  • contains monthly (and optionally daily) returns

    • for portfolio and benchmark

    • for all available return types (gross, net, ?)

Path

/portfolio/returns

Parameters

portfolioId*

string

The id of the portfolio (or consolidation) in the data source

startDate*

string (date)

The start date of the period for which return data is requested

endDate*

string (date)

The end date of the period for which return data is requested

includeDailyReturns

boolean
(default: false)

Response to include daily return data (where available)

includeBenchmark

boolean
(default: false)

Response to include benchmark return data

(customBenchmarkId)

string

Future parameter to query data of the portfolio measured against another benchmark

Example call

/portfolio/returns?portfolioId=E0002&startDate=2011-04-01&endDate=2019-03-31

Response structure

If the API can fulfill the request (response status code 200 = OK) the response must have the following high-level structure and must follow the respective json-schema.

High-level Structure
Code Block
languagejs
{
    "request": { ... },
    "dataVersioning": {...},
    "returns": [ ... ]
}

Note
  • The request part of the response has to match the path and parameters used in the API call/request

  • The json schema currently excludes the schema for dataVersioning (should be designed by CSAM)

Schema

https://bitbucket.org/banknotes/ngr/src/df61b39d18a16581cd95aed9694991bbe39c5fb1/ngr-csamsolution/src/Model/schema/PortfolioReturns.schema.json?at=release%2Fcurrent

Error handling

If the request can't be fulfilled an appropriate response status code (4xx or 5xx) must be used. Possible errors could be

  • bad request structure → expected status = 400

  • portfolioId not found or reportingDate in future → expected status = 404

  • etc.

The body of the response should contain information about the reason of the error in plain text or as json object.

Reporting Business Logic

  • cumulation over time (monthly → quarterly, YTD, ITD etc.) or rather de-cumulating index values to monhtly / quarterly returns

  • alignment of data frequencies (monthly ITD history with daily for more current periods)

  • relative return calculation for different return types

  • formatting of returns (in %, in bps)

Consistency Rules

The following rules should be adhered to by any response and will

eventually Code Block
languagejs
*

be checked when consuming a response:

Consistency Rules
  • All

  • data

  • returned

  • has

  • to

  • respect

  • the

  • requested

  • period:

  • no

  • data

  • earlier

  • than

  • startDate,

  • no

  • (daily)

  • data

  • later

  • than

  • endDate

*
  • No

  • gaps

  • are

  • allowed

  • in

  • the

  • years

  • and

  • months

  • arrays

  • (only

  • daily

  • array

  • can

  • have

  • gaps

  • for

  • weekends/holidays)

*
  • (Year,

  • Month,

  • Day)

  • has

  • to

  • be

  • a

  • valid

  • date

  • (e.g.

  • no

  • 31.

  • of

  • april)

*
  • all

  • return

  • data

  • (years,

  • months,

  • days)

  • should

  • be

  • sorted

  • in

  • the

  • chronological

  • order

*
  • if

  • ordered

  • with

  • "includeBenchmark",

  • "bmIndexStart"

  • has

  • to

  • be

  • provided

  • and

  • all

  • indexed

  • return

  • objects

  • have

  • to

  • provide

  • a

  • "bmIndex"

  • value

*
  • the

  • interface

  • should

  • respond

  • with

  • a

  • valid

  • file

  • for

  • any

  • period

  • starting

  • earliest

  • at

  • PortfolioMasterData.performanceMeasurementStartDate

  • and

  • ending

  • with

  • the

  • most

  • current

  • date

  • (delivered

  • by

  • future

  • data

  • availability

  • calls)

*
  • if

  • ordered

  • with

  • "includeDailyReturns"

  • all

  • and

  • only

  • the

  • months

  • buckets

  • beginning

  • with

  • the

  • month

  • of

  • PortfolioMasterData.dailyPerformanceStartDate

  • to

  • the

  • endDate

  • should

  • provide

  • daily

  • return

  • data.

Reporting Business Logic

  • cumulation over time (monthly → quarterly, YTD, ITD etc.) or rather de-cumulating index values to monhtly / quarterly returns

  • alignment of data frequencies (monthly ITD history with daily for more current periods)

  • relative return calculation for different return types

  • formatting of returns (in %, in bps)

Example

Example response
Code Block
languagejs
{
    "request": {
        "path": "/portfolio/returns",
        "parameters": {
            "portfolioId": "E0001",
            "period": { "startDate": "2019-03-15", "endDate": "2019-03-31" },
            "includeDailyReturns": true,
            "includeBenchmark": true
        }
    },

    "dataVersioning": "include here any data needed for data lineage like dataquality-level, timestamps, data file versions, program versions",

    "returns": {
        "indexStartValues": {"grossIndexStart": 1.00, "netIndexStart": 1.00, "bmIndexStart": 1.00},
        "indexedReturns": [
			{"year": 2019, "monthly": [
					{ "month": 3, "grossIndex": 0.998610167389151, "netIndex": 0.998411811861891, "bmIndex": 0.99832365534172 , "daily": [
						{ "day": 15, "grossIndex": 1.0045101948, "netIndex": 1.0045101948, "bmIndex": 1.0044517811 },
						{ "day": 16, "grossIndex": 1.0045101948, "netIndex": 1.0045101948, "bmIndex": 1.0044517811 },
						{ "day": 17, "grossIndex": 1.0045101948, "netIndex": 1.0045101948, "bmIndex": 1.0044517811 },
						{ "day": 18, "grossIndex": 1.00649181104652, "netIndex": 1.00649181104652, "bmIndex": 1.00642390043263 },
						{ "day": 19, "grossIndex": 1.00752296895238, "netIndex": 1.00752296895238, "bmIndex": 1.00739509929527 },
						{ "day": 20, "grossIndex": 1.00095942480408, "netIndex": 1.00095942480408, "bmIndex": 1.00084622231232 },
						{ "day": 21, "grossIndex": 1.00349696955389, "netIndex": 1.00349696955389, "bmIndex": 1.00335123601851 },
						{ "day": 22, "grossIndex": 0.989428389700745, "netIndex": 0.989428389700745, "bmIndex": 0.989231476718871 },
						{ "day": 23, "grossIndex": 0.989428389700745, "netIndex": 0.989428389700745, "bmIndex": 0.989231476718871 },
						{ "day": 24, "grossIndex": 0.989428389700745, "netIndex": 0.989428389700745, "bmIndex": 0.989231476718871 },
						{ "day": 25, "grossIndex": 0.983761504593607, "netIndex": 0.983761504593607, "bmIndex": 0.983544720209762 },
						{ "day": 26, "grossIndex": 0.993059858670534, "netIndex": 0.993059858670534, "bmIndex": 0.992871364286443 },
						{ "day": 27, "grossIndex": 0.990423681175259, "netIndex": 0.990423681175259, "bmIndex": 0.990199383224224 },
						{ "day": 28, "grossIndex": 0.991777636303084, "netIndex": 0.991777636303084, "bmIndex": 0.991461936056625 },
						{ "day": 29, "grossIndex": 0.991777636303084, "netIndex": 0.991777636303084, "bmIndex": 0.99832365534172 },
						{ "day": 30, "grossIndex": 0.991777636303084, "netIndex": 0.991777636303084, "bmIndex": 0.99832365534172 },
						{ "day": 31, "grossIndex": 0.998610167389151, "netIndex": 0.998411811861891, "bmIndex": 0.99832365534172 } ]
					}
				]
			}
		]
    }
}

Potential Problems

  • Incorrect MTD index values: If we get MTD index values built only from MTD return data, such MTD index values could be wrong if they are not adjusted to the monthly corrected data.

  • Persistent "kinks" in cumulated performance: If only month-end data is corrected but not the first N days of the new month we get a multi-day kink that shows up in the cumulated (daily) performance chart

Interface "Portfolio Instrument or Segment Returns"

Status

Status
colourBlue
titleParked

Usage

Query performance / return data on sector or instrument level for a given period used to produce

  • PO009: Performance overview - cumulated by dimension

  • PR001: Performance and contribution by position

  • PR002: Performance overview by position

Discussion

  • do we need this interface or can it be integrated into "Portfolio Performance"?

Info
  • If we assume that we only show sector returns as part of MWR contributions then we will not need this interface

  • If we want to show TWR returns e.g. in chart PO009 then we probably need this interface

  • can we aggregate from instrument to segment level (and do we want to?)

    • if no, should we allow to fetch mutliple (the portfolio's standard) segmentations in one call?

Data Contents

  • monthly (and optionally daily) returns on instrument/segment level

  • for portfolio and benchmark

  • all available return types (gross, net, ?)

Parameters

  • portfolioId

  • period

  • inculdeDailyReturns

  • includeBenchmark

Reporting Business Logic

  • aggregation from instrument to segment level???

  • cumulation over time (daily/monthly → quarterly, YTD, ITD etc.)

  • alignment of data frequencies (monthly ITD history with daily for more current periods)

  • relative return calculation for different return types

  • formatting of returns (in %, in bps)

Example

Potential Problems

Path

/portfolio/returns

Parameters

portfolioId*

string

The id of the portfolio (or consolidation) in the data source

startDate*

string (date)

The start date of the period for which return data is requested

endDate*

string (date)

The end date of the period for which return data is requested

includeDailyReturns

boolean (default: false)

Response to include daily return data (where available)

includeBenchmark

boolean (default: false)

Response to include benchmark return data

customBenchmarkId

string

parameter to query data of the portfolio measured against another benchmark

Example call

/portfolio/returns?portfolioId=E0002&startDate=2011-04-01&endDate=2019-03-31

Schema

Status
titleon request

Example

Status
titleon request

Interface "InstrumentReturns"

Usage & Contents

  • used to produce instrument returns tables and charts (MA001, MA003, MA004)

Reporting Business Logic

Consistency rules

  • Same consistency rules as for PortfolioReturns

Path

/instrument/returns

Parameters

startDate

string (date)

The start date the reporting is produced for

endDate

string (date)

The end date the reporting is produced for

instrumentIds

string[]

The list of instruments the return series should be generated

includeDailyReturns

boolean (default: false)

Response to include daily return data (where available)

Example call

/instrument/returns?startDate=2019-01-01&endDate=2019-03-31&instrumentIds=FTSEEUR,SWIIT,SF0003M

Schema

Status
titleon request

Example

Status
titleon request