Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…ngstar into feature/implement-risk-score
  • Loading branch information
Eskils committed Sep 20, 2024
2 parents cdef3ec + 3c39ead commit bca680f
Show file tree
Hide file tree
Showing 42 changed files with 1,489 additions and 171 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,5 @@ jobs:
- name: Build webpack bundles
run: npm run webpack

- name: Run unit-tests
run: npx ts-node test/unit-tests/runtime
- name: Run tests
run: npm run test:tests
3 changes: 2 additions & 1 deletion demos/dashboards-rna-news/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
<link rel="stylesheet" href="demo.css" />
<script src="https://code.highcharts.com/dashboards/datagrid.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="../../code/connectors-morningstar.src.js"></script>
<script src="https://code.highcharts.com/dashboards/dashboards.js"></script>
<script src="https://code.highcharts.com/connectors/morningstar/connectors-morningstar.src.js"></script>
<title>Highcharts Dashboards + Morningstar RNA News</title>
</head>
<body>
Expand Down
2 changes: 1 addition & 1 deletion demos/stock-ohlcv/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />
<script src="https://code.highcharts.com/stock/highstock.src.js"></script>
<script src="../../code/connectors-morningstar.src.js"></script>
<script src="https://code.highcharts.com/connectors/morningstar/connectors-morningstar.src.js"></script>
<title>Highcharts Stock + Morningstar OHLCV TimeSeries</title>
<style>
body {
Expand Down
2 changes: 1 addition & 1 deletion demos/stock-timeseries/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />
<script src="https://code.highcharts.com/stock/highstock.src.js"></script>
<script src="../../code/connectors-morningstar.src.js"></script>
<script src="https://code.highcharts.com/connectors/morningstar/connectors-morningstar.src.js"></script>
<title>Highcharts Stock + Morningstar TimeSeries</title>
<style>
body {
Expand Down
7 changes: 7 additions & 0 deletions docs/connectors/morningstar.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,10 @@ For Highcharts Dashboards you just need to load the `connectors-morningstar`
bundle, which will register all connectors to the Dashboards registry. All
Morningstar connectors are then available in the data pool as other connector
types.



### Available Connectors

* [RNANews](morningstar/rna-news/regulatory-news-announcements.md)
* [TimeSeries](morningstar/time-series/time-series.md)
1 change: 1 addition & 0 deletions docs/connectors/morningstar/time-series/time-series.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ period.
- [Cumulative Return](cumulative-return.md)
- [Dividend](dividend.md)
- [Growth](growth.md)
- [OHLCV](ohlcv.md)
- [Price](price.md)
- [Regulatory News Announcements](../rna-news/regulatory-news-announcements.md)

Expand Down
53 changes: 53 additions & 0 deletions docs/connectors/morningstar/x-ray.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
X-Ray Connector
===============

The Morningstar X-Ray capability enables you to quickly analyze a portfolio's
holdings. You define the portfolio individually in the connector options.

The X-Ray Connector aggregates individual holdings data with the help of the
Morningstar API. Data returned by the Highcharts Connector shows how a portfolio
is diversified by region, sector, and investment style.



How to use X-Ray
----------------

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

```js
const xRayConnector = MC.XRayConnector({
postman: {
environmentJSON: postmanJSON
},
dataPoints: {
type: 'benchmark',
dataPoints: [
'HistoricalPerformanceSeries',
['PerformanceReturn', 'M0', 'M1', 'M2', 'M3', 'M6', 'M12'],
'ShowBreakdown'
]
},
holdings: [
{
id: 'GB00BWDBJF10',
idType: 'ISIN',
weight: 100
}
]
});
```

For more details, see [Morningstar's X-Ray API].



<!-- Links -->



[Morningstar's X-Ray API]: https://developer.morningstar.com/direct-web-services/documentation/api-reference/portfolio-analysis-apacemea/x-ray
5 changes: 4 additions & 1 deletion package-build.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"private": true,
"version": "0.4.1",
"version": "0.5.0",
"name": "@highcharts/connectors-morningstar",
"license": "UNLICENSED",
"description": "Highcharts connectors for Morningstar Direct Web Services",
Expand All @@ -27,6 +27,9 @@
"Morningstar",
"Time Series"
],
"dependencies": {
"marked": "^14.1.2"
},
"optionalDependencies": {
"@highcharts/dashboards": ">=2.3.0"
}
Expand Down
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"husky": "^9.1.2",
"jsdom": "^24.1.1",
"lint-staged": "^15.2.7",
"marked": "^14.1.2",
"ts-node": "^10.9.2",
"typescript": "~5.5.4",
"webpack": "^5.94.0",
Expand All @@ -43,22 +44,24 @@
"scripts": {
"build": "npm run webpack && npm run build:prepare && npm run build:copy && npm run build:pack && npm run build:cleanup",
"build:cleanup": "rm -rf build/package/",
"build:copy": "cp -R bin code/* demos docs LICENSE.md README.md build/package/ && cp package-build.json build/package/package.json",
"build:copy": "cp -R bin code/* demos LICENSE.md README.md build/package/ && cp -R docs/connectors/ build/package/docs/ && cp package-build.json build/package/package.json",
"build:pack": "npm pack build/package/ --pack-destination build/",
"build:prepare": "rm -rf build/ ; mkdir -p build/package/",
"demos": "npm run webpack && npm run demos:server",
"demos:server": "(sleep 1 ; open http://localhost:8080) & node bin/connectors-morningstar demos",
"docs": "npm run webpack && npm run docs:server",
"docs:server": "(sleep 1 ; open http://localhost:8000) & node bin/connectors-morningstar docs",
"dryrun": "ts-node tools/dist --dryrun",
"husky:pre-commit": "npx lint-staged && npm run webpack",
"prepare": "rm -rf '.husky/_' ; husky",
"scripts": "npm run scripts:bin && npm run scripts:code",
"scripts:bin": "rm -rf bin/ ; tsc -p src/CLI/ ; chmod +x bin/*.js",
"scripts:code": "rm -rf code/ ; tsc -p src/",
"reset": "rm -rf bin/ build/ code/ node_modules/ ; npm i",
"test": "npm run webpack && npm run test:eslint && npm run test:unit-tests",
"test": "npm run webpack && npm run test:eslint && npm run test:tests",
"test:eslint": "eslint .",
"test:morningstar": "npx -y newman run --bail tmp/Collection.json -e tmp/Environment.json",
"test:unit-tests": "ts-node test/unit-tests/runtime",
"test:tests": "ts-node tools/tests",
"watch": "tsc -p src/ -w",
"webpack": "npm run scripts && webpack && npm run webpack:dts",
"webpack:dts": "npm run webpack:dts:cm && npm run webpack:dts:dbm && npm run webpack:dts:dgm && npm run webpack:dts:hcm",
Expand Down
113 changes: 90 additions & 23 deletions src/CLI/Library/Server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import * as FS from 'node:fs';
import * as HTTP from 'node:http';
import * as Marked from 'marked';
import * as Path from 'node:path';


Expand All @@ -41,17 +42,22 @@ export const DEFAULT_PORT = 8080;


export const MIMES: Record<string, string> = {
css: 'text/css',
css: 'text/css; charset=utf-8',
eot: 'application/vnd.ms-fontobject',
gif: 'image/gif',
html: 'text/html; charset=utf-8',
ico: 'image/x-icon',
jpeg: 'image/jpeg',
jpg: 'image/jpeg',
js: 'application/javascript',
json: 'application/json',
html: 'text/html',
ico: 'image/x-icon',
map: 'application/json',
markdown: 'text/markdown',
md: 'text/markdown; charset=utf-8',
png: 'image/png',
svg: 'image/svg+xml',
ttf: 'font/ttf',
txt: 'text/plain',
txt: 'text/plain; charset=utf-8',
woff: 'font/woff',
woff2: 'font/woff2',
xml: 'application/xml'
Expand Down Expand Up @@ -88,6 +94,22 @@ function sanitizePath (path: string) {
}


/**
* Removes all non-word characters and capitalize the first character.
*
* @param text
* Text to capitalize.
*
* @return
* Capitalized text.
*/
function capitalize (text: string) {
return text
.replace(/\W/gu, ' ')
.replace(/\b\w/gu, (match) => match.toUpperCase());
}


/* *
*
* Class
Expand All @@ -106,10 +128,17 @@ export class Server {


public constructor (
folder: string = process.cwd()
folder: string = process.cwd(),
defaultFile: string = 'index.html',
baseTitle: string = ''
) {
this.baseTitle = baseTitle;
this.defaultFile = defaultFile;
this.folder = folder;
this.http = new HTTP.Server((req, res) => this.handle(req, res));
this.http = new HTTP.Server((req, res) => {
// eslint-disable-next-line no-console
this.handle(req, res).catch(console.error);
});
}


Expand All @@ -120,6 +149,12 @@ export class Server {
* */


public baseTitle: string;


public defaultFile: string;


public folder: string;


Expand All @@ -142,12 +177,12 @@ export class Server {
* @param response
* Outgoing HTTP message.
*/
public handle (
public async handle (
request: HTTP.IncomingMessage,
response: HTTP.ServerResponse<HTTP.IncomingMessage>
): void {
): Promise<void> {
let folder = this.folder;
let path = sanitizePath(request.url || '/index.html');
let path = sanitizePath(request.url || '/' + this.defaultFile);

if (path.startsWith('/code/')) {
if (folder.includes('node_modules')) {
Expand All @@ -163,7 +198,7 @@ export class Server {
let file = Path.posix.basename(path);

if (path.endsWith('/')) {
file = 'index.html';
file = this.defaultFile;
} else {
file = Path.posix.basename(path);
path = Path.posix.dirname(path) + '/';
Expand All @@ -184,20 +219,51 @@ export class Server {
filePath = filePath.substring(1);
}

FS.readFile(
filePath,
(error, data) => {
if (error) {
// eslint-disable-next-line no-console
console.error(error.message);
response.writeHead(404);
response.end('404: Path not found', 'utf-8');
} else {
response.writeHead(200, { 'Content-Type': MIMES[ext] });
response.end(data);
}
try {
let fileBuffer = FS.readFileSync(filePath);

if (['', 'markdown', 'md'].includes(ext)) {
const title = capitalize(file.substring(0, file.length - ext.length - 1));
fileBuffer = Buffer.from([
'<!DOCTYPE html>',
'<html><head>',
'<meta charset="UTF-8" />',
`<title>${title}${this.baseTitle}</title>`,
'</head><body>',
await Marked.marked(fileBuffer.toString('utf8')),
'</body></html>'
].join('\n'));
ext = 'html';
}

if (['html', 'js'].includes(ext)) {
fileBuffer = Buffer.from(
fileBuffer
.toString('utf8')
.replace(
/https:\/\/code\.highcharts\.com\/connectors\/morningstar\//u,
'/code/'
)
);
}

response.writeHead(200, {
'Access-Control-Allow-Origin': '*',
'Content-Type': MIMES[ext]
});
response.end(fileBuffer);

} catch (error) {

if (error instanceof Error) {
// eslint-disable-next-line no-console
console.error(error.message);
}
);

response.writeHead(404);
response.end('404: Path not found', 'utf-8');

}

}

Expand All @@ -220,6 +286,7 @@ export class Server {
): Server {

this.folder = (folder || this.folder);

this.http.listen(port);

return this;
Expand Down
Loading

0 comments on commit bca680f

Please sign in to comment.