@ch20026103/anysis 0.0.19-beta → 0.0.20-alpha.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/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +5 -1
- package/dist/cjs/stockSkills/cmf.d.ts +11 -0
- package/dist/cjs/stockSkills/cmf.js +90 -0
- package/dist/cjs/stockSkills/cmf.test.d.ts +1 -0
- package/dist/cjs/stockSkills/cmf.test.js +77 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/stockSkills/cmf.d.ts +11 -0
- package/dist/esm/stockSkills/cmf.js +88 -0
- package/dist/esm/stockSkills/cmf.test.d.ts +1 -0
- package/dist/esm/stockSkills/cmf.test.js +75 -0
- package/dist/umd/index.js +348 -57
- package/package.json +1 -1
package/dist/cjs/index.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export { default as Williams } from "./stockSkills/williams.js";
|
|
|
21
21
|
export { default as ObvEma } from "./stockSkills/obv_ema.js";
|
|
22
22
|
export { default as Mfi } from "./stockSkills/mfi.js";
|
|
23
23
|
export { default as Ichimoku } from "./stockSkills/ichimoku.js";
|
|
24
|
+
export { default as Dmi } from "./stockSkills/dmi.js";
|
|
25
|
+
export { default as Cmf } from "./stockSkills/cmf.js";
|
|
24
26
|
export { add } from "./test/add.js";
|
|
25
27
|
export { minus } from "./test/minus.js";
|
|
26
28
|
export { default as calculateDivisionFactor } from "./utils/calculateDivisionFactor.js";
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseLsusbOutput = exports.isJSON = exports.calculateDivisionFactor = exports.minus = exports.add = exports.Ichimoku = exports.Mfi = exports.ObvEma = exports.Williams = exports.Vma = exports.Week = exports.dateFormat = exports.Rsi = exports.Obv = exports.Macd = exports.Ma = exports.Kd = exports.Gold = exports.Ema = exports.Boll = exports.calcSeasonalIndicesNoTrend = exports.weightMovingAverages = exports.movingAverages = exports.exponentialSmoothing = exports.findTroughByGradient = exports.findPeaksByGradient = exports.SwingExtremesType = exports.SwingExtremes = exports.slope = exports.simpleRegressionModel = exports.Angle = void 0;
|
|
3
|
+
exports.parseLsusbOutput = exports.isJSON = exports.calculateDivisionFactor = exports.minus = exports.add = exports.Cmf = exports.Dmi = exports.Ichimoku = exports.Mfi = exports.ObvEma = exports.Williams = exports.Vma = exports.Week = exports.dateFormat = exports.Rsi = exports.Obv = exports.Macd = exports.Ma = exports.Kd = exports.Gold = exports.Ema = exports.Boll = exports.calcSeasonalIndicesNoTrend = exports.weightMovingAverages = exports.movingAverages = exports.exponentialSmoothing = exports.findTroughByGradient = exports.findPeaksByGradient = exports.SwingExtremesType = exports.SwingExtremes = exports.slope = exports.simpleRegressionModel = exports.Angle = void 0;
|
|
4
4
|
/*
|
|
5
5
|
請注意,在 src/index.ts 中,我的導入包含文件擴展名(.js)。
|
|
6
6
|
如果需要支持 Node.js 和構建工具(ex: webpack),則不需要這樣做。 **因為commonJs默認js副檔名**
|
|
@@ -53,6 +53,10 @@ var mfi_js_1 = require("./stockSkills/mfi.js");
|
|
|
53
53
|
Object.defineProperty(exports, "Mfi", { enumerable: true, get: function () { return mfi_js_1.default; } });
|
|
54
54
|
var ichimoku_js_1 = require("./stockSkills/ichimoku.js");
|
|
55
55
|
Object.defineProperty(exports, "Ichimoku", { enumerable: true, get: function () { return ichimoku_js_1.default; } });
|
|
56
|
+
var dmi_js_1 = require("./stockSkills/dmi.js");
|
|
57
|
+
Object.defineProperty(exports, "Dmi", { enumerable: true, get: function () { return dmi_js_1.default; } });
|
|
58
|
+
var cmf_js_1 = require("./stockSkills/cmf.js");
|
|
59
|
+
Object.defineProperty(exports, "Cmf", { enumerable: true, get: function () { return cmf_js_1.default; } });
|
|
56
60
|
var add_js_1 = require("./test/add.js");
|
|
57
61
|
Object.defineProperty(exports, "add", { enumerable: true, get: function () { return add_js_1.add; } });
|
|
58
62
|
var minus_js_1 = require("./test/minus.js");
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { StockListType, StockType } from "./types";
|
|
2
|
+
export type CmfResType = {
|
|
3
|
+
dataset: StockListType;
|
|
4
|
+
cmf: number;
|
|
5
|
+
ema: number;
|
|
6
|
+
cmfList: number[];
|
|
7
|
+
};
|
|
8
|
+
export default class Cmf {
|
|
9
|
+
init(data: StockType): CmfResType;
|
|
10
|
+
next(data: StockType, preList: CmfResType, period?: number, emaPeriod?: number): CmfResType;
|
|
11
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
3
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
4
|
+
if (ar || !(i in from)) {
|
|
5
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
6
|
+
ar[i] = from[i];
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
var Cmf = /** @class */ (function () {
|
|
13
|
+
function Cmf() {
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(Cmf.prototype, "init", {
|
|
16
|
+
enumerable: false,
|
|
17
|
+
configurable: true,
|
|
18
|
+
writable: true,
|
|
19
|
+
value: function (data) {
|
|
20
|
+
return {
|
|
21
|
+
dataset: [data],
|
|
22
|
+
cmf: 0,
|
|
23
|
+
ema: 0,
|
|
24
|
+
cmfList: [],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
Object.defineProperty(Cmf.prototype, "next", {
|
|
29
|
+
enumerable: false,
|
|
30
|
+
configurable: true,
|
|
31
|
+
writable: true,
|
|
32
|
+
value: function (data, preList, period, emaPeriod) {
|
|
33
|
+
if (period === void 0) { period = 20; }
|
|
34
|
+
if (emaPeriod === void 0) { emaPeriod = 10; }
|
|
35
|
+
preList.dataset.push(data);
|
|
36
|
+
if (preList.dataset.length > period) {
|
|
37
|
+
preList.dataset.shift();
|
|
38
|
+
}
|
|
39
|
+
var cmf = 0;
|
|
40
|
+
// Calculate CMF
|
|
41
|
+
if (preList.dataset.length === period) {
|
|
42
|
+
var sumMfVol = 0;
|
|
43
|
+
var sumVol = 0;
|
|
44
|
+
for (var i = 0; i < preList.dataset.length; i++) {
|
|
45
|
+
var item = preList.dataset[i];
|
|
46
|
+
var h = item.h;
|
|
47
|
+
var l = item.l;
|
|
48
|
+
var c = item.c;
|
|
49
|
+
var v = item.v;
|
|
50
|
+
if (h === l) {
|
|
51
|
+
sumVol += v;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
var multiplier = (c - l - (h - c)) / (h - l);
|
|
55
|
+
var mfVol = multiplier * v;
|
|
56
|
+
sumMfVol += mfVol;
|
|
57
|
+
sumVol += v;
|
|
58
|
+
}
|
|
59
|
+
if (sumVol !== 0) {
|
|
60
|
+
cmf = sumMfVol / sumVol;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Calculate EMA of CMF
|
|
64
|
+
var ema = preList.ema;
|
|
65
|
+
var cmfList = __spreadArray([], preList.cmfList, true);
|
|
66
|
+
// Use current 'cmf' only if we had enough data for it (dataset.length === period)
|
|
67
|
+
if (preList.dataset.length === period) {
|
|
68
|
+
cmfList.push(cmf);
|
|
69
|
+
}
|
|
70
|
+
if (cmfList.length === emaPeriod) {
|
|
71
|
+
// First time we have enough data to calculate EMA (SMA seed)
|
|
72
|
+
var sum = cmfList.reduce(function (pre, current) { return pre + current; }, 0);
|
|
73
|
+
ema = sum / emaPeriod;
|
|
74
|
+
}
|
|
75
|
+
else if (cmfList.length > emaPeriod) {
|
|
76
|
+
cmfList.shift();
|
|
77
|
+
// EMA formula: (Current * 2 + (period - 1) * PreviousEMA) / (period + 1)
|
|
78
|
+
ema = (cmf * 2 + (emaPeriod - 1) * preList.ema) / (emaPeriod + 1);
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
dataset: preList.dataset,
|
|
82
|
+
cmf: cmf,
|
|
83
|
+
ema: ema,
|
|
84
|
+
cmfList: cmfList,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
return Cmf;
|
|
89
|
+
}());
|
|
90
|
+
exports.default = Cmf;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var cmf_1 = require("./cmf");
|
|
4
|
+
describe("test Cmf methods", function () {
|
|
5
|
+
it("test CMF calculation with simple data (All Bullish)", function () {
|
|
6
|
+
var cmf = new cmf_1.default();
|
|
7
|
+
var period = 3;
|
|
8
|
+
// Data Case 1: Max positive MF
|
|
9
|
+
// H=10, L=0, C=10 => (10-0)-(10-10) = 10, Multiplier = 10/10 = 1.
|
|
10
|
+
var d1 = { c: 10, h: 10, l: 0, v: 100, o: 5, t: 1 };
|
|
11
|
+
var state = cmf.init(d1);
|
|
12
|
+
// Step 1: length 1 < 3. CMF = 0
|
|
13
|
+
expect(state.cmf).toBe(0);
|
|
14
|
+
state = cmf.next(d1, state, period); // length 2
|
|
15
|
+
expect(state.cmf).toBe(0);
|
|
16
|
+
state = cmf.next(d1, state, period); // length 3. SumMFV = 300, SumV = 300. CMF = 1.
|
|
17
|
+
expect(state.cmf).toBe(1);
|
|
18
|
+
});
|
|
19
|
+
it("test CMF calculation with mixed data", function () {
|
|
20
|
+
var cmf = new cmf_1.default();
|
|
21
|
+
var period = 3;
|
|
22
|
+
// Day 1: Mul=1, V=100 -> MFV=100
|
|
23
|
+
var d1 = { c: 10, h: 10, l: 0, v: 100, o: 5, t: 1 };
|
|
24
|
+
// Day 2: Mul=-1, V=100 -> MFV=-100. (C=0, H=10, L=0 => -10 / 10 = -1)
|
|
25
|
+
var d2 = { c: 0, h: 10, l: 0, v: 100, o: 5, t: 2 };
|
|
26
|
+
// Day 3: Mul=0, V=100 -> MFV=0. (C=5, H=10, L=0 => (5-0)-(10-5)=0)
|
|
27
|
+
var d3 = { c: 5, h: 10, l: 0, v: 100, o: 5, t: 3 };
|
|
28
|
+
var state = cmf.init(d1);
|
|
29
|
+
state = cmf.next(d2, state, period);
|
|
30
|
+
state = cmf.next(d3, state, period);
|
|
31
|
+
// Sum MFV = 100 - 100 + 0 = 0. CMF = 0.
|
|
32
|
+
expect(state.cmf).toBe(0);
|
|
33
|
+
});
|
|
34
|
+
it("test CMF EMA calculation", function () {
|
|
35
|
+
var instance = new cmf_1.default();
|
|
36
|
+
var period = 2;
|
|
37
|
+
var emaPeriod = 3;
|
|
38
|
+
// d1: CMF -> 0 (len 1)
|
|
39
|
+
var d1 = { c: 10, h: 10, l: 0, v: 100, o: 5, t: 1 };
|
|
40
|
+
var state = instance.init(d1);
|
|
41
|
+
// CMF undefined yet (0)
|
|
42
|
+
expect(state.cmf).toBe(0);
|
|
43
|
+
expect(state.ema).toBe(0);
|
|
44
|
+
// d2: CMF -> 1. (len 2). MFV=100+100=200, Vol=200.
|
|
45
|
+
var d2 = { c: 10, h: 10, l: 0, v: 100, o: 5, t: 2 };
|
|
46
|
+
state = instance.next(d2, state, period, emaPeriod);
|
|
47
|
+
expect(state.cmf).toBe(1);
|
|
48
|
+
// EMA calc: cmfList = [1]. len=1 < 3. ema=0.
|
|
49
|
+
expect(state.ema).toBe(0);
|
|
50
|
+
// d3: CMF -> 1. (len 2 shift). MFV=100+100=200.
|
|
51
|
+
var d3 = { c: 10, h: 10, l: 0, v: 100, o: 5, t: 3 };
|
|
52
|
+
state = instance.next(d3, state, period, emaPeriod);
|
|
53
|
+
expect(state.cmf).toBe(1);
|
|
54
|
+
// EMA calc: cmfList = [1, 1]. len=2 < 3. ema=0.
|
|
55
|
+
expect(state.ema).toBe(0);
|
|
56
|
+
// d4: CMF -> 1.
|
|
57
|
+
var d4 = { c: 10, h: 10, l: 0, v: 100, o: 5, t: 4 };
|
|
58
|
+
state = instance.next(d4, state, period, emaPeriod);
|
|
59
|
+
expect(state.cmf).toBe(1);
|
|
60
|
+
// EMA calc: cmfList = [1, 1, 1]. len=3. SMA = 1.
|
|
61
|
+
expect(state.ema).toBe(1);
|
|
62
|
+
// d5: CMF -> 2? No, let's make CMF different.
|
|
63
|
+
// period=2. window [d4, d5].
|
|
64
|
+
// d4: MFV=100, V=100.
|
|
65
|
+
// d5: c=0, h=10, l=0, v=100. mul=-1. MFV=-100.
|
|
66
|
+
// SumMFV = 100 - 100 = 0. CMF = 0.
|
|
67
|
+
var d5 = { c: 0, h: 10, l: 0, v: 100, o: 5, t: 5 };
|
|
68
|
+
state = instance.next(d5, state, period, emaPeriod);
|
|
69
|
+
expect(state.cmf).toBe(0);
|
|
70
|
+
// EMA calc: cmfList was [1, 1, 1]. Pushed 0 -> [1, 1, 1, 0]. Shift -> [1, 1, 0].
|
|
71
|
+
// Wait, implementation:
|
|
72
|
+
// push cmf -> [1, 1, 1, 0]
|
|
73
|
+
// if len > emaPeriod -> shift -> [1, 1, 0]
|
|
74
|
+
// EMA = (0 * 2 + (3-1) * 1) / (3+1) = (0 + 2) / 4 = 0.5.
|
|
75
|
+
expect(state.ema).toBe(0.5);
|
|
76
|
+
});
|
|
77
|
+
});
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export { default as Williams } from "./stockSkills/williams.js";
|
|
|
21
21
|
export { default as ObvEma } from "./stockSkills/obv_ema.js";
|
|
22
22
|
export { default as Mfi } from "./stockSkills/mfi.js";
|
|
23
23
|
export { default as Ichimoku } from "./stockSkills/ichimoku.js";
|
|
24
|
+
export { default as Dmi } from "./stockSkills/dmi.js";
|
|
25
|
+
export { default as Cmf } from "./stockSkills/cmf.js";
|
|
24
26
|
export { add } from "./test/add.js";
|
|
25
27
|
export { minus } from "./test/minus.js";
|
|
26
28
|
export { default as calculateDivisionFactor } from "./utils/calculateDivisionFactor.js";
|
package/dist/esm/index.js
CHANGED
|
@@ -24,6 +24,8 @@ export { default as Williams } from "./stockSkills/williams.js";
|
|
|
24
24
|
export { default as ObvEma } from "./stockSkills/obv_ema.js";
|
|
25
25
|
export { default as Mfi } from "./stockSkills/mfi.js";
|
|
26
26
|
export { default as Ichimoku } from "./stockSkills/ichimoku.js";
|
|
27
|
+
export { default as Dmi } from "./stockSkills/dmi.js";
|
|
28
|
+
export { default as Cmf } from "./stockSkills/cmf.js";
|
|
27
29
|
export { add } from "./test/add.js";
|
|
28
30
|
export { minus } from "./test/minus.js";
|
|
29
31
|
export { default as calculateDivisionFactor } from "./utils/calculateDivisionFactor.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { StockListType, StockType } from "./types";
|
|
2
|
+
export type CmfResType = {
|
|
3
|
+
dataset: StockListType;
|
|
4
|
+
cmf: number;
|
|
5
|
+
ema: number;
|
|
6
|
+
cmfList: number[];
|
|
7
|
+
};
|
|
8
|
+
export default class Cmf {
|
|
9
|
+
init(data: StockType): CmfResType;
|
|
10
|
+
next(data: StockType, preList: CmfResType, period?: number, emaPeriod?: number): CmfResType;
|
|
11
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
2
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
3
|
+
if (ar || !(i in from)) {
|
|
4
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
5
|
+
ar[i] = from[i];
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
9
|
+
};
|
|
10
|
+
var Cmf = /** @class */ (function () {
|
|
11
|
+
function Cmf() {
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(Cmf.prototype, "init", {
|
|
14
|
+
enumerable: false,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: function (data) {
|
|
18
|
+
return {
|
|
19
|
+
dataset: [data],
|
|
20
|
+
cmf: 0,
|
|
21
|
+
ema: 0,
|
|
22
|
+
cmfList: [],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(Cmf.prototype, "next", {
|
|
27
|
+
enumerable: false,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: function (data, preList, period, emaPeriod) {
|
|
31
|
+
if (period === void 0) { period = 20; }
|
|
32
|
+
if (emaPeriod === void 0) { emaPeriod = 10; }
|
|
33
|
+
preList.dataset.push(data);
|
|
34
|
+
if (preList.dataset.length > period) {
|
|
35
|
+
preList.dataset.shift();
|
|
36
|
+
}
|
|
37
|
+
var cmf = 0;
|
|
38
|
+
// Calculate CMF
|
|
39
|
+
if (preList.dataset.length === period) {
|
|
40
|
+
var sumMfVol = 0;
|
|
41
|
+
var sumVol = 0;
|
|
42
|
+
for (var i = 0; i < preList.dataset.length; i++) {
|
|
43
|
+
var item = preList.dataset[i];
|
|
44
|
+
var h = item.h;
|
|
45
|
+
var l = item.l;
|
|
46
|
+
var c = item.c;
|
|
47
|
+
var v = item.v;
|
|
48
|
+
if (h === l) {
|
|
49
|
+
sumVol += v;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
var multiplier = (c - l - (h - c)) / (h - l);
|
|
53
|
+
var mfVol = multiplier * v;
|
|
54
|
+
sumMfVol += mfVol;
|
|
55
|
+
sumVol += v;
|
|
56
|
+
}
|
|
57
|
+
if (sumVol !== 0) {
|
|
58
|
+
cmf = sumMfVol / sumVol;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Calculate EMA of CMF
|
|
62
|
+
var ema = preList.ema;
|
|
63
|
+
var cmfList = __spreadArray([], preList.cmfList, true);
|
|
64
|
+
// Use current 'cmf' only if we had enough data for it (dataset.length === period)
|
|
65
|
+
if (preList.dataset.length === period) {
|
|
66
|
+
cmfList.push(cmf);
|
|
67
|
+
}
|
|
68
|
+
if (cmfList.length === emaPeriod) {
|
|
69
|
+
// First time we have enough data to calculate EMA (SMA seed)
|
|
70
|
+
var sum = cmfList.reduce(function (pre, current) { return pre + current; }, 0);
|
|
71
|
+
ema = sum / emaPeriod;
|
|
72
|
+
}
|
|
73
|
+
else if (cmfList.length > emaPeriod) {
|
|
74
|
+
cmfList.shift();
|
|
75
|
+
// EMA formula: (Current * 2 + (period - 1) * PreviousEMA) / (period + 1)
|
|
76
|
+
ema = (cmf * 2 + (emaPeriod - 1) * preList.ema) / (emaPeriod + 1);
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
dataset: preList.dataset,
|
|
80
|
+
cmf: cmf,
|
|
81
|
+
ema: ema,
|
|
82
|
+
cmfList: cmfList,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
return Cmf;
|
|
87
|
+
}());
|
|
88
|
+
export default Cmf;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import Cmf from "./cmf";
|
|
2
|
+
describe("test Cmf methods", function () {
|
|
3
|
+
it("test CMF calculation with simple data (All Bullish)", function () {
|
|
4
|
+
var cmf = new Cmf();
|
|
5
|
+
var period = 3;
|
|
6
|
+
// Data Case 1: Max positive MF
|
|
7
|
+
// H=10, L=0, C=10 => (10-0)-(10-10) = 10, Multiplier = 10/10 = 1.
|
|
8
|
+
var d1 = { c: 10, h: 10, l: 0, v: 100, o: 5, t: 1 };
|
|
9
|
+
var state = cmf.init(d1);
|
|
10
|
+
// Step 1: length 1 < 3. CMF = 0
|
|
11
|
+
expect(state.cmf).toBe(0);
|
|
12
|
+
state = cmf.next(d1, state, period); // length 2
|
|
13
|
+
expect(state.cmf).toBe(0);
|
|
14
|
+
state = cmf.next(d1, state, period); // length 3. SumMFV = 300, SumV = 300. CMF = 1.
|
|
15
|
+
expect(state.cmf).toBe(1);
|
|
16
|
+
});
|
|
17
|
+
it("test CMF calculation with mixed data", function () {
|
|
18
|
+
var cmf = new Cmf();
|
|
19
|
+
var period = 3;
|
|
20
|
+
// Day 1: Mul=1, V=100 -> MFV=100
|
|
21
|
+
var d1 = { c: 10, h: 10, l: 0, v: 100, o: 5, t: 1 };
|
|
22
|
+
// Day 2: Mul=-1, V=100 -> MFV=-100. (C=0, H=10, L=0 => -10 / 10 = -1)
|
|
23
|
+
var d2 = { c: 0, h: 10, l: 0, v: 100, o: 5, t: 2 };
|
|
24
|
+
// Day 3: Mul=0, V=100 -> MFV=0. (C=5, H=10, L=0 => (5-0)-(10-5)=0)
|
|
25
|
+
var d3 = { c: 5, h: 10, l: 0, v: 100, o: 5, t: 3 };
|
|
26
|
+
var state = cmf.init(d1);
|
|
27
|
+
state = cmf.next(d2, state, period);
|
|
28
|
+
state = cmf.next(d3, state, period);
|
|
29
|
+
// Sum MFV = 100 - 100 + 0 = 0. CMF = 0.
|
|
30
|
+
expect(state.cmf).toBe(0);
|
|
31
|
+
});
|
|
32
|
+
it("test CMF EMA calculation", function () {
|
|
33
|
+
var instance = new Cmf();
|
|
34
|
+
var period = 2;
|
|
35
|
+
var emaPeriod = 3;
|
|
36
|
+
// d1: CMF -> 0 (len 1)
|
|
37
|
+
var d1 = { c: 10, h: 10, l: 0, v: 100, o: 5, t: 1 };
|
|
38
|
+
var state = instance.init(d1);
|
|
39
|
+
// CMF undefined yet (0)
|
|
40
|
+
expect(state.cmf).toBe(0);
|
|
41
|
+
expect(state.ema).toBe(0);
|
|
42
|
+
// d2: CMF -> 1. (len 2). MFV=100+100=200, Vol=200.
|
|
43
|
+
var d2 = { c: 10, h: 10, l: 0, v: 100, o: 5, t: 2 };
|
|
44
|
+
state = instance.next(d2, state, period, emaPeriod);
|
|
45
|
+
expect(state.cmf).toBe(1);
|
|
46
|
+
// EMA calc: cmfList = [1]. len=1 < 3. ema=0.
|
|
47
|
+
expect(state.ema).toBe(0);
|
|
48
|
+
// d3: CMF -> 1. (len 2 shift). MFV=100+100=200.
|
|
49
|
+
var d3 = { c: 10, h: 10, l: 0, v: 100, o: 5, t: 3 };
|
|
50
|
+
state = instance.next(d3, state, period, emaPeriod);
|
|
51
|
+
expect(state.cmf).toBe(1);
|
|
52
|
+
// EMA calc: cmfList = [1, 1]. len=2 < 3. ema=0.
|
|
53
|
+
expect(state.ema).toBe(0);
|
|
54
|
+
// d4: CMF -> 1.
|
|
55
|
+
var d4 = { c: 10, h: 10, l: 0, v: 100, o: 5, t: 4 };
|
|
56
|
+
state = instance.next(d4, state, period, emaPeriod);
|
|
57
|
+
expect(state.cmf).toBe(1);
|
|
58
|
+
// EMA calc: cmfList = [1, 1, 1]. len=3. SMA = 1.
|
|
59
|
+
expect(state.ema).toBe(1);
|
|
60
|
+
// d5: CMF -> 2? No, let's make CMF different.
|
|
61
|
+
// period=2. window [d4, d5].
|
|
62
|
+
// d4: MFV=100, V=100.
|
|
63
|
+
// d5: c=0, h=10, l=0, v=100. mul=-1. MFV=-100.
|
|
64
|
+
// SumMFV = 100 - 100 = 0. CMF = 0.
|
|
65
|
+
var d5 = { c: 0, h: 10, l: 0, v: 100, o: 5, t: 5 };
|
|
66
|
+
state = instance.next(d5, state, period, emaPeriod);
|
|
67
|
+
expect(state.cmf).toBe(0);
|
|
68
|
+
// EMA calc: cmfList was [1, 1, 1]. Pushed 0 -> [1, 1, 1, 0]. Shift -> [1, 1, 0].
|
|
69
|
+
// Wait, implementation:
|
|
70
|
+
// push cmf -> [1, 1, 1, 0]
|
|
71
|
+
// if len > emaPeriod -> shift -> [1, 1, 0]
|
|
72
|
+
// EMA = (0 * 2 + (3-1) * 1) / (3+1) = (0 + 2) / 4 = 0.5.
|
|
73
|
+
expect(state.ema).toBe(0.5);
|
|
74
|
+
});
|
|
75
|
+
});
|
package/dist/umd/index.js
CHANGED
|
@@ -282,8 +282,8 @@
|
|
|
282
282
|
return nextYearForecast;
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
-
var __assign$
|
|
286
|
-
__assign$
|
|
285
|
+
var __assign$8 = (undefined && undefined.__assign) || function () {
|
|
286
|
+
__assign$8 = Object.assign || function(t) {
|
|
287
287
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
288
288
|
s = arguments[i];
|
|
289
289
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
@@ -291,7 +291,7 @@
|
|
|
291
291
|
}
|
|
292
292
|
return t;
|
|
293
293
|
};
|
|
294
|
-
return __assign$
|
|
294
|
+
return __assign$8.apply(this, arguments);
|
|
295
295
|
};
|
|
296
296
|
var Boll = /** @class */ (function () {
|
|
297
297
|
function Boll() {
|
|
@@ -352,7 +352,7 @@
|
|
|
352
352
|
var res = [];
|
|
353
353
|
var _loop_1 = function (i) {
|
|
354
354
|
if (i < type)
|
|
355
|
-
res[i] = __assign$
|
|
355
|
+
res[i] = __assign$8(__assign$8({}, list[i]), { bollMa: 0, bollUb: 0, bollLb: 0 });
|
|
356
356
|
else {
|
|
357
357
|
// bollMa
|
|
358
358
|
var sumMa = list
|
|
@@ -366,7 +366,7 @@
|
|
|
366
366
|
return bollMa_2 !== 0 ? pre + Math.pow(current.c - bollMa_2, 2) : pre;
|
|
367
367
|
}, 0);
|
|
368
368
|
var std = Math.round(Math.sqrt(difference / type) * 100) / 100;
|
|
369
|
-
res[i] = __assign$
|
|
369
|
+
res[i] = __assign$8(__assign$8({}, list[i]), { bollMa: bollMa_2, bollUb: bollMa_2 + 2 * std, bollLb: bollMa_2 - 2 * std });
|
|
370
370
|
}
|
|
371
371
|
};
|
|
372
372
|
for (var i = 0; i < list.length; i++) {
|
|
@@ -455,8 +455,8 @@
|
|
|
455
455
|
return Ema;
|
|
456
456
|
}());
|
|
457
457
|
|
|
458
|
-
var __assign$
|
|
459
|
-
__assign$
|
|
458
|
+
var __assign$7 = (undefined && undefined.__assign) || function () {
|
|
459
|
+
__assign$7 = Object.assign || function(t) {
|
|
460
460
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
461
461
|
s = arguments[i];
|
|
462
462
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
@@ -464,13 +464,13 @@
|
|
|
464
464
|
}
|
|
465
465
|
return t;
|
|
466
466
|
};
|
|
467
|
-
return __assign$
|
|
467
|
+
return __assign$7.apply(this, arguments);
|
|
468
468
|
};
|
|
469
469
|
function addDetail(obj, list, detail) {
|
|
470
470
|
if (detail)
|
|
471
|
-
return __assign$
|
|
471
|
+
return __assign$7(__assign$7({}, obj), { detail: list });
|
|
472
472
|
else
|
|
473
|
-
return __assign$
|
|
473
|
+
return __assign$7({}, obj);
|
|
474
474
|
}
|
|
475
475
|
function getWeekLine(list, detail) {
|
|
476
476
|
var res = [];
|
|
@@ -799,8 +799,8 @@
|
|
|
799
799
|
return Kd;
|
|
800
800
|
}());
|
|
801
801
|
|
|
802
|
-
var __assign$
|
|
803
|
-
__assign$
|
|
802
|
+
var __assign$6 = (undefined && undefined.__assign) || function () {
|
|
803
|
+
__assign$6 = Object.assign || function(t) {
|
|
804
804
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
805
805
|
s = arguments[i];
|
|
806
806
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
@@ -808,7 +808,7 @@
|
|
|
808
808
|
}
|
|
809
809
|
return t;
|
|
810
810
|
};
|
|
811
|
-
return __assign$
|
|
811
|
+
return __assign$6.apply(this, arguments);
|
|
812
812
|
};
|
|
813
813
|
var Ma = /** @class */ (function () {
|
|
814
814
|
function Ma() {
|
|
@@ -882,13 +882,13 @@
|
|
|
882
882
|
var res = [];
|
|
883
883
|
for (var i = 0; i < list.length; i++) {
|
|
884
884
|
if (i < 4)
|
|
885
|
-
res[i] = __assign$
|
|
885
|
+
res[i] = __assign$6(__assign$6({}, list[i]), { ma5: 0 });
|
|
886
886
|
else {
|
|
887
887
|
var sum = list
|
|
888
888
|
.slice(i - 4, i + 1)
|
|
889
889
|
.reduce(function (pre, current) { return pre + current.c; }, 0);
|
|
890
890
|
var ma5 = Math.round((sum / 5) * 100) / 100;
|
|
891
|
-
res[i] = __assign$
|
|
891
|
+
res[i] = __assign$6(__assign$6({}, list[i]), { ma5: ma5 });
|
|
892
892
|
}
|
|
893
893
|
}
|
|
894
894
|
return res;
|
|
@@ -902,13 +902,13 @@
|
|
|
902
902
|
var res = [];
|
|
903
903
|
for (var i = 0; i < list.length; i++) {
|
|
904
904
|
if (i < 9)
|
|
905
|
-
res[i] = __assign$
|
|
905
|
+
res[i] = __assign$6(__assign$6({}, list[i]), { ma10: 0 });
|
|
906
906
|
else {
|
|
907
907
|
var sum = list
|
|
908
908
|
.slice(i - 9, i + 1)
|
|
909
909
|
.reduce(function (pre, current) { return pre + current.c; }, 0);
|
|
910
910
|
var ma10 = Math.round((sum / 10) * 100) / 100;
|
|
911
|
-
res[i] = __assign$
|
|
911
|
+
res[i] = __assign$6(__assign$6({}, list[i]), { ma10: ma10 });
|
|
912
912
|
}
|
|
913
913
|
}
|
|
914
914
|
return res;
|
|
@@ -922,13 +922,13 @@
|
|
|
922
922
|
var res = [];
|
|
923
923
|
for (var i = 0; i < list.length; i++) {
|
|
924
924
|
if (i < 19)
|
|
925
|
-
res[i] = __assign$
|
|
925
|
+
res[i] = __assign$6(__assign$6({}, list[i]), { ma20: 0 });
|
|
926
926
|
else {
|
|
927
927
|
var sum = list
|
|
928
928
|
.slice(i - 19, i + 1)
|
|
929
929
|
.reduce(function (pre, current) { return pre + current.c; }, 0);
|
|
930
930
|
var ma20 = Math.round((sum / 20) * 100) / 100;
|
|
931
|
-
res[i] = __assign$
|
|
931
|
+
res[i] = __assign$6(__assign$6({}, list[i]), { ma20: ma20 });
|
|
932
932
|
}
|
|
933
933
|
}
|
|
934
934
|
return res;
|
|
@@ -942,13 +942,13 @@
|
|
|
942
942
|
var res = [];
|
|
943
943
|
for (var i = 0; i < list.length; i++) {
|
|
944
944
|
if (i < 59)
|
|
945
|
-
res[i] = __assign$
|
|
945
|
+
res[i] = __assign$6(__assign$6({}, list[i]), { ma60: 0 });
|
|
946
946
|
else {
|
|
947
947
|
var sum = list
|
|
948
948
|
.slice(i - 59, i + 1)
|
|
949
949
|
.reduce(function (pre, current) { return pre + current.c; }, 0);
|
|
950
950
|
var ma60 = Math.round((sum / 60) * 100) / 100;
|
|
951
|
-
res[i] = __assign$
|
|
951
|
+
res[i] = __assign$6(__assign$6({}, list[i]), { ma60: ma60 });
|
|
952
952
|
}
|
|
953
953
|
}
|
|
954
954
|
return res;
|
|
@@ -962,13 +962,13 @@
|
|
|
962
962
|
var res = [];
|
|
963
963
|
for (var i = 0; i < list.length; i++) {
|
|
964
964
|
if (i < self - 1)
|
|
965
|
-
res[i] = __assign$
|
|
965
|
+
res[i] = __assign$6(__assign$6({}, list[i]), { ma: 0 });
|
|
966
966
|
else {
|
|
967
967
|
var sum = list
|
|
968
968
|
.slice(i - (self - 1), i + 1)
|
|
969
969
|
.reduce(function (pre, current) { return pre + current.c; }, 0);
|
|
970
970
|
var ma = Math.round((sum / self) * 100) / 100;
|
|
971
|
-
res[i] = __assign$
|
|
971
|
+
res[i] = __assign$6(__assign$6({}, list[i]), { ma: ma });
|
|
972
972
|
}
|
|
973
973
|
}
|
|
974
974
|
return res;
|
|
@@ -977,8 +977,8 @@
|
|
|
977
977
|
return Ma;
|
|
978
978
|
}());
|
|
979
979
|
|
|
980
|
-
var __assign$
|
|
981
|
-
__assign$
|
|
980
|
+
var __assign$5 = (undefined && undefined.__assign) || function () {
|
|
981
|
+
__assign$5 = Object.assign || function(t) {
|
|
982
982
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
983
983
|
s = arguments[i];
|
|
984
984
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
@@ -986,7 +986,7 @@
|
|
|
986
986
|
}
|
|
987
987
|
return t;
|
|
988
988
|
};
|
|
989
|
-
return __assign$
|
|
989
|
+
return __assign$5.apply(this, arguments);
|
|
990
990
|
};
|
|
991
991
|
var MACD = /** @class */ (function () {
|
|
992
992
|
function MACD() {
|
|
@@ -1124,10 +1124,10 @@
|
|
|
1124
1124
|
var res = [];
|
|
1125
1125
|
for (var i = 0; i < list.length; i++) {
|
|
1126
1126
|
if (i < 12)
|
|
1127
|
-
res[i] = __assign$
|
|
1127
|
+
res[i] = __assign$5(__assign$5({}, list[i]), { EMA12: null });
|
|
1128
1128
|
else {
|
|
1129
1129
|
beforeEMA12 = (beforeEMA12 * 11) / 13 + (this.getDI(list[i]) * 2) / 13;
|
|
1130
|
-
res[i] = __assign$
|
|
1130
|
+
res[i] = __assign$5(__assign$5({}, list[i]), { EMA12: beforeEMA12 });
|
|
1131
1131
|
}
|
|
1132
1132
|
}
|
|
1133
1133
|
return res;
|
|
@@ -1143,10 +1143,10 @@
|
|
|
1143
1143
|
var res = [];
|
|
1144
1144
|
for (var i = 0; i < list.length; i++) {
|
|
1145
1145
|
if (i < 26)
|
|
1146
|
-
res[i] = __assign$
|
|
1146
|
+
res[i] = __assign$5(__assign$5({}, list[i]), { EMA26: null });
|
|
1147
1147
|
else {
|
|
1148
1148
|
beforeEMA26 = (beforeEMA26 * 25) / 27 + (this.getDI(list[i]) * 2) / 27;
|
|
1149
|
-
res[i] = __assign$
|
|
1149
|
+
res[i] = __assign$5(__assign$5({}, list[i]), { EMA26: beforeEMA26 });
|
|
1150
1150
|
}
|
|
1151
1151
|
}
|
|
1152
1152
|
return res;
|
|
@@ -1161,12 +1161,12 @@
|
|
|
1161
1161
|
var res = [];
|
|
1162
1162
|
for (var i = 0; i < list.length; i++) {
|
|
1163
1163
|
if (i < 26)
|
|
1164
|
-
res[i] = __assign$
|
|
1164
|
+
res[i] = __assign$5(__assign$5({}, list[i]), { DIF: null });
|
|
1165
1165
|
else {
|
|
1166
1166
|
var EMA12 = ((_a = ResEMA12 === null || ResEMA12 === void 0 ? void 0 : ResEMA12[i]) === null || _a === void 0 ? void 0 : _a["EMA12"]) && ResEMA12[i]["EMA12"];
|
|
1167
1167
|
var EMA26 = ((_b = ResEMA26 === null || ResEMA26 === void 0 ? void 0 : ResEMA26[i]) === null || _b === void 0 ? void 0 : _b["EMA26"]) && ResEMA26[i]["EMA26"];
|
|
1168
1168
|
var DIF = EMA12 - EMA26;
|
|
1169
|
-
res[i] = __assign$
|
|
1169
|
+
res[i] = __assign$5(__assign$5({}, list[i]), { DIF: DIF });
|
|
1170
1170
|
}
|
|
1171
1171
|
}
|
|
1172
1172
|
return res;
|
|
@@ -1181,19 +1181,19 @@
|
|
|
1181
1181
|
var beforeMACD9 = 0;
|
|
1182
1182
|
for (var i = 0; i < list.length; i++) {
|
|
1183
1183
|
if (i < 26)
|
|
1184
|
-
res[i] = __assign$
|
|
1184
|
+
res[i] = __assign$5(__assign$5({}, list[i]), { MACD9: null, OSC: null });
|
|
1185
1185
|
else if (i === 26) {
|
|
1186
1186
|
var MACD9 = DIF.slice(26, 34)
|
|
1187
1187
|
.map(function (item) { return ((item === null || item === void 0 ? void 0 : item.DIF) ? item["DIF"] : 0); })
|
|
1188
1188
|
.reduce(function (accumulator, currentValue) { return accumulator + currentValue; });
|
|
1189
1189
|
var OSC = DIF[i]["DIF"] - MACD9;
|
|
1190
|
-
res[26] = __assign$
|
|
1190
|
+
res[26] = __assign$5(__assign$5({}, list[i]), { MACD9: MACD9, OSC: OSC });
|
|
1191
1191
|
beforeMACD9 = MACD9;
|
|
1192
1192
|
}
|
|
1193
1193
|
else {
|
|
1194
1194
|
var MACD9 = beforeMACD9 + ((DIF[i]["DIF"] - beforeMACD9) * 2) / 10;
|
|
1195
1195
|
var OSC = DIF[i]["DIF"] - MACD9;
|
|
1196
|
-
res[i] = __assign$
|
|
1196
|
+
res[i] = __assign$5(__assign$5({}, list[i]), { MACD9: MACD9, OSC: OSC });
|
|
1197
1197
|
beforeMACD9 = MACD9;
|
|
1198
1198
|
}
|
|
1199
1199
|
}
|
|
@@ -1203,8 +1203,8 @@
|
|
|
1203
1203
|
return MACD;
|
|
1204
1204
|
}());
|
|
1205
1205
|
|
|
1206
|
-
var __assign$
|
|
1207
|
-
__assign$
|
|
1206
|
+
var __assign$4 = (undefined && undefined.__assign) || function () {
|
|
1207
|
+
__assign$4 = Object.assign || function(t) {
|
|
1208
1208
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
1209
1209
|
s = arguments[i];
|
|
1210
1210
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
@@ -1212,9 +1212,9 @@
|
|
|
1212
1212
|
}
|
|
1213
1213
|
return t;
|
|
1214
1214
|
};
|
|
1215
|
-
return __assign$
|
|
1215
|
+
return __assign$4.apply(this, arguments);
|
|
1216
1216
|
};
|
|
1217
|
-
var __spreadArray = (undefined && undefined.__spreadArray) || function (to, from, pack) {
|
|
1217
|
+
var __spreadArray$2 = (undefined && undefined.__spreadArray) || function (to, from, pack) {
|
|
1218
1218
|
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
1219
1219
|
if (ar || !(i in from)) {
|
|
1220
1220
|
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
@@ -1254,7 +1254,7 @@
|
|
|
1254
1254
|
obv -= currentVolume;
|
|
1255
1255
|
}
|
|
1256
1256
|
return {
|
|
1257
|
-
dataset: __spreadArray(__spreadArray([], preList.dataset, true), [data], false),
|
|
1257
|
+
dataset: __spreadArray$2(__spreadArray$2([], preList.dataset, true), [data], false),
|
|
1258
1258
|
obv: obv,
|
|
1259
1259
|
preClose: currentClose,
|
|
1260
1260
|
};
|
|
@@ -1282,7 +1282,7 @@
|
|
|
1282
1282
|
else {
|
|
1283
1283
|
obv = currentVolume;
|
|
1284
1284
|
}
|
|
1285
|
-
res[i] = __assign$
|
|
1285
|
+
res[i] = __assign$4(__assign$4({}, list[i]), { obv: obv });
|
|
1286
1286
|
}
|
|
1287
1287
|
return res;
|
|
1288
1288
|
}
|
|
@@ -1290,8 +1290,8 @@
|
|
|
1290
1290
|
return Obv;
|
|
1291
1291
|
}());
|
|
1292
1292
|
|
|
1293
|
-
var __assign$
|
|
1294
|
-
__assign$
|
|
1293
|
+
var __assign$3 = (undefined && undefined.__assign) || function () {
|
|
1294
|
+
__assign$3 = Object.assign || function(t) {
|
|
1295
1295
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
1296
1296
|
s = arguments[i];
|
|
1297
1297
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
@@ -1299,7 +1299,7 @@
|
|
|
1299
1299
|
}
|
|
1300
1300
|
return t;
|
|
1301
1301
|
};
|
|
1302
|
-
return __assign$
|
|
1302
|
+
return __assign$3.apply(this, arguments);
|
|
1303
1303
|
};
|
|
1304
1304
|
var Rsi = /** @class */ (function () {
|
|
1305
1305
|
function Rsi() {
|
|
@@ -1325,7 +1325,7 @@
|
|
|
1325
1325
|
value: function (data, preList, type) {
|
|
1326
1326
|
preList.dataset.push(data);
|
|
1327
1327
|
if (preList.dataset.length < type + 1) {
|
|
1328
|
-
return __assign$
|
|
1328
|
+
return __assign$3(__assign$3({}, preList), { rsi: 0, type: type, avgGain: 0, avgLoss: 0 });
|
|
1329
1329
|
}
|
|
1330
1330
|
else {
|
|
1331
1331
|
// 计算初始增益和损失
|
|
@@ -1359,7 +1359,7 @@
|
|
|
1359
1359
|
// 计算RSI
|
|
1360
1360
|
var rs = avgGain / avgLoss;
|
|
1361
1361
|
var rsi = 100 - 100 / (1 + rs);
|
|
1362
|
-
return __assign$
|
|
1362
|
+
return __assign$3(__assign$3({}, preList), { type: type, rsi: rsi, avgGain: avgGain, avgLoss: avgLoss });
|
|
1363
1363
|
}
|
|
1364
1364
|
}
|
|
1365
1365
|
});
|
|
@@ -1547,8 +1547,8 @@
|
|
|
1547
1547
|
return Vma;
|
|
1548
1548
|
}());
|
|
1549
1549
|
|
|
1550
|
-
var __assign$
|
|
1551
|
-
__assign$
|
|
1550
|
+
var __assign$2 = (undefined && undefined.__assign) || function () {
|
|
1551
|
+
__assign$2 = Object.assign || function(t) {
|
|
1552
1552
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
1553
1553
|
s = arguments[i];
|
|
1554
1554
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
@@ -1556,7 +1556,7 @@
|
|
|
1556
1556
|
}
|
|
1557
1557
|
return t;
|
|
1558
1558
|
};
|
|
1559
|
-
return __assign$
|
|
1559
|
+
return __assign$2.apply(this, arguments);
|
|
1560
1560
|
};
|
|
1561
1561
|
var Williams = /** @class */ (function () {
|
|
1562
1562
|
function Williams() {
|
|
@@ -1619,7 +1619,7 @@
|
|
|
1619
1619
|
var res = [];
|
|
1620
1620
|
for (var i = 0; i < list.length; i++) {
|
|
1621
1621
|
if (i < 9)
|
|
1622
|
-
res[i] = __assign$
|
|
1622
|
+
res[i] = __assign$2(__assign$2({}, list[i]), { williams9: null });
|
|
1623
1623
|
else {
|
|
1624
1624
|
var maxList = list.slice(i - 8, i).map(function (item) { return item["h"]; });
|
|
1625
1625
|
var minList = list.slice(i - 8, i).map(function (item) { return item["l"]; });
|
|
@@ -1627,7 +1627,7 @@
|
|
|
1627
1627
|
var min = Math.min.apply(Math, minList);
|
|
1628
1628
|
var close_2 = list[i]["c"];
|
|
1629
1629
|
var williams9 = ((max - close_2) / (max - min)) * -100;
|
|
1630
|
-
res[i] = __assign$
|
|
1630
|
+
res[i] = __assign$2(__assign$2({}, list[i]), { williams9: Math.round(williams9 * 100) / 100 });
|
|
1631
1631
|
}
|
|
1632
1632
|
}
|
|
1633
1633
|
return res;
|
|
@@ -1641,7 +1641,7 @@
|
|
|
1641
1641
|
var res = [];
|
|
1642
1642
|
for (var i = 0; i < list.length; i++) {
|
|
1643
1643
|
if (i < 18)
|
|
1644
|
-
res[i] = __assign$
|
|
1644
|
+
res[i] = __assign$2(__assign$2({}, list[i]), { williams18: null });
|
|
1645
1645
|
else {
|
|
1646
1646
|
var maxList = list.slice(i - 17, i).map(function (item) { return item["h"]; });
|
|
1647
1647
|
var minList = list.slice(i - 17, i).map(function (item) { return item["l"]; });
|
|
@@ -1649,7 +1649,7 @@
|
|
|
1649
1649
|
var min = Math.min.apply(Math, minList);
|
|
1650
1650
|
var close_3 = list[i]["c"];
|
|
1651
1651
|
var williams18 = ((max - close_3) / (max - min)) * -100;
|
|
1652
|
-
res[i] = __assign$
|
|
1652
|
+
res[i] = __assign$2(__assign$2({}, list[i]), { williams18: Math.round(williams18 * 100) / 100 });
|
|
1653
1653
|
}
|
|
1654
1654
|
}
|
|
1655
1655
|
return res;
|
|
@@ -1705,8 +1705,8 @@
|
|
|
1705
1705
|
return ObvEma;
|
|
1706
1706
|
}());
|
|
1707
1707
|
|
|
1708
|
-
var __assign = (undefined && undefined.__assign) || function () {
|
|
1709
|
-
__assign = Object.assign || function(t) {
|
|
1708
|
+
var __assign$1 = (undefined && undefined.__assign) || function () {
|
|
1709
|
+
__assign$1 = Object.assign || function(t) {
|
|
1710
1710
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
1711
1711
|
s = arguments[i];
|
|
1712
1712
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
@@ -1714,7 +1714,7 @@
|
|
|
1714
1714
|
}
|
|
1715
1715
|
return t;
|
|
1716
1716
|
};
|
|
1717
|
-
return __assign.apply(this, arguments);
|
|
1717
|
+
return __assign$1.apply(this, arguments);
|
|
1718
1718
|
};
|
|
1719
1719
|
var Mfi = /** @class */ (function () {
|
|
1720
1720
|
function Mfi() {
|
|
@@ -1759,7 +1759,7 @@
|
|
|
1759
1759
|
preList.dataset.push(data);
|
|
1760
1760
|
// 資料不足,不計算 MFI
|
|
1761
1761
|
if (preList.dataset.length < type + 1) {
|
|
1762
|
-
return __assign(__assign({}, preList), { mfi: null, type: type, sumPositiveMF: 0, sumNegativeMF: 0 });
|
|
1762
|
+
return __assign$1(__assign$1({}, preList), { mfi: null, type: type, sumPositiveMF: 0, sumNegativeMF: 0 });
|
|
1763
1763
|
}
|
|
1764
1764
|
var sumPositiveMF = preList.sumPositiveMF;
|
|
1765
1765
|
var sumNegativeMF = preList.sumNegativeMF;
|
|
@@ -1963,6 +1963,295 @@
|
|
|
1963
1963
|
return Ichimoku;
|
|
1964
1964
|
}());
|
|
1965
1965
|
|
|
1966
|
+
var __assign = (undefined && undefined.__assign) || function () {
|
|
1967
|
+
__assign = Object.assign || function(t) {
|
|
1968
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
1969
|
+
s = arguments[i];
|
|
1970
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
1971
|
+
t[p] = s[p];
|
|
1972
|
+
}
|
|
1973
|
+
return t;
|
|
1974
|
+
};
|
|
1975
|
+
return __assign.apply(this, arguments);
|
|
1976
|
+
};
|
|
1977
|
+
var __spreadArray$1 = (undefined && undefined.__spreadArray) || function (to, from, pack) {
|
|
1978
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
1979
|
+
if (ar || !(i in from)) {
|
|
1980
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
1981
|
+
ar[i] = from[i];
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
1985
|
+
};
|
|
1986
|
+
var Dmi = /** @class */ (function () {
|
|
1987
|
+
function Dmi() {
|
|
1988
|
+
}
|
|
1989
|
+
Object.defineProperty(Dmi.prototype, "init", {
|
|
1990
|
+
enumerable: false,
|
|
1991
|
+
configurable: true,
|
|
1992
|
+
writable: true,
|
|
1993
|
+
value: function (data, type) {
|
|
1994
|
+
return {
|
|
1995
|
+
dataset: [data],
|
|
1996
|
+
pDi: 0,
|
|
1997
|
+
mDi: 0,
|
|
1998
|
+
adx: 0,
|
|
1999
|
+
type: type,
|
|
2000
|
+
smoothTr: 0,
|
|
2001
|
+
smoothPdm: 0,
|
|
2002
|
+
smoothMdm: 0,
|
|
2003
|
+
dxBuffer: [],
|
|
2004
|
+
smoothAdx: 0,
|
|
2005
|
+
};
|
|
2006
|
+
}
|
|
2007
|
+
});
|
|
2008
|
+
Object.defineProperty(Dmi.prototype, "next", {
|
|
2009
|
+
enumerable: false,
|
|
2010
|
+
configurable: true,
|
|
2011
|
+
writable: true,
|
|
2012
|
+
value: function (data, preList, type) {
|
|
2013
|
+
preList.dataset.push(data);
|
|
2014
|
+
// Need type + 1 data points to have 'type' periods of change
|
|
2015
|
+
if (preList.dataset.length < type + 1) {
|
|
2016
|
+
return __assign(__assign({}, preList), { pDi: 0, mDi: 0, adx: 0 });
|
|
2017
|
+
}
|
|
2018
|
+
else {
|
|
2019
|
+
// Logic to get TR, +DM, -DM for the NEWEST data point
|
|
2020
|
+
// We need the newest point and the one before it.
|
|
2021
|
+
// If we are in the initialization phase (length === type + 1), we process the whole window.
|
|
2022
|
+
// If we are in the incremental phase (length > type + 1), we just process the last step.
|
|
2023
|
+
var newSmoothTr = preList.smoothTr;
|
|
2024
|
+
var newSmoothPdm = preList.smoothPdm;
|
|
2025
|
+
var newSmoothMdm = preList.smoothMdm;
|
|
2026
|
+
if (preList.dataset.length === type + 1) {
|
|
2027
|
+
// Initialization: Calculate sum of first N periods (using N+1 data points)
|
|
2028
|
+
var sumTr = 0;
|
|
2029
|
+
var sumPdm = 0;
|
|
2030
|
+
var sumMdm = 0;
|
|
2031
|
+
for (var i = 1; i <= type; i++) {
|
|
2032
|
+
var curr = preList.dataset[i];
|
|
2033
|
+
var prev = preList.dataset[i - 1];
|
|
2034
|
+
// TR
|
|
2035
|
+
var hl = curr.h - curr.l;
|
|
2036
|
+
var hpc = Math.abs(curr.h - prev.c);
|
|
2037
|
+
var lpc = Math.abs(curr.l - prev.c);
|
|
2038
|
+
var tr = Math.max(hl, hpc, lpc);
|
|
2039
|
+
// DM
|
|
2040
|
+
var hph = curr.h - prev.h;
|
|
2041
|
+
var pll = prev.l - curr.l;
|
|
2042
|
+
var pdm = 0;
|
|
2043
|
+
var mdm = 0;
|
|
2044
|
+
if (hph > pll && hph > 0) {
|
|
2045
|
+
pdm = hph;
|
|
2046
|
+
}
|
|
2047
|
+
if (pll > hph && pll > 0) {
|
|
2048
|
+
mdm = pll;
|
|
2049
|
+
}
|
|
2050
|
+
sumTr += tr;
|
|
2051
|
+
sumPdm += pdm;
|
|
2052
|
+
sumMdm += mdm;
|
|
2053
|
+
}
|
|
2054
|
+
// Wilder's first value is often just the Sum.
|
|
2055
|
+
// But to make it consistent with the "Average" view for the formula:
|
|
2056
|
+
// NextAvg = (PrevAvg * (N-1) + Curr) / N
|
|
2057
|
+
// The first "PrevAvg" acts as the seed. The seed is usually the Simple Average.
|
|
2058
|
+
// So we divide by type.
|
|
2059
|
+
newSmoothTr = sumTr; // Some sources say keep Sum. But standard indicators often normalize to Average range.
|
|
2060
|
+
// Let's check RSI implementation. RSI divides by type: gains / type.
|
|
2061
|
+
// So we will divide by type to get the Average TR/DM.
|
|
2062
|
+
// Wait! DMI standard often keeps the SUM for the first value?
|
|
2063
|
+
// Wilder's book: "+DM14 is the sum of the +DM for the last 14 days".
|
|
2064
|
+
// Then subsequent: "+DM14_today = +DM14_yesterday - (+DM14_yesterday/14) + +DM_today".
|
|
2065
|
+
// This formula maintains the "Sum" magnitude (approx 14x the average).
|
|
2066
|
+
// BUT, RSI implementation uses Average magnitude (0-100 range inputs usually lead to small AvgGain).
|
|
2067
|
+
// Let's stick to the RSI pattern: Average.
|
|
2068
|
+
// Formula: (Avg * (N-1) + Curr) / N. This maintains "Average" magnitude.
|
|
2069
|
+
// If we used Sum logic: (Sum - Sum/N + Curr) = Sum * (1 - 1/N) + Curr.
|
|
2070
|
+
// These are mathematically consistent in shape, just scaled by N.
|
|
2071
|
+
// DI calculation is (Pdm / Tr) * 100. The scale cancels out!
|
|
2072
|
+
// So using Average is safer for preventing overflow and easier to debug (per-day values).
|
|
2073
|
+
newSmoothTr = sumTr / type;
|
|
2074
|
+
newSmoothPdm = sumPdm / type;
|
|
2075
|
+
newSmoothMdm = sumMdm / type;
|
|
2076
|
+
}
|
|
2077
|
+
else {
|
|
2078
|
+
// Shift if needed to keep dataset size manageable, though strictly we only need last 2 points
|
|
2079
|
+
// reusing rsi pattern:
|
|
2080
|
+
if (preList.dataset.length > type + 1) {
|
|
2081
|
+
preList.dataset.shift();
|
|
2082
|
+
}
|
|
2083
|
+
var curr = preList.dataset[preList.dataset.length - 1];
|
|
2084
|
+
var prev = preList.dataset[preList.dataset.length - 2];
|
|
2085
|
+
// TR
|
|
2086
|
+
var hl = curr.h - curr.l;
|
|
2087
|
+
var hpc = Math.abs(curr.h - prev.c);
|
|
2088
|
+
var lpc = Math.abs(curr.l - prev.c);
|
|
2089
|
+
var tr = Math.max(hl, hpc, lpc);
|
|
2090
|
+
// DM
|
|
2091
|
+
var hph = curr.h - prev.h;
|
|
2092
|
+
var pll = prev.l - curr.l;
|
|
2093
|
+
var pdm = 0;
|
|
2094
|
+
var mdm = 0;
|
|
2095
|
+
if (hph > pll && hph > 0)
|
|
2096
|
+
pdm = hph;
|
|
2097
|
+
if (pll > hph && pll > 0)
|
|
2098
|
+
mdm = pll;
|
|
2099
|
+
// Wilder's Smoothing (Average form)
|
|
2100
|
+
newSmoothTr = (preList.smoothTr * (type - 1) + tr) / type;
|
|
2101
|
+
newSmoothPdm = (preList.smoothPdm * (type - 1) + pdm) / type;
|
|
2102
|
+
newSmoothMdm = (preList.smoothMdm * (type - 1) + mdm) / type;
|
|
2103
|
+
}
|
|
2104
|
+
// Calculate DI
|
|
2105
|
+
// Avoid division by zero
|
|
2106
|
+
var pDi = newSmoothTr === 0 ? 0 : (newSmoothPdm / newSmoothTr) * 100;
|
|
2107
|
+
var mDi = newSmoothTr === 0 ? 0 : (newSmoothMdm / newSmoothTr) * 100;
|
|
2108
|
+
// Calculate DX
|
|
2109
|
+
var diDiff = Math.abs(pDi - mDi);
|
|
2110
|
+
var diSum = pDi + mDi;
|
|
2111
|
+
var dx = diSum === 0 ? 0 : (diDiff / diSum) * 100;
|
|
2112
|
+
// ADX Logic
|
|
2113
|
+
var dxBuffer = __spreadArray$1([], preList.dxBuffer, true);
|
|
2114
|
+
var adx = preList.adx;
|
|
2115
|
+
var newSmoothAdx = preList.smoothAdx;
|
|
2116
|
+
if (dxBuffer.length < type) {
|
|
2117
|
+
dxBuffer.push(dx);
|
|
2118
|
+
// Special case: if we Just reached 'type' count, we can calc initial ADX
|
|
2119
|
+
if (dxBuffer.length === type) {
|
|
2120
|
+
// First ADX is average of the DX buffer?
|
|
2121
|
+
// "ADX is the 14-day smoothed average of DX".
|
|
2122
|
+
// First value is simple average of previous 14 DX values.
|
|
2123
|
+
var sumDx = dxBuffer.reduce(function (a, b) { return a + b; }, 0);
|
|
2124
|
+
newSmoothAdx = sumDx / type;
|
|
2125
|
+
adx = newSmoothAdx;
|
|
2126
|
+
}
|
|
2127
|
+
else {
|
|
2128
|
+
// Not enough data for ADX yet
|
|
2129
|
+
adx = 0;
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
else {
|
|
2133
|
+
// We already have ADX initialized, so we smooth it
|
|
2134
|
+
// Note: we don't need to keep growing dxBuffer indefinitely.
|
|
2135
|
+
// We just needed it for startup.
|
|
2136
|
+
// Update ADX using Wilder's smoothing
|
|
2137
|
+
newSmoothAdx = (preList.smoothAdx * (type - 1) + dx) / type;
|
|
2138
|
+
adx = newSmoothAdx;
|
|
2139
|
+
}
|
|
2140
|
+
return __assign(__assign({}, preList), { pDi: pDi, // +DI
|
|
2141
|
+
mDi: mDi, // -DI
|
|
2142
|
+
adx: adx, smoothTr: newSmoothTr, smoothPdm: newSmoothPdm, smoothMdm: newSmoothMdm, dxBuffer: dxBuffer, smoothAdx: newSmoothAdx });
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
});
|
|
2146
|
+
// Helper to get formatted results similar to ma.ts
|
|
2147
|
+
Object.defineProperty(Dmi.prototype, "calculateDmiValues", {
|
|
2148
|
+
enumerable: false,
|
|
2149
|
+
configurable: true,
|
|
2150
|
+
writable: true,
|
|
2151
|
+
value: function (list, period) {
|
|
2152
|
+
if (period === void 0) { period = 14; }
|
|
2153
|
+
var res = [];
|
|
2154
|
+
var state = this.init(list[0], period);
|
|
2155
|
+
// First point (index 0) has 0 DMI
|
|
2156
|
+
res.push(__assign(__assign({}, list[0]), { pDi: 0, mDi: 0, adx: 0 }));
|
|
2157
|
+
for (var i = 1; i < list.length; i++) {
|
|
2158
|
+
state = this.next(list[i], state, period);
|
|
2159
|
+
res.push(__assign(__assign({}, list[i]), { pDi: state.pDi, mDi: state.mDi, adx: state.adx }));
|
|
2160
|
+
}
|
|
2161
|
+
return res;
|
|
2162
|
+
}
|
|
2163
|
+
});
|
|
2164
|
+
return Dmi;
|
|
2165
|
+
}());
|
|
2166
|
+
|
|
2167
|
+
var __spreadArray = (undefined && undefined.__spreadArray) || function (to, from, pack) {
|
|
2168
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
2169
|
+
if (ar || !(i in from)) {
|
|
2170
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
2171
|
+
ar[i] = from[i];
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
2175
|
+
};
|
|
2176
|
+
var Cmf = /** @class */ (function () {
|
|
2177
|
+
function Cmf() {
|
|
2178
|
+
}
|
|
2179
|
+
Object.defineProperty(Cmf.prototype, "init", {
|
|
2180
|
+
enumerable: false,
|
|
2181
|
+
configurable: true,
|
|
2182
|
+
writable: true,
|
|
2183
|
+
value: function (data) {
|
|
2184
|
+
return {
|
|
2185
|
+
dataset: [data],
|
|
2186
|
+
cmf: 0,
|
|
2187
|
+
ema: 0,
|
|
2188
|
+
cmfList: [],
|
|
2189
|
+
};
|
|
2190
|
+
}
|
|
2191
|
+
});
|
|
2192
|
+
Object.defineProperty(Cmf.prototype, "next", {
|
|
2193
|
+
enumerable: false,
|
|
2194
|
+
configurable: true,
|
|
2195
|
+
writable: true,
|
|
2196
|
+
value: function (data, preList, period, emaPeriod) {
|
|
2197
|
+
if (period === void 0) { period = 20; }
|
|
2198
|
+
if (emaPeriod === void 0) { emaPeriod = 10; }
|
|
2199
|
+
preList.dataset.push(data);
|
|
2200
|
+
if (preList.dataset.length > period) {
|
|
2201
|
+
preList.dataset.shift();
|
|
2202
|
+
}
|
|
2203
|
+
var cmf = 0;
|
|
2204
|
+
// Calculate CMF
|
|
2205
|
+
if (preList.dataset.length === period) {
|
|
2206
|
+
var sumMfVol = 0;
|
|
2207
|
+
var sumVol = 0;
|
|
2208
|
+
for (var i = 0; i < preList.dataset.length; i++) {
|
|
2209
|
+
var item = preList.dataset[i];
|
|
2210
|
+
var h = item.h;
|
|
2211
|
+
var l = item.l;
|
|
2212
|
+
var c = item.c;
|
|
2213
|
+
var v = item.v;
|
|
2214
|
+
if (h === l) {
|
|
2215
|
+
sumVol += v;
|
|
2216
|
+
continue;
|
|
2217
|
+
}
|
|
2218
|
+
var multiplier = (c - l - (h - c)) / (h - l);
|
|
2219
|
+
var mfVol = multiplier * v;
|
|
2220
|
+
sumMfVol += mfVol;
|
|
2221
|
+
sumVol += v;
|
|
2222
|
+
}
|
|
2223
|
+
if (sumVol !== 0) {
|
|
2224
|
+
cmf = sumMfVol / sumVol;
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
// Calculate EMA of CMF
|
|
2228
|
+
var ema = preList.ema;
|
|
2229
|
+
var cmfList = __spreadArray([], preList.cmfList, true);
|
|
2230
|
+
// Use current 'cmf' only if we had enough data for it (dataset.length === period)
|
|
2231
|
+
if (preList.dataset.length === period) {
|
|
2232
|
+
cmfList.push(cmf);
|
|
2233
|
+
}
|
|
2234
|
+
if (cmfList.length === emaPeriod) {
|
|
2235
|
+
// First time we have enough data to calculate EMA (SMA seed)
|
|
2236
|
+
var sum = cmfList.reduce(function (pre, current) { return pre + current; }, 0);
|
|
2237
|
+
ema = sum / emaPeriod;
|
|
2238
|
+
}
|
|
2239
|
+
else if (cmfList.length > emaPeriod) {
|
|
2240
|
+
cmfList.shift();
|
|
2241
|
+
// EMA formula: (Current * 2 + (period - 1) * PreviousEMA) / (period + 1)
|
|
2242
|
+
ema = (cmf * 2 + (emaPeriod - 1) * preList.ema) / (emaPeriod + 1);
|
|
2243
|
+
}
|
|
2244
|
+
return {
|
|
2245
|
+
dataset: preList.dataset,
|
|
2246
|
+
cmf: cmf,
|
|
2247
|
+
ema: ema,
|
|
2248
|
+
cmfList: cmfList,
|
|
2249
|
+
};
|
|
2250
|
+
}
|
|
2251
|
+
});
|
|
2252
|
+
return Cmf;
|
|
2253
|
+
}());
|
|
2254
|
+
|
|
1966
2255
|
function add(a, b) {
|
|
1967
2256
|
return a + b;
|
|
1968
2257
|
}
|
|
@@ -2001,6 +2290,8 @@
|
|
|
2001
2290
|
|
|
2002
2291
|
exports.Angle = TwoPointAngle;
|
|
2003
2292
|
exports.Boll = Boll;
|
|
2293
|
+
exports.Cmf = Cmf;
|
|
2294
|
+
exports.Dmi = Dmi;
|
|
2004
2295
|
exports.Ema = Ema;
|
|
2005
2296
|
exports.Gold = Gold;
|
|
2006
2297
|
exports.Ichimoku = Ichimoku;
|