@progress/kendo-angular-schematics
Version:
Kendo UI Schematics for Angular
185 lines (167 loc) • 6.17 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
// The following source code is copied from https://github.com/d3fc/d3fc
// The MIT License (MIT)
// Copyright (c) 2015-2019 Scott Logic Ltd.
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
const geometricBrownianMotion = require('./geometricBrownianMotion');
const randomNormal = require('./randomNormal');
const { rebindAll } = require('./d3fc-rebind/rebindAll');
// const { timeDay, timeYear } = require('d3-time');
const { timeDay } = require("./day");
const { timeYear } = require("./year");
const { functor } = require('./fn');
module.exports = function() {
let startDate = new Date();
let startPrice = 100;
let interval = timeDay;
let intervalStep = 1;
let unitInterval = timeYear;
let unitIntervalStep = 1;
let filter = null;
let volume = () => {
const normal = randomNormal(1, 0.1);
return Math.ceil(normal() * 1000);
};
const gbm = geometricBrownianMotion();
const getOffsetPeriod = date => {
const unitMilliseconds = unitInterval.offset(date, unitIntervalStep) - date;
return (interval.offset(date, intervalStep) - date) / unitMilliseconds;
};
const calculateOHLC = (start, price) => {
const period = getOffsetPeriod(start);
const prices = gbm.period(period)(price);
const ohlc = {
date: start,
open: prices[0],
high: Math.max.apply(Math, prices),
low: Math.min.apply(Math, prices),
close: prices[gbm.steps()]
};
ohlc.volume = volume();
return ohlc;
};
const getNextDatum = ohlc => {
let date, price, filtered;
do {
date = ohlc ? interval.offset(ohlc.date, intervalStep) : new Date(startDate.getTime());
price = ohlc ? ohlc.close : startPrice;
ohlc = calculateOHLC(date, price);
filtered = filter && !filter(ohlc);
} while (filtered);
return ohlc;
};
const makeStream = () => {
let latest;
const stream = {};
stream.next = () => {
const ohlc = getNextDatum(latest);
latest = ohlc;
return ohlc;
};
stream.take = numPoints => stream.until((d, i) => !numPoints || numPoints < 0 || i === numPoints);
stream.until = comparison => {
const data = [];
let index = 0;
let ohlc = getNextDatum(latest);
let compared = comparison && !comparison(ohlc, index);
while (compared) {
data.push(ohlc);
latest = ohlc;
ohlc = getNextDatum(latest);
index += 1;
compared = comparison && !comparison(ohlc, index);
}
return data;
};
return stream;
};
const financial = numPoints => makeStream().take(numPoints);
financial.stream = makeStream;
if (typeof Symbol !== 'function' || typeof Symbol.iterator !== 'symbol') {
throw new Error('d3fc-random-data depends on Symbol. Make sure that you load a polyfill in older browsers. See README.');
}
financial[Symbol.iterator] = () => {
const stream = makeStream();
return {
next: () => ({
value: stream.next(),
done: false
})
};
};
financial.startDate = (...args) => {
if (!args.length) {
return startDate;
}
startDate = args[0];
return financial;
};
financial.startPrice = (...args) => {
if (!args.length) {
return startPrice;
}
startPrice = args[0];
return financial;
};
financial.interval = (...args) => {
if (!args.length) {
return interval;
}
interval = args[0];
return financial;
};
financial.intervalStep = (...args) => {
if (!args.length) {
return intervalStep;
}
intervalStep = args[0];
return financial;
};
financial.unitInterval = (...args) => {
if (!args.length) {
return unitInterval;
}
unitInterval = args[0];
return financial;
};
financial.unitIntervalStep = (...args) => {
if (!args.length) {
return unitIntervalStep;
}
unitIntervalStep = args[0];
return financial;
};
financial.filter = (...args) => {
if (!args.length) {
return filter;
}
filter = args[0];
return financial;
};
financial.volume = (...args) => {
if (!args.length) {
return volume;
}
volume = functor(args[0]);
return financial;
};
rebindAll(financial, gbm);
return financial;
}