@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 +12 -1
- package/README.md +6 -1
- package/deque.d.ts +12 -0
- package/deque.js +25 -0
- package/donchian.js +19 -6
- package/index.d.ts +3 -0
- package/index.js +3 -0
- package/moving-maximum.d.ts +4 -0
- package/moving-maximum.js +21 -0
- package/moving-minimum.d.ts +4 -0
- package/moving-minimum.js +21 -0
- package/package.json +12 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2024-
|
|
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.
|
|
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 {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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 ?
|
|
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.
|
|
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": "
|
|
144
|
+
"gitHead": "1148f3130b867c65141957b4b7617021d7ac7fc9\n"
|
|
135
145
|
}
|