Skip to content

Commit

Permalink
Added GoalAnalysisConnector. (#31)
Browse files Browse the repository at this point in the history
* Added GoalAnalysisOptions.
* Replaced goal analysis draft with correct implementation.
* Tools: Fixed tests results validation.
* Removed test noise.
* Added goal analysis doc.
* Fixed API escaping and typing.
* Fixed doclets in GoalAnalysisOptions.
  • Loading branch information
bre1470 authored Sep 30, 2024
1 parent a754620 commit f8962d7
Show file tree
Hide file tree
Showing 17 changed files with 854 additions and 81 deletions.
4 changes: 3 additions & 1 deletion docs/connectors/morningstar.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ types.

### Available Connectors

* [RNANews](morningstar/rna-news/regulatory-news-announcements.md)
* [Goal Analysis](morningstar/goal-analysis.md)
* [RNANews](morningstar/regulatory-news-announcements.md)
* [Risk Score](morningstar/risk-score.md)
* [TimeSeries](morningstar/time-series/time-series.md)
* [XRay](morningstar/x-ray.md)
45 changes: 45 additions & 0 deletions docs/connectors/morningstar/goal-analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
Goal Analysis Connector
=======================

The Morningstar Goal Analysis service calculates the probabilities of an
investor meeting their financial goals based on assumptions about markets and
the assets in a portfolio.



How to use Goal Analysis
------------------------

The Goal Analysis Connector provides an easy way to create an analysis to
specific scenarios. The options give control over insights displayed in charts
and dashboards.

In order to fetch the analysis, you can request for example:

```js
const goalAnalysisConnector = MC.GoalAnalysisConnector({
postman: {
environmentJSON: postmanJSON
},
annualInvestment: 4800,
assetClassWeights: [
0.1, 0, 0, 0, 0, 0, 0, 0, 0.08, 0.03, 0, 0, 0.17,
0.05, 0, 0, 0, 0.13, 0.28, 0, 0, 0, 0.11, 0, 0
],
currentSavings: 20000,
includeDetailedInvestmentGrowthGraph: true,
requestProbability: 90,
target: 9000,
timeHorizon: 5
});
```

For more details, see [Morningstar's Goal Analysis API].



<!-- Links -->



[Morningstar's Goal Analysis API]: https://developer.morningstar.com/direct-web-services/documentation/api-reference/portfolio-analysis-apacemea/goal-analysis
File renamed without changes.
2 changes: 1 addition & 1 deletion docs/connectors/morningstar/x-ray.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ You can use the X-Ray Connector to fetch portfolio data points, holding data
points, or benchmark data points. Depending on the request additional breakdown
columns might be added to the table.

In order to fetch a benchmark, you can for example
In order to fetch a benchmark, you can request for example:

```js
const xRayConnector = MC.XRayConnector({
Expand Down
154 changes: 78 additions & 76 deletions src/CLI/Library/APIServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,51 +131,6 @@ const STATIC_PATH = Path.join(__dirname, '..', 'Static');
* */


/**
* Creates or retrieves an option with the given name path.
*
* @param tree
* Tree root to walk on.
*
* @param nodePath
* Node path to retrieve.
*
* @return
* Created or retrieved option.
*/
function treeNode (
tree: Options,
nodePath: string
): Option {
let node: Option = {
doclet: {},
meta: {
fullname: '',
name: ''
},
children: tree
};

let currentName = '';

for (const name of nodePath.split('.')) {
currentName = (currentName ? `${currentName}.${name}` : name);
node = node.children[name] = (
node.children[name] ||
{
doclet: {},
meta: {
fullname: currentName,
name
},
children: {}
}
);
}

return node;
}


function escape (
text: string
Expand Down Expand Up @@ -234,7 +189,7 @@ async function getOption (

if (node) {
option.doclet.description =
await Marked.parse(jsdoc2Markdown(node.description));
await Marked.parse(jsdoc2Markdown(escape(node.description)));

if (node.deprecated) {
option.doclet.deprecated = `${node.deprecated.toFixed(2)}.0`;
Expand All @@ -246,7 +201,7 @@ async function getOption (
(option.doclet as Record<string, string>).default =
node.doclet.default.join(',');
} else {
option.doclet.defaultvalue = escape(node.doclet.default.join(','));
option.doclet.defaultvalue = node.doclet.default.join(',');
}
}
}
Expand All @@ -265,11 +220,11 @@ async function getOption (
root.meta.hasChildren = true;
childOption = treeNode(root.children, child.name);
childOption.doclet.description =
await Marked.parse(jsdoc2Markdown(child.description));
await Marked.parse(jsdoc2Markdown(escape(child.description)));

if (child.doclet.type) {
childOption.doclet.type = {
name: child.doclet.type.map(escape)
name: child.doclet.type
};
}

Expand Down Expand Up @@ -319,33 +274,6 @@ function jsdoc2Markdown (text: string): string {
}


async function toNav (
item: Database.Item
): Promise<Nav> {
const nav: Nav = {};

if (item.description) {
nav.description = await Marked.parse(jsdoc2Markdown(item.description));
}

if (item.meta.file) {
nav.filename = item.meta.file;
}

nav.fullname = item.name;
nav.name = item.name.split('.').pop();

if (item.doclet.type) {
if (item.doclet.default) {
nav.default = item.doclet.default[item.doclet.default.length - 1];
}
nav.typeList = { names: item.doclet.type.map(escape) };
}

return nav;
}


/**
* Response with a 200
*
Expand Down Expand Up @@ -410,6 +338,80 @@ function sanitizePath (path: string): string {
}


async function toNav (
item: Database.Item
): Promise<Nav> {
const nav: Nav = {};

if (item.description) {
nav.description =
await Marked.parse(jsdoc2Markdown(escape(item.description)));
}

if (item.meta.file) {
nav.filename = item.meta.file;
}

nav.fullname = item.name;
nav.name = item.name.split('.').pop();

if (item.doclet.type) {
if (item.doclet.default) {
nav.default = item.doclet.default[item.doclet.default.length - 1];
}
nav.typeList = { names: item.doclet.type };
}

return nav;
}


/**
* Creates or retrieves an option with the given name path.
*
* @param tree
* Tree root to walk on.
*
* @param nodePath
* Node path to retrieve.
*
* @return
* Created or retrieved option.
*/
function treeNode (
tree: Options,
nodePath: string
): Option {
let node: Option = {
doclet: {},
meta: {
fullname: '',
name: ''
},
children: tree
};

let currentName = '';

for (const name of nodePath.split('.')) {
currentName = (currentName ? `${currentName}.${name}` : name);
node = node.children[name] = (
node.children[name] ||
{
doclet: {},
meta: {
fullname: currentName,
name
},
children: {}
}
);
}

return node;
}


/* *
*
* Tasks
Expand Down
Loading

0 comments on commit f8962d7

Please sign in to comment.