@thi.ng/transducers-stats 2.1.136 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2024-10-05T12:12:32Z
3
+ - **Last updated**: 2024-11-03T16:41:34Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,17 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ ## [2.2.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/transducers-stats@2.2.0) (2024-11-03)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add moving min/max, update donchian ([188d11a](https://github.com/thi-ng/umbrella/commit/188d11a))
17
+ - add movingMaximum() transducer
18
+ - add movingMinimum() transducer
19
+ - refactor donchian()
20
+ - add internal Deque helper class
21
+ - add tests
22
+
12
23
  ### [2.1.113](https://github.com/thi-ng/umbrella/tree/@thi.ng/transducers-stats@2.1.113) (2024-04-08)
13
24
 
14
25
  #### ♻️ Refactoring
package/README.md CHANGED
@@ -49,6 +49,8 @@ transforming ES6 iterator (generator) instead of a transducer.
49
49
  - [HMA (Hull Moving Average)](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers-stats/src/hma.ts)
50
50
  - [MACD (Moving Average Convergence/Divergence)](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers-stats/src/macd.ts)
51
51
  - [Momentum](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers-stats/src/momentum.ts)
52
+ - [Moving Maximum](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers-stats/src/moving-maximum.ts)
53
+ - [Moving Minimum](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers-stats/src/moving-minimum.ts)
52
54
  - [ROC (Rate of change)](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers-stats/src/roc.ts)
53
55
  - [RSI (Relative Strength Index)](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers-stats/src/rsi.ts)
54
56
  - [SD (Standard Deviation)](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers-stats/src/sd.ts)
@@ -89,15 +91,18 @@ For Node.js REPL:
89
91
  const ts = await import("@thi.ng/transducers-stats");
