From 97a9db3644ea996d938b83a857fc125b292abeeb Mon Sep 17 00:00:00 2001 From: Benny Neugebauer Date: Mon, 13 Jan 2025 14:43:13 +0100 Subject: [PATCH] refactor!: Remove "getFixedArray" --- src/BBANDS/BollingerBands.ts | 1 - src/CCI/CCI.ts | 21 ++++++++++++-------- src/CG/CG.ts | 1 - src/MACD/MACD.ts | 1 - src/MAD/MAD.ts | 1 - src/MOM/MOM.ts | 13 +++++++++--- src/ROC/ROC.ts | 1 - src/RSI/RSI.ts | 1 - src/SMA/SMA.ts | 1 - src/STOCH/StochasticOscillator.ts | 1 - src/WMA/WMA.ts | 1 - src/util/Period.ts | 13 +++++++++--- src/util/getFixedArray.test.ts | 33 ------------------------------- src/util/getFixedArray.ts | 17 ---------------- src/util/index.ts | 1 - 15 files changed, 33 insertions(+), 74 deletions(-) delete mode 100644 src/util/getFixedArray.test.ts delete mode 100644 src/util/getFixedArray.ts diff --git a/src/BBANDS/BollingerBands.ts b/src/BBANDS/BollingerBands.ts index 1fdc4eacf..2ece85f9e 100644 --- a/src/BBANDS/BollingerBands.ts +++ b/src/BBANDS/BollingerBands.ts @@ -21,7 +21,6 @@ import {getFasterAverage, getFasterStandardDeviation, getStandardDeviation, push * @see https://www.investopedia.com/terms/b/bollingerbands.asp */ export class BollingerBands extends TechnicalIndicator { - // TODO: Use "getFixedArray" public readonly prices: Big[] = []; /** diff --git a/src/CCI/CCI.ts b/src/CCI/CCI.ts index 69153e121..c6ce8fda5 100644 --- a/src/CCI/CCI.ts +++ b/src/CCI/CCI.ts @@ -1,9 +1,8 @@ +import Big from 'big.js'; import {BigIndicatorSeries, NumberIndicatorSeries} from '../Indicator.js'; -import {getFixedArray, pushUpdate, type HighLowClose, type HighLowCloseNumber} from '../util/index.js'; -import {FasterSMA, SMA} from '../SMA/SMA.js'; import {FasterMAD, MAD} from '../MAD/MAD.js'; -import type {BigSource} from 'big.js'; -import Big from 'big.js'; +import {FasterSMA, SMA} from '../SMA/SMA.js'; +import {pushUpdate, type HighLowClose, type HighLowCloseNumber} from '../util/index.js'; /** * Commodity Channel Index (CCI) @@ -30,20 +29,23 @@ import Big from 'big.js'; * @see https://en.wikipedia.org/wiki/Commodity_channel_index */ export class CCI extends BigIndicatorSeries { - public readonly prices: BigSource[] = []; private readonly sma: SMA; private readonly typicalPrices: Big[]; constructor(public readonly interval: number) { super(); this.sma = new SMA(this.interval); - this.typicalPrices = getFixedArray(interval); + this.typicalPrices = []; } update(candle: HighLowClose, replace: boolean) { const typicalPrice = this.cacheTypicalPrice(candle, replace); this.sma.update(typicalPrice, replace); + if (this.typicalPrices.length > this.interval) { + this.typicalPrices.shift(); + } + if (this.sma.isStable) { const mean = this.sma.getResultOrThrow(); const meanDeviation = MAD.getResultFromBatch(this.typicalPrices, mean); @@ -63,20 +65,23 @@ export class CCI extends BigIndicatorSeries { } export class FasterCCI extends NumberIndicatorSeries { - public readonly prices: number[] = []; private readonly sma: FasterSMA; private readonly typicalPrices: number[]; constructor(public readonly interval: number) { super(); this.sma = new FasterSMA(this.interval); - this.typicalPrices = getFixedArray(interval); + this.typicalPrices = []; } update(candle: HighLowCloseNumber, replace: boolean) { const typicalPrice = this.cacheTypicalPrice(candle, replace); this.sma.update(typicalPrice, replace); + if (this.typicalPrices.length > this.interval) { + this.typicalPrices.shift(); + } + if (this.sma.isStable) { const mean = this.sma.getResultOrThrow(); const meanDeviation = FasterMAD.getResultFromBatch(this.typicalPrices, mean); diff --git a/src/CG/CG.ts b/src/CG/CG.ts index 8a465068a..5eeb07ad4 100644 --- a/src/CG/CG.ts +++ b/src/CG/CG.ts @@ -19,7 +19,6 @@ import {pushUpdate} from '../util/pushUpdate.js'; */ export class CG extends BigIndicatorSeries { public signal: SMA; - // TODO: Use "getFixedArray" public readonly prices: Big[] = []; override get isStable(): boolean { diff --git a/src/MACD/MACD.ts b/src/MACD/MACD.ts index 841447e86..d12ed5542 100644 --- a/src/MACD/MACD.ts +++ b/src/MACD/MACD.ts @@ -34,7 +34,6 @@ export type FasterMACDResult = { * @see https://www.investopedia.com/terms/m/macd.asp */ export class MACD extends TechnicalIndicator { - // TODO: Use "getFixedArray" public readonly prices: BigSource[] = []; public readonly long: EMA | DEMA; public readonly short: EMA | DEMA; diff --git a/src/MAD/MAD.ts b/src/MAD/MAD.ts index 81c6b1d94..54c84f030 100644 --- a/src/MAD/MAD.ts +++ b/src/MAD/MAD.ts @@ -13,7 +13,6 @@ import {getAverage, getFasterAverage, pushUpdate} from '../util/index.js'; * @see https://en.wikipedia.org/wiki/Average_absolute_deviation */ export class MAD extends BigIndicatorSeries { - // TODO: Use "getFixedArray" public readonly prices: BigSource[] = []; constructor(public readonly interval: number) { diff --git a/src/MOM/MOM.ts b/src/MOM/MOM.ts index 2c9d9ff39..02c0cd87b 100644 --- a/src/MOM/MOM.ts +++ b/src/MOM/MOM.ts @@ -1,7 +1,6 @@ import type {BigSource} from 'big.js'; import Big from 'big.js'; import {BigIndicatorSeries, NumberIndicatorSeries} from '../Indicator.js'; -import {getFixedArray} from '../util/getFixedArray.js'; import {pushUpdate} from '../util/pushUpdate.js'; /** @@ -20,12 +19,16 @@ export class MOM extends BigIndicatorSeries { constructor(public readonly interval: number) { super(); this.historyLength = interval + 1; - this.history = getFixedArray(this.historyLength); + this.history = []; } update(value: BigSource, replace: boolean) { pushUpdate(this.history, replace, value); + if (this.history.length > this.historyLength) { + this.history.shift(); + } + if (this.history.length === this.historyLength) { return this.setResult(new Big(value).minus(this.history[0]), replace); } @@ -41,12 +44,16 @@ export class FasterMOM extends NumberIndicatorSeries { constructor(public readonly interval: number) { super(); this.historyLength = interval + 1; - this.history = getFixedArray(this.historyLength); + this.history = []; } update(value: number, replace: boolean) { pushUpdate(this.history, replace, value); + if (this.history.length > this.historyLength) { + this.history.shift(); + } + if (this.history.length === this.historyLength) { return this.setResult(value - this.history[0], replace); } diff --git a/src/ROC/ROC.ts b/src/ROC/ROC.ts index d949f0daa..78e3355b4 100644 --- a/src/ROC/ROC.ts +++ b/src/ROC/ROC.ts @@ -13,7 +13,6 @@ import {pushUpdate} from '../util/pushUpdate.js'; * @see https://www.investopedia.com/terms/r/rateofchange.asp */ export class ROC extends BigIndicatorSeries { - // TODO: Use "getFixedArray" public readonly prices: Big[] = []; constructor(public readonly interval: number) { diff --git a/src/RSI/RSI.ts b/src/RSI/RSI.ts index 5045d9069..7c71ec43a 100644 --- a/src/RSI/RSI.ts +++ b/src/RSI/RSI.ts @@ -24,7 +24,6 @@ import {pushUpdate} from '../util/pushUpdate.js'; * @see https://www.investopedia.com/terms/r/rsi.asp */ export class RSI extends BigIndicatorSeries { - // TODO: Use "getFixedArray" private readonly previousPrices: BigSource[] = []; private readonly avgGain: MovingAverage; private readonly avgLoss: MovingAverage; diff --git a/src/SMA/SMA.ts b/src/SMA/SMA.ts index f23b2f23c..1a16be30c 100644 --- a/src/SMA/SMA.ts +++ b/src/SMA/SMA.ts @@ -13,7 +13,6 @@ import Big from 'big.js'; * @see https://www.investopedia.com/terms/s/sma.asp */ export class SMA extends MovingAverage { - // TODO: Use "getFixedArray" public readonly prices: BigSource[] = []; update(price: BigSource, replace: boolean) { diff --git a/src/STOCH/StochasticOscillator.ts b/src/STOCH/StochasticOscillator.ts index effe41399..b1d5c761d 100644 --- a/src/STOCH/StochasticOscillator.ts +++ b/src/STOCH/StochasticOscillator.ts @@ -40,7 +40,6 @@ export interface FasterStochasticResult { export class StochasticOscillator extends TechnicalIndicator { private readonly periodM: SMA; private readonly periodP: SMA; - // TODO: Use "getFixedArray" private readonly candles: HighLowClose[] = []; /** diff --git a/src/WMA/WMA.ts b/src/WMA/WMA.ts index 381ce393b..ed128738b 100644 --- a/src/WMA/WMA.ts +++ b/src/WMA/WMA.ts @@ -13,7 +13,6 @@ import {pushUpdate} from '../util/pushUpdate.js'; * @see https://corporatefinanceinstitute.com/resources/career-map/sell-side/capital-markets/weighted-moving-average-wma/ */ export class WMA extends MovingAverage { - // TODO: Use "getFixedArray" public readonly prices: BigSource[] = []; constructor(public override readonly interval: number) { diff --git a/src/util/Period.ts b/src/util/Period.ts index 079c2ead3..5f546258a 100644 --- a/src/util/Period.ts +++ b/src/util/Period.ts @@ -1,7 +1,6 @@ import type {BigSource} from 'big.js'; import Big from 'big.js'; import {TechnicalIndicator} from '../Indicator.js'; -import {getFixedArray} from './getFixedArray.js'; import {getMaximum} from './getMaximum.js'; import {getMinimum} from './getMinimum.js'; import {pushUpdate} from './pushUpdate.js'; @@ -33,12 +32,16 @@ export class Period extends TechnicalIndicator { constructor(public readonly interval: number) { super(); - this.values = getFixedArray(interval); + this.values = []; } update(value: BigSource, replace: boolean) { pushUpdate(this.values, replace, new Big(value)); + if (this.values.length > this.interval) { + this.values.shift(); + } + if (this.values.length === this.interval) { this._lowest = getMinimum(this.values); this._highest = getMaximum(this.values); @@ -69,12 +72,16 @@ export class FasterPeriod extends TechnicalIndicator constructor(public readonly interval: number) { super(); - this.values = getFixedArray(interval); + this.values = []; } update(value: number, replace: boolean) { pushUpdate(this.values, replace, value); + if (this.values.length > this.interval) { + this.values.shift(); + } + if (this.values.length === this.interval) { this._lowest = Math.min(...this.values); this._highest = Math.max(...this.values); diff --git a/src/util/getFixedArray.test.ts b/src/util/getFixedArray.test.ts deleted file mode 100644 index 271f926b0..000000000 --- a/src/util/getFixedArray.test.ts +++ /dev/null @@ -1,33 +0,0 @@ -import {getFixedArray} from './getFixedArray.js'; - -describe('getFixedArray', () => { - describe('push', () => { - it('removes items from the beginning when the amount of items exceed the maximum length', () => { - const maxLength = 3; - const array = getFixedArray(maxLength); - array.push(1); - expect(array.length).toBe(1); - array.push(2); - expect(array.length).toBe(2); - array.push(3); - expect(array.length).toBe(maxLength); - array.push(4); - expect(array.length).toBe(maxLength); - array.push(5); - expect(array.length).toBe(maxLength); - expect(array[0]).toBe(3); - expect(array[1]).toBe(4); - expect(array[2]).toBe(5); - }); - - it('works when pushing multiple items at once', () => { - const maxLength = 3; - const array = getFixedArray(maxLength); - array.push(1, 2, 3, 4, 5); - expect(array.length).toBe(maxLength); - expect(array[0]).toBe(3); - expect(array[1]).toBe(4); - expect(array[2]).toBe(5); - }); - }); -}); diff --git a/src/util/getFixedArray.ts b/src/util/getFixedArray.ts deleted file mode 100644 index c3040831d..000000000 --- a/src/util/getFixedArray.ts +++ /dev/null @@ -1,17 +0,0 @@ -export function getFixedArray(length: number): T[] { - const array = new Array(); - - array.push = function (...items: T[]): number { - if (items.length >= length) { - items.splice(0, items.length - length); - } - - if (this.length >= length) { - this.shift(); - } - - return Array.prototype.push.apply(this, items); - }; - - return array; -} diff --git a/src/util/index.ts b/src/util/index.ts index 003f964ff..c36bc2bf3 100644 --- a/src/util/index.ts +++ b/src/util/index.ts @@ -1,6 +1,5 @@ export * from './BandsResult.js'; export * from './getAverage.js'; -export * from './getFixedArray.js'; export * from './getLastFromForEach.js'; export * from './getMaximum.js'; export * from './getMinimum.js';