90
92
  ```
91
93
 
92
- Package sizes (brotli'd, pre-treeshake): ESM: 1.39 KB
94
+ Package sizes (brotli'd, pre-treeshake): ESM: 1.75 KB
93
95
 
94
96
  ## Dependencies
95
97
 
98
+ - [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/develop/packages/api)
96
99
  - [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/develop/packages/checks)
97
100
  - [@thi.ng/dcons](https://github.com/thi-ng/umbrella/tree/develop/packages/dcons)
98
101
  - [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/develop/packages/errors)
99
102
  - [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers)
100
103
 
104
+ Note: @thi.ng/api is in _most_ cases a type-only import (not used at runtime)
105
+
101
106
  ## Usage examples
102
107
 
103
108
  Three projects in this repo's
package/deque.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import type { Predicate2 } from "@thi.ng/api";
2
+ /** @internal */
3
+ export declare class Deque {
4
+ samples: number[];
5
+ pred: Predicate2<number>;
6
+ index: number[];
7
+ constructor(samples: number[], pred: Predicate2<number>);
8
+ head(): number;
9
+ add(x: number): void;
10
+ shift(): void;
11
+ }
12
+ //# sourceMappingURL=deque.d.ts.map
package/deque.js ADDED
@@ -0,0 +1,25 @@
1
+ class Deque {
2
+ constructor(samples, pred) {
3
+ this.samples = samples;
4
+ this.pred = pred;
5
+ }
6
+ index = [];
7
+ head() {
8
+ return this.samples[this.index[0]];
9
+ }
10
+ add(x) {
11
+ const { index, samples, pred } = this;
12
+ while (index.length && pred(samples[index[index.length - 1]], x)) {
13
+ index.pop();
14
+ }
15
+ index.push(samples.length - 1);
16
+ }
17
+ shift() {
18
+ const { index } = this;
19
+ if (index[0] === 0) index.shift();
20
+ for (let i = 0; i < index.length; i++) index[i]--;
21
+ }
22
+ }
23
+ export {
24
+ Deque
25
+ };
package/donchian.js CHANGED
@@ -1,10 +1,23 @@
1
- import { comp } from "@thi.ng/transducers/comp";
2
- import { iterator } from "@thi.ng/transducers/iterator";
3
- import { map } from "@thi.ng/transducers/map";
4
- import { partition } from "@thi.ng/transducers/partition";
5
- import { bounds } from "./bounds.js";
1
+ import { compR } from "@thi.ng/transducers/compr";
2
+ import { iterator1 } from "@thi.ng/transducers/iterator";
3
+ import { Deque } from "./deque.js";
6
4
  function donchian(period, src) {
7
- return src ? iterator(donchian(period), src) : comp(partition(period, 1), map(bounds));
5
+ return src ? iterator1(donchian(period), src) : (rfn) => {
6
+ const samples = [];
7
+ const minDeque = new Deque(samples, (a, b) => a >= b);
8
+ const maxDeque = new Deque(samples, (a, b) => a <= b);
9
+ return compR(rfn, (acc, x) => {
10
+ const num = samples.push(x);
11
+ minDeque.add(x);
12
+ maxDeque.add(x);
13
+ if (num > period) {
14
+ samples.shift();
15
+ minDeque.shift();
16
+ maxDeque.shift();
17
+ }
18
+ return num >= period ? rfn[2](acc, [minDeque.head(), maxDeque.head()]) : acc;
19
+ });
20
+ };
8
21
  }
9
22
  export {
10
23
  donchian
package/index.d.ts CHANGED
@@ -4,6 +4,8 @@ export * from "./ema.js";
4
4
  export * from "./hma.js";
5
5
  export * from "./macd.js";
6
6
  export * from "./momentum.js";
7
+ export * from "./moving-maximum.js";
8
+ export * from "./moving-minimum.js";
7
9
  export * from "./roc.js";
8
10
  export * from "./rsi.js";
9
11
  export * from "./sd.js";
@@ -12,6 +14,7 @@ export * from "./stochastic.js";
12
14
  export * from "./trix.js";
13
15
  export * from "./wma.js";
14
16
  export * from "./bounds.js";
17
+ export * from "./deque.js";
15
18
  export * from "./dot.js";
16
19
  export * from "./mse.js";
17
20
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -4,6 +4,8 @@ export * from "./ema.js";
4
4
  export * from "./hma.js";
5
5
  export * from "./macd.js";
6
6
  export * from "./momentum.js";
7
+ export * from "./moving-maximum.js";
8
+ export * from "./moving-minimum.js";
7
9
  export * from "./roc.js";
8
10
  export * from "./rsi.js";
9
11
  export * from "./sd.js";
@@ -12,5 +14,6 @@ export * from "./stochastic.js";
12
14
  export * from "./trix.js";
13
15
  export * from "./wma.js";
14
16
  export * from "./bounds.js";
17
+ export * from "./deque.js";
15
18
  export * from "./dot.js";
16
19
  export * from "./mse.js";
@@ -0,0 +1,4 @@
1
+ import type { Transducer } from "@thi.ng/transducers";
2
+ export declare function movingMaximum(period: number): Transducer<number, number>;
3
+ export declare function movingMaximum(period: number, src: Iterable<number>): IterableIterator<number>;
4
+ //# sourceMappingURL=moving-maximum.d.ts.map
@@ -0,0 +1,21 @@
1
+ import { compR } from "@thi.ng/transducers/compr";
2
+ import { iterator1 } from "@thi.ng/transducers/iterator";
3
+ import { Deque } from "./deque.js";
4
+ function movingMaximum(period, src) {
5
+ return src ? iterator1(movingMaximum(period), src) : (rfn) => {
6
+ const samples = [];
7
+ const deque = new Deque(samples, (a, b) => a <= b);
8
+ return compR(rfn, (acc, x) => {
9
+ const num = samples.push(x);
10
+ deque.add(x);
11
+ if (num > period) {
12
+ samples.shift();
13
+ deque.shift();
14
+ }
15
+ return num >= period ? rfn[2](acc, deque.head()) : acc;
16
+ });
17
+ };
18
+ }
19
+ export {
20
+ movingMaximum
21
+ };
@@ -0,0 +1,4 @@
1
+ import type { Transducer } from "@thi.ng/transducers";
2
+ export declare function movingMinimum(period: number): Transducer<number, number>;
3
+ export declare function movingMinimum(period: number, src: Iterable<number>): IterableIterator<number>;
4
+ //# sourceMappingURL=moving-minimum.d.ts.map
@@ -0,0 +1,21 @@
1
+ import { compR } from "@thi.ng/transducers/compr";
2
+ import { iterator1 } from "@thi.ng/transducers/iterator";
3
+ import { Deque } from "./deque.js";
4
+ function movingMinimum(period, src) {
5
+ return src ? iterator1(movingMinimum(period), src) : (rfn) => {
6
+ const samples = [];
7
+ const deque = new Deque(samples, (a, b) => a >= b);
8
+ return compR(rfn, (acc, x) => {
9
+ const num = samples.push(x);
10
+ deque.add(x);
11
+ if (num > period) {
12
+ samples.shift();
13
+ deque.shift();
14
+ }
15
+ return num >= period ? rfn[2](acc, deque.head()) : acc;
16
+ });
17
+ };
18
+ }
19
+ export {
20
+ movingMinimum
21
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/transducers-stats",
3
- "version": "2.1.136",
3
+ "version": "2.2.0",
4
4
  "description": "Transducers for statistical / technical analysis",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -36,6 +36,7 @@
36
36
  "tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
37
37
  },
38
38
  "dependencies": {
39
+ "@thi.ng/api": "^8.11.11",
39
40
  "@thi.ng/checks": "^3.6.13",
40
41
  "@thi.ng/dcons": "^3.2.131",
41
42
  "@thi.ng/errors": "^2.5.17",
@@ -84,6 +85,9 @@
84
85
  "./bounds": {
85
86
  "default": "./bounds.js"
86
87
  },
88
+ "./deque": {
89
+ "default": "./deque.js"
90
+ },
87
91
  "./donchian": {
88
92
  "default": "./donchian.js"
89
93
  },
@@ -102,6 +106,12 @@
102
106
  "./momentum": {
103
107
  "default": "./momentum.js"
104
108
  },
109
+ "./moving-maximum": {
110
+ "default": "./moving-maximum.js"
111
+ },
112
+ "./moving-minimum": {
113
+ "default": "./moving-minimum.js"
114
+ },
105
115
  "./mse": {
106
116
  "default": "./mse.js"
107
117
  },
@@ -131,5 +141,5 @@
131
141
  "parent": "@thi.ng/transducers",
132
142
  "year": 2017
133
143
  },
134
- "gitHead": "8301254c4436505a1fb0e3cc28eca3adb920c3e0\n"
144
+ "gitHead": "1148f3130b867c65141957b4b7617021d7ac7fc9\n"
135
145
  }