@ch20026103/anysis 0.0.16-beta1 → 0.0.16
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/demo/main.js +1 -1
- package/dist/cjs/analyze/SwingExtremes/index.d.ts +4 -1
- package/dist/cjs/analyze/SwingExtremes/index.js +17 -40
- package/dist/cjs/analyze/SwingExtremes/index.test.js +18 -4
- package/dist/cjs/stockSkills/types.d.ts +1 -1
- package/dist/cjs/stockSkills/week.d.ts +1 -1
- package/dist/cjs/stockSkills/week.js +29 -30
- package/dist/cjs/stockSkills/week.test.js +84 -22
- package/dist/esm/analyze/SwingExtremes/index.d.ts +4 -1
- package/dist/esm/analyze/SwingExtremes/index.js +17 -40
- package/dist/esm/analyze/SwingExtremes/index.test.js +18 -4
- package/dist/esm/stockSkills/types.d.ts +1 -1
- package/dist/esm/stockSkills/week.d.ts +1 -1
- package/dist/esm/stockSkills/week.js +29 -30
- package/dist/esm/stockSkills/week.test.js +85 -23
- package/dist/umd/index.js +48 -72
- package/package.json +17 -15
package/demo/main.js
CHANGED
|
@@ -5,5 +5,8 @@ export declare enum SwingExtremesType {
|
|
|
5
5
|
type Index = number;
|
|
6
6
|
export declare function findPeaksByGradient(prices: number[], level?: number): Index[];
|
|
7
7
|
export declare function findTroughByGradient(prices: number[], level?: number): Index[];
|
|
8
|
-
export declare function SwingExtremes(y: number[],
|
|
8
|
+
export declare function SwingExtremes(y: number[], level?: number): {
|
|
9
|
+
index: Index;
|
|
10
|
+
type: SwingExtremesType;
|
|
11
|
+
}[];
|
|
9
12
|
export {};
|
|
@@ -60,48 +60,25 @@ function findTroughByGradient(prices, level) {
|
|
|
60
60
|
return troughs;
|
|
61
61
|
}
|
|
62
62
|
exports.findTroughByGradient = findTroughByGradient;
|
|
63
|
-
function SwingExtremes(y,
|
|
63
|
+
function SwingExtremes(y, level) {
|
|
64
64
|
if (level === void 0) { level = 1; }
|
|
65
|
-
|
|
66
|
-
var
|
|
67
|
-
var
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
else
|
|
80
|
-
result.push(indexs[i]);
|
|
81
|
-
}
|
|
82
|
-
return result;
|
|
83
|
-
}
|
|
84
|
-
if (type === SwingExtremesType.Trough) {
|
|
85
|
-
var result = [];
|
|
86
|
-
var indexs = findTroughByGradient(y, level);
|
|
87
|
-
result.push(indexs[0]);
|
|
88
|
-
for (var i = 1; i < indexs.length; i++) {
|
|
89
|
-
if (y[indexs[i]] < y[result[result.length - 1]] &&
|
|
90
|
-
y[indexs[i]] < y[result[result.length - 2]]) {
|
|
91
|
-
result[result.length - 1] = indexs[i];
|
|
92
|
-
}
|
|
93
|
-
else if (y[indexs[i + 1]] > y[i] &&
|
|
94
|
-
y[indexs[i]] < y[result[result.length - 1]]) {
|
|
95
|
-
result.pop();
|
|
96
|
-
result.push(indexs[i]);
|
|
97
|
-
}
|
|
98
|
-
else
|
|
99
|
-
result.push(indexs[i]);
|
|
100
|
-
}
|
|
101
|
-
return result;
|
|
65
|
+
try {
|
|
66
|
+
var peaks = findPeaksByGradient(y, level);
|
|
67
|
+
var peakObjs = peaks.map(function (index) { return ({
|
|
68
|
+
index: index,
|
|
69
|
+
type: SwingExtremesType.Peak,
|
|
70
|
+
}); });
|
|
71
|
+
var troughs = findTroughByGradient(y, level);
|
|
72
|
+
var troughObjs = troughs.map(function (index) { return ({
|
|
73
|
+
index: index,
|
|
74
|
+
type: SwingExtremesType.Trough,
|
|
75
|
+
}); });
|
|
76
|
+
var merge = peakObjs.concat(troughObjs);
|
|
77
|
+
return merge.sort(function (a, b) { return a.index - b.index; });
|
|
102
78
|
}
|
|
103
|
-
|
|
104
|
-
|
|
79
|
+
catch (err) {
|
|
80
|
+
console.error(err);
|
|
81
|
+
return [];
|
|
105
82
|
}
|
|
106
83
|
}
|
|
107
84
|
exports.SwingExtremes = SwingExtremes;
|
|
@@ -16,11 +16,25 @@ describe("test SwingExtremes", function () {
|
|
|
16
16
|
expect(res).toEqual([2, 5, 8, 12, 14]);
|
|
17
17
|
});
|
|
18
18
|
it("test SwingExtremes Peak", function () {
|
|
19
|
-
var
|
|
20
|
-
|
|
19
|
+
var arr = (0, index_1.SwingExtremes)(prices);
|
|
20
|
+
var res = arr.filter(function (x) { return x.type === index_1.SwingExtremesType.Peak; });
|
|
21
|
+
expect(res).toEqual([
|
|
22
|
+
{ index: 1, type: "Peak" },
|
|
23
|
+
{ index: 4, type: "Peak" },
|
|
24
|
+
{ index: 6, type: "Peak" },
|
|
25
|
+
{ index: 10, type: "Peak" },
|
|
26
|
+
{ index: 13, type: "Peak" },
|
|
27
|
+
]);
|
|
21
28
|
});
|
|
22
29
|
it("test SwingExtremes Trough", function () {
|
|
23
|
-
var
|
|
24
|
-
|
|
30
|
+
var arr = (0, index_1.SwingExtremes)(prices);
|
|
31
|
+
var res = arr.filter(function (x) { return x.type === index_1.SwingExtremesType.Trough; });
|
|
32
|
+
expect(res).toEqual([
|
|
33
|
+
{ index: 2, type: "Trough" },
|
|
34
|
+
{ index: 5, type: "Trough" },
|
|
35
|
+
{ index: 8, type: "Trough" },
|
|
36
|
+
{ index: 12, type: "Trough" },
|
|
37
|
+
{ index: 14, type: "Trough" },
|
|
38
|
+
]);
|
|
25
39
|
});
|
|
26
40
|
});
|
|
@@ -1,13 +1,4 @@
|
|
|
1
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
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
var Week = /** @class */ (function () {
|
|
13
4
|
function Week() {
|
|
@@ -25,30 +16,38 @@ var Week = /** @class */ (function () {
|
|
|
25
16
|
configurable: true,
|
|
26
17
|
writable: true,
|
|
27
18
|
value: function (data, preList) {
|
|
28
|
-
var year = data.t
|
|
29
|
-
.toString()
|
|
30
|
-
.replace(/^(\d{4})(\d{2})(\d{2})$/, "$1-$2-$3");
|
|
31
|
-
var day = new Date(year).getDay();
|
|
32
|
-
if (day === 6 || day === 0)
|
|
33
|
-
return { dataset: preList.dataset, week: preList.week };
|
|
34
19
|
preList.dataset.push(data);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
preList.dataset = [data];
|
|
20
|
+
var index = 0;
|
|
21
|
+
if (preList.dataset.length === 1)
|
|
22
|
+
return preList;
|
|
23
|
+
for (var i = 1; i < preList.dataset.length; i++) {
|
|
24
|
+
var pre_day = new Date(preList.dataset[i - 1].t
|
|
25
|
+
.toString()
|
|
26
|
+
.replace(/^(\d{4})(\d{2})(\d{2})$/, "$1-$2-$3")).getDay();
|
|
27
|
+
var curr_day = new Date(preList.dataset[i].t
|
|
28
|
+
.toString()
|
|
29
|
+
.replace(/^(\d{4})(\d{2})(\d{2})$/, "$1-$2-$3")).getDay();
|
|
30
|
+
if (pre_day > curr_day) {
|
|
31
|
+
index = i;
|
|
32
|
+
break;
|
|
49
33
|
}
|
|
50
|
-
return { dataset: preList.dataset, week: preList.week };
|
|
51
34
|
}
|
|
35
|
+
// 以index拆分数组
|
|
36
|
+
var week = preList.dataset.slice(0, index);
|
|
37
|
+
var dataset = preList.dataset.slice(index);
|
|
38
|
+
if (week.length > 0) {
|
|
39
|
+
var weekData = {
|
|
40
|
+
o: week[0]["o"],
|
|
41
|
+
c: week[week.length - 1]["c"],
|
|
42
|
+
t: week[week.length - 1]["t"],
|
|
43
|
+
h: Math.max.apply(Math, week.map(function (item) { return item.h; })),
|
|
44
|
+
l: Math.min.apply(Math, week.map(function (item) { return item.l; })),
|
|
45
|
+
v: week.reduce(function (pre, current) { return pre + current.v; }, 0),
|
|
46
|
+
};
|
|
47
|
+
preList.week.push(weekData);
|
|
48
|
+
}
|
|
49
|
+
preList.dataset = dataset;
|
|
50
|
+
return preList;
|
|
52
51
|
}
|
|
53
52
|
});
|
|
54
53
|
return Week;
|
|
@@ -1,57 +1,119 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
var week_1 = require("./week");
|
|
4
|
-
describe(
|
|
4
|
+
describe("Week", function () {
|
|
5
5
|
var week;
|
|
6
6
|
beforeEach(function () {
|
|
7
7
|
week = new week_1.default();
|
|
8
8
|
});
|
|
9
|
-
describe(
|
|
10
|
-
it(
|
|
11
|
-
var data = {
|
|
9
|
+
describe("init", function () {
|
|
10
|
+
it("應該正確初始化數據", function () {
|
|
11
|
+
var data = {
|
|
12
|
+
o: 100,
|
|
13
|
+
c: 101,
|
|
14
|
+
h: 102,
|
|
15
|
+
l: 99,
|
|
16
|
+
t: 20230501,
|
|
17
|
+
v: 1000,
|
|
18
|
+
};
|
|
12
19
|
var result = week.init(data);
|
|
13
20
|
expect(result).toEqual({ dataset: [data], week: [] });
|
|
14
21
|
});
|
|
15
22
|
});
|
|
16
|
-
describe(
|
|
17
|
-
it(
|
|
18
|
-
var initialData = {
|
|
19
|
-
|
|
23
|
+
describe("next", function () {
|
|
24
|
+
it("應該正確處理非週末的數據", function () {
|
|
25
|
+
var initialData = {
|
|
26
|
+
o: 100,
|
|
27
|
+
c: 101,
|
|
28
|
+
h: 102,
|
|
29
|
+
l: 99,
|
|
30
|
+
t: 20230501,
|
|
31
|
+
v: 1000,
|
|
32
|
+
};
|
|
33
|
+
var nextData = {
|
|
34
|
+
o: 101,
|
|
35
|
+
c: 102,
|
|
36
|
+
h: 103,
|
|
37
|
+
l: 100,
|
|
38
|
+
t: 20230502,
|
|
39
|
+
v: 1100,
|
|
40
|
+
};
|
|
20
41
|
var initialResult = week.init(initialData);
|
|
21
42
|
var result = week.next(nextData, initialResult);
|
|
22
43
|
expect(result.dataset).toHaveLength(2);
|
|
23
44
|
expect(result.week).toHaveLength(0);
|
|
24
45
|
});
|
|
25
|
-
it(
|
|
26
|
-
var initialData = {
|
|
46
|
+
it("應該在週五時生成週數據", function () {
|
|
47
|
+
var initialData = {
|
|
48
|
+
o: 100,
|
|
49
|
+
c: 101,
|
|
50
|
+
h: 102,
|
|
51
|
+
l: 99,
|
|
52
|
+
t: 20230501,
|
|
53
|
+
v: 1000,
|
|
54
|
+
};
|
|
27
55
|
var result = week.init(initialData);
|
|
28
|
-
for (var i =
|
|
29
|
-
var nextData = {
|
|
56
|
+
for (var i = 1; i <= 9; i++) {
|
|
57
|
+
var nextData = {
|
|
58
|
+
o: 100 + i,
|
|
59
|
+
c: 101 + i,
|
|
60
|
+
h: 102 + i,
|
|
61
|
+
l: 99 + i,
|
|
62
|
+
t: 20230501 + i,
|
|
63
|
+
v: 1000 + i * 100,
|
|
64
|
+
};
|
|
30
65
|
result = week.next(nextData, result);
|
|
31
66
|
}
|
|
32
|
-
expect(result.dataset).toHaveLength(
|
|
67
|
+
expect(result.dataset).toHaveLength(4);
|
|
33
68
|
expect(result.week).toHaveLength(1);
|
|
34
69
|
expect(result.week[0]).toEqual({
|
|
35
70
|
o: 100,
|
|
36
71
|
c: 106,
|
|
72
|
+
t: 20230506,
|
|
37
73
|
h: 107,
|
|
38
74
|
l: 99,
|
|
39
|
-
|
|
40
|
-
v: 6400
|
|
75
|
+
v: 7500,
|
|
41
76
|
});
|
|
42
77
|
});
|
|
43
|
-
it(
|
|
44
|
-
var initialData = {
|
|
45
|
-
|
|
78
|
+
it("應該忽略週末數據", function () {
|
|
79
|
+
var initialData = {
|
|
80
|
+
o: 100,
|
|
81
|
+
c: 101,
|
|
82
|
+
h: 102,
|
|
83
|
+
l: 99,
|
|
84
|
+
t: 20230505,
|
|
85
|
+
v: 1000,
|
|
86
|
+
};
|
|
87
|
+
var weekendData = {
|
|
88
|
+
o: 101,
|
|
89
|
+
c: 102,
|
|
90
|
+
h: 103,
|
|
91
|
+
l: 100,
|
|
92
|
+
t: 20230506,
|
|
93
|
+
v: 1100,
|
|
94
|
+
};
|
|
46
95
|
var initialResult = week.init(initialData);
|
|
47
96
|
var result = week.next(weekendData, initialResult);
|
|
48
97
|
expect(result).toEqual(initialResult);
|
|
49
98
|
});
|
|
50
|
-
it(
|
|
51
|
-
var fridayData = {
|
|
52
|
-
|
|
99
|
+
it("應該在新的一週開始時重置數據集", function () {
|
|
100
|
+
var fridayData = {
|
|
101
|
+
o: 100,
|
|
102
|
+
c: 101,
|
|
103
|
+
h: 102,
|
|
104
|
+
l: 99,
|
|
105
|
+
t: 20230505,
|
|
106
|
+
v: 1000,
|
|
107
|
+
};
|
|
108
|
+
var mondayData = {
|
|
109
|
+
o: 101,
|
|
110
|
+
c: 102,
|
|
111
|
+
h: 103,
|
|
112
|
+
l: 100,
|
|
113
|
+
t: 20230508,
|
|
114
|
+
v: 1100,
|
|
115
|
+
};
|
|
53
116
|
var result = week.init(fridayData);
|
|
54
|
-
result = week.next(fridayData, result);
|
|
55
117
|
result = week.next(mondayData, result);
|
|
56
118
|
expect(result.dataset).toHaveLength(1);
|
|
57
119
|
expect(result.dataset[0]).toEqual(mondayData);
|
|
@@ -5,5 +5,8 @@ export declare enum SwingExtremesType {
|
|
|
5
5
|
type Index = number;
|
|
6
6
|
export declare function findPeaksByGradient(prices: number[], level?: number): Index[];
|
|
7
7
|
export declare function findTroughByGradient(prices: number[], level?: number): Index[];
|
|
8
|
-
export declare function SwingExtremes(y: number[],
|
|
8
|
+
export declare function SwingExtremes(y: number[], level?: number): {
|
|
9
|
+
index: Index;
|
|
10
|
+
type: SwingExtremesType;
|
|
11
|
+
}[];
|
|
9
12
|
export {};
|
|
@@ -55,47 +55,24 @@ export function findTroughByGradient(prices, level) {
|
|
|
55
55
|
}
|
|
56
56
|
return troughs;
|
|
57
57
|
}
|
|
58
|
-
export function SwingExtremes(y,
|
|
58
|
+
export function SwingExtremes(y, level) {
|
|
59
59
|
if (level === void 0) { level = 1; }
|
|
60
|
-
|
|
61
|
-
var
|
|
62
|
-
var
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
else
|
|
75
|
-
result.push(indexs[i]);
|
|
76
|
-
}
|
|
77
|
-
return result;
|
|
78
|
-
}
|
|
79
|
-
if (type === SwingExtremesType.Trough) {
|
|
80
|
-
var result = [];
|
|
81
|
-
var indexs = findTroughByGradient(y, level);
|
|
82
|
-
result.push(indexs[0]);
|
|
83
|
-
for (var i = 1; i < indexs.length; i++) {
|
|
84
|
-
if (y[indexs[i]] < y[result[result.length - 1]] &&
|
|
85
|
-
y[indexs[i]] < y[result[result.length - 2]]) {
|
|
86
|
-
result[result.length - 1] = indexs[i];
|
|
87
|
-
}
|
|
88
|
-
else if (y[indexs[i + 1]] > y[i] &&
|
|
89
|
-
y[indexs[i]] < y[result[result.length - 1]]) {
|
|
90
|
-
result.pop();
|
|
91
|
-
result.push(indexs[i]);
|
|
92
|
-
}
|
|
93
|
-
else
|
|
94
|
-
result.push(indexs[i]);
|
|
95
|
-
}
|
|
96
|
-
return result;
|
|
60
|
+
try {
|
|
61
|
+
var peaks = findPeaksByGradient(y, level);
|
|
62
|
+
var peakObjs = peaks.map(function (index) { return ({
|
|
63
|
+
index: index,
|
|
64
|
+
type: SwingExtremesType.Peak,
|
|
65
|
+
}); });
|
|
66
|
+
var troughs = findTroughByGradient(y, level);
|
|
67
|
+
var troughObjs = troughs.map(function (index) { return ({
|
|
68
|
+
index: index,
|
|
69
|
+
type: SwingExtremesType.Trough,
|
|
70
|
+
}); });
|
|
71
|
+
var merge = peakObjs.concat(troughObjs);
|
|
72
|
+
return merge.sort(function (a, b) { return a.index - b.index; });
|
|
97
73
|
}
|
|
98
|
-
|
|
99
|
-
|
|
74
|
+
catch (err) {
|
|
75
|
+
console.error(err);
|
|
76
|
+
return [];
|
|
100
77
|
}
|
|
101
78
|
}
|
|
@@ -14,11 +14,25 @@ describe("test SwingExtremes", function () {
|
|
|
14
14
|
expect(res).toEqual([2, 5, 8, 12, 14]);
|
|
15
15
|
});
|
|
16
16
|
it("test SwingExtremes Peak", function () {
|
|
17
|
-
var
|
|
18
|
-
|
|
17
|
+
var arr = SwingExtremes(prices);
|
|
18
|
+
var res = arr.filter(function (x) { return x.type === SwingExtremesType.Peak; });
|
|
19
|
+
expect(res).toEqual([
|
|
20
|
+
{ index: 1, type: "Peak" },
|
|
21
|
+
{ index: 4, type: "Peak" },
|
|
22
|
+
{ index: 6, type: "Peak" },
|
|
23
|
+
{ index: 10, type: "Peak" },
|
|
24
|
+
{ index: 13, type: "Peak" },
|
|
25
|
+
]);
|
|
19
26
|
});
|
|
20
27
|
it("test SwingExtremes Trough", function () {
|
|
21
|
-
var
|
|
22
|
-
|
|
28
|
+
var arr = SwingExtremes(prices);
|
|
29
|
+
var res = arr.filter(function (x) { return x.type === SwingExtremesType.Trough; });
|
|
30
|
+
expect(res).toEqual([
|
|
31
|
+
{ index: 2, type: "Trough" },
|
|
32
|
+
{ index: 5, type: "Trough" },
|
|
33
|
+
{ index: 8, type: "Trough" },
|
|
34
|
+
{ index: 12, type: "Trough" },
|
|
35
|
+
{ index: 14, type: "Trough" },
|
|
36
|
+
]);
|
|
23
37
|
});
|
|
24
38
|
});
|
|
@@ -1,12 +1,3 @@
|
|
|
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
1
|
var Week = /** @class */ (function () {
|
|
11
2
|
function Week() {
|
|
12
3
|
}
|
|
@@ -23,30 +14,38 @@ var Week = /** @class */ (function () {
|
|
|
23
14
|
configurable: true,
|
|
24
15
|
writable: true,
|
|
25
16
|
value: function (data, preList) {
|
|
26
|
-
var year = data.t
|
|
27
|
-
.toString()
|
|
28
|
-
.replace(/^(\d{4})(\d{2})(\d{2})$/, "$1-$2-$3");
|
|
29
|
-
var day = new Date(year).getDay();
|
|
30
|
-
if (day === 6 || day === 0)
|
|
31
|
-
return { dataset: preList.dataset, week: preList.week };
|
|
32
17
|
preList.dataset.push(data);
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
preList.dataset = [data];
|
|
18
|
+
var index = 0;
|
|
19
|
+
if (preList.dataset.length === 1)
|
|
20
|
+
return preList;
|
|
21
|
+
for (var i = 1; i < preList.dataset.length; i++) {
|
|
22
|
+
var pre_day = new Date(preList.dataset[i - 1].t
|
|
23
|
+
.toString()
|
|
24
|
+
.replace(/^(\d{4})(\d{2})(\d{2})$/, "$1-$2-$3")).getDay();
|
|
25
|
+
var curr_day = new Date(preList.dataset[i].t
|
|
26
|
+
.toString()
|
|
27
|
+
.replace(/^(\d{4})(\d{2})(\d{2})$/, "$1-$2-$3")).getDay();
|
|
28
|
+
if (pre_day > curr_day) {
|
|
29
|
+
index = i;
|
|
30
|
+
break;
|
|
47
31
|
}
|
|
48
|
-
return { dataset: preList.dataset, week: preList.week };
|
|
49
32
|
}
|
|
33
|
+
// 以index拆分数组
|
|
34
|
+
var week = preList.dataset.slice(0, index);
|
|
35
|
+
var dataset = preList.dataset.slice(index);
|
|
36
|
+
if (week.length > 0) {
|
|
37
|
+
var weekData = {
|
|
38
|
+
o: week[0]["o"],
|
|
39
|
+
c: week[week.length - 1]["c"],
|
|
40
|
+
t: week[week.length - 1]["t"],
|
|
41
|
+
h: Math.max.apply(Math, week.map(function (item) { return item.h; })),
|
|
42
|
+
l: Math.min.apply(Math, week.map(function (item) { return item.l; })),
|
|
43
|
+
v: week.reduce(function (pre, current) { return pre + current.v; }, 0),
|
|
44
|
+
};
|
|
45
|
+
preList.week.push(weekData);
|
|
46
|
+
}
|
|
47
|
+
preList.dataset = dataset;
|
|
48
|
+
return preList;
|
|
50
49
|
}
|
|
51
50
|
});
|
|
52
51
|
return Week;
|
|
@@ -1,55 +1,117 @@
|
|
|
1
|
-
import Week from
|
|
2
|
-
describe(
|
|
1
|
+
import Week from "./week";
|
|
2
|
+
describe("Week", function () {
|
|
3
3
|
var week;
|
|
4
4
|
beforeEach(function () {
|
|
5
5
|
week = new Week();
|
|
6
6
|
});
|
|
7
|
-
describe(
|
|
8
|
-
it(
|
|
9
|
-
var data = {
|
|
7
|
+
describe("init", function () {
|
|
8
|
+
it("應該正確初始化數據", function () {
|
|
9
|
+
var data = {
|
|
10
|
+
o: 100,
|
|
11
|
+
c: 101,
|
|
12
|
+
h: 102,
|
|
13
|
+
l: 99,
|
|
14
|
+
t: 20230501,
|
|
15
|
+
v: 1000,
|
|
16
|
+
};
|
|
10
17
|
var result = week.init(data);
|
|
11
18
|
expect(result).toEqual({ dataset: [data], week: [] });
|
|
12
19
|
});
|
|
13
20
|
});
|
|
14
|
-
describe(
|
|
15
|
-
it(
|
|
16
|
-
var initialData = {
|
|
17
|
-
|
|
21
|
+
describe("next", function () {
|
|
22
|
+
it("應該正確處理非週末的數據", function () {
|
|
23
|
+
var initialData = {
|
|
24
|
+
o: 100,
|
|
25
|
+
c: 101,
|
|
26
|
+
h: 102,
|
|
27
|
+
l: 99,
|
|
28
|
+
t: 20230501,
|
|
29
|
+
v: 1000,
|
|
30
|
+
};
|
|
31
|
+
var nextData = {
|
|
32
|
+
o: 101,
|
|
33
|
+
c: 102,
|
|
34
|
+
h: 103,
|
|
35
|
+
l: 100,
|
|
36
|
+
t: 20230502,
|
|
37
|
+
v: 1100,
|
|
38
|
+
};
|
|
18
39
|
var initialResult = week.init(initialData);
|
|
19
40
|
var result = week.next(nextData, initialResult);
|
|
20
41
|
expect(result.dataset).toHaveLength(2);
|
|
21
42
|
expect(result.week).toHaveLength(0);
|
|
22
43
|
});
|
|
23
|
-
it(
|
|
24
|
-
var initialData = {
|
|
44
|
+
it("應該在週五時生成週數據", function () {
|
|
45
|
+
var initialData = {
|
|
46
|
+
o: 100,
|
|
47
|
+
c: 101,
|
|
48
|
+
h: 102,
|
|
49
|
+
l: 99,
|
|
50
|
+
t: 20230501,
|
|
51
|
+
v: 1000,
|
|
52
|
+
};
|
|
25
53
|
var result = week.init(initialData);
|
|
26
|
-
for (var i =
|
|
27
|
-
var nextData = {
|
|
54
|
+
for (var i = 1; i <= 9; i++) {
|
|
55
|
+
var nextData = {
|
|
56
|
+
o: 100 + i,
|
|
57
|
+
c: 101 + i,
|
|
58
|
+
h: 102 + i,
|
|
59
|
+
l: 99 + i,
|
|
60
|
+
t: 20230501 + i,
|
|
61
|
+
v: 1000 + i * 100,
|
|
62
|
+
};
|
|
28
63
|
result = week.next(nextData, result);
|
|
29
64
|
}
|
|
30
|
-
expect(result.dataset).toHaveLength(
|
|
65
|
+
expect(result.dataset).toHaveLength(4);
|
|
31
66
|
expect(result.week).toHaveLength(1);
|
|
32
67
|
expect(result.week[0]).toEqual({
|
|
33
68
|
o: 100,
|
|
34
69
|
c: 106,
|
|
70
|
+
t: 20230506,
|
|
35
71
|
h: 107,
|
|
36
72
|
l: 99,
|
|
37
|
-
|
|
38
|
-
v: 6400
|
|
73
|
+
v: 7500,
|
|
39
74
|
});
|
|
40
75
|
});
|
|
41
|
-
it(
|
|
42
|
-
var initialData = {
|
|
43
|
-
|
|
76
|
+
it("應該忽略週末數據", function () {
|
|
77
|
+
var initialData = {
|
|
78
|
+
o: 100,
|
|
79
|
+
c: 101,
|
|
80
|
+
h: 102,
|
|
81
|
+
l: 99,
|
|
82
|
+
t: 20230505,
|
|
83
|
+
v: 1000,
|
|
84
|
+
};
|
|
85
|
+
var weekendData = {
|
|
86
|
+
o: 101,
|
|
87
|
+
c: 102,
|
|
88
|
+
h: 103,
|
|
89
|
+
l: 100,
|
|
90
|
+
t: 20230506,
|
|
91
|
+
v: 1100,
|
|
92
|
+
};
|
|
44
93
|
var initialResult = week.init(initialData);
|
|
45
94
|
var result = week.next(weekendData, initialResult);
|
|
46
95
|
expect(result).toEqual(initialResult);
|
|
47
96
|
});
|
|
48
|
-
it(
|
|
49
|
-
var fridayData = {
|
|
50
|
-
|
|
97
|
+
it("應該在新的一週開始時重置數據集", function () {
|
|
98
|
+
var fridayData = {
|
|
99
|
+
o: 100,
|
|
100
|
+
c: 101,
|
|
101
|
+
h: 102,
|
|
102
|
+
l: 99,
|
|
103
|
+
t: 20230505,
|
|
104
|
+
v: 1000,
|
|
105
|
+
};
|
|
106
|
+
var mondayData = {
|
|
107
|
+
o: 101,
|
|
108
|
+
c: 102,
|
|
109
|
+
h: 103,
|
|
110
|
+
l: 100,
|
|
111
|
+
t: 20230508,
|
|
112
|
+
v: 1100,
|
|
113
|
+
};
|
|
51
114
|
var result = week.init(fridayData);
|
|
52
|
-
result = week.next(fridayData, result);
|
|
53
115
|
result = week.next(mondayData, result);
|
|
54
116
|
expect(result.dataset).toHaveLength(1);
|
|
55
117
|
expect(result.dataset[0]).toEqual(mondayData);
|
package/dist/umd/index.js
CHANGED
|
@@ -178,48 +178,25 @@
|
|
|
178
178
|
}
|
|
179
179
|
return troughs;
|
|
180
180
|
}
|
|
181
|
-
function SwingExtremes(y,
|
|
181
|
+
function SwingExtremes(y, level) {
|
|
182
182
|
if (level === void 0) { level = 1; }
|
|
183
|
-
|
|
184
|
-
var
|
|
185
|
-
var
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
else
|
|
198
|
-
result.push(indexs[i]);
|
|
199
|
-
}
|
|
200
|
-
return result;
|
|
201
|
-
}
|
|
202
|
-
if (type === exports.SwingExtremesType.Trough) {
|
|
203
|
-
var result = [];
|
|
204
|
-
var indexs = findTroughByGradient(y, level);
|
|
205
|
-
result.push(indexs[0]);
|
|
206
|
-
for (var i = 1; i < indexs.length; i++) {
|
|
207
|
-
if (y[indexs[i]] < y[result[result.length - 1]] &&
|
|
208
|
-
y[indexs[i]] < y[result[result.length - 2]]) {
|
|
209
|
-
result[result.length - 1] = indexs[i];
|
|
210
|
-
}
|
|
211
|
-
else if (y[indexs[i + 1]] > y[i] &&
|
|
212
|
-
y[indexs[i]] < y[result[result.length - 1]]) {
|
|
213
|
-
result.pop();
|
|
214
|
-
result.push(indexs[i]);
|
|
215
|
-
}
|
|
216
|
-
else
|
|
217
|
-
result.push(indexs[i]);
|
|
218
|
-
}
|
|
219
|
-
return result;
|
|
183
|
+
try {
|
|
184
|
+
var peaks = findPeaksByGradient(y, level);
|
|
185
|
+
var peakObjs = peaks.map(function (index) { return ({
|
|
186
|
+
index: index,
|
|
187
|
+
type: exports.SwingExtremesType.Peak,
|
|
188
|
+
}); });
|
|
189
|
+
var troughs = findTroughByGradient(y, level);
|
|
190
|
+
var troughObjs = troughs.map(function (index) { return ({
|
|
191
|
+
index: index,
|
|
192
|
+
type: exports.SwingExtremesType.Trough,
|
|
193
|
+
}); });
|
|
194
|
+
var merge = peakObjs.concat(troughObjs);
|
|
195
|
+
return merge.sort(function (a, b) { return a.index - b.index; });
|
|
220
196
|
}
|
|
221
|
-
|
|
222
|
-
|
|
197
|
+
catch (err) {
|
|
198
|
+
console.error(err);
|
|
199
|
+
return [];
|
|
223
200
|
}
|
|
224
201
|
}
|
|
225
202
|
|
|
@@ -1295,7 +1272,7 @@
|
|
|
1295
1272
|
};
|
|
1296
1273
|
return __assign$2.apply(this, arguments);
|
|
1297
1274
|
};
|
|
1298
|
-
var __spreadArray
|
|
1275
|
+
var __spreadArray = (undefined && undefined.__spreadArray) || function (to, from, pack) {
|
|
1299
1276
|
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
1300
1277
|
if (ar || !(i in from)) {
|
|
1301
1278
|
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
@@ -1345,7 +1322,7 @@
|
|
|
1345
1322
|
var sum = obvList.reduce(function (pre, current) { return pre + current; }, 0);
|
|
1346
1323
|
var vma = Math.round((sum / type) * 100) / 100;
|
|
1347
1324
|
return {
|
|
1348
|
-
dataset: __spreadArray
|
|
1325
|
+
dataset: __spreadArray(__spreadArray([], preList.dataset, true), [data], false),
|
|
1349
1326
|
obv: obv,
|
|
1350
1327
|
preClose: currentClose,
|
|
1351
1328
|
obvList: obvList,
|
|
@@ -1555,15 +1532,6 @@
|
|
|
1555
1532
|
}
|
|
1556
1533
|
}
|
|
1557
1534
|
|
|
1558
|
-
var __spreadArray = (undefined && undefined.__spreadArray) || function (to, from, pack) {
|
|
1559
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
1560
|
-
if (ar || !(i in from)) {
|
|
1561
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
1562
|
-
ar[i] = from[i];
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1565
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
1566
|
-
};
|
|
1567
1535
|
var Week = /** @class */ (function () {
|
|
1568
1536
|
function Week() {
|
|
1569
1537
|
}
|
|
@@ -1580,30 +1548,38 @@
|
|
|
1580
1548
|
configurable: true,
|
|
1581
1549
|
writable: true,
|
|
1582
1550
|
value: function (data, preList) {
|
|
1583
|
-
var year = data.t
|
|
1584
|
-
.toString()
|
|
1585
|
-
.replace(/^(\d{4})(\d{2})(\d{2})$/, "$1-$2-$3");
|
|
1586
|
-
var day = new Date(year).getDay();
|
|
1587
|
-
if (day === 6 || day === 0)
|
|
1588
|
-
return { dataset: preList.dataset, week: preList.week };
|
|
1589
1551
|
preList.dataset.push(data);
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
preList.dataset = [data];
|
|
1552
|
+
var index = 0;
|
|
1553
|
+
if (preList.dataset.length === 1)
|
|
1554
|
+
return preList;
|
|
1555
|
+
for (var i = 1; i < preList.dataset.length; i++) {
|
|
1556
|
+
var pre_day = new Date(preList.dataset[i - 1].t
|
|
1557
|
+
.toString()
|
|
1558
|
+
.replace(/^(\d{4})(\d{2})(\d{2})$/, "$1-$2-$3")).getDay();
|
|
1559
|
+
var curr_day = new Date(preList.dataset[i].t
|
|
1560
|
+
.toString()
|
|
1561
|
+
.replace(/^(\d{4})(\d{2})(\d{2})$/, "$1-$2-$3")).getDay();
|
|
1562
|
+
if (pre_day > curr_day) {
|
|
1563
|
+
index = i;
|
|
1564
|
+
break;
|
|
1604
1565
|
}
|
|
1605
|
-
return { dataset: preList.dataset, week: preList.week };
|
|
1606
1566
|
}
|
|
1567
|
+
// 以index拆分数组
|
|
1568
|
+
var week = preList.dataset.slice(0, index);
|
|
1569
|
+
var dataset = preList.dataset.slice(index);
|
|
1570
|
+
if (week.length > 0) {
|
|
1571
|
+
var weekData = {
|
|
1572
|
+
o: week[0]["o"],
|
|
1573
|
+
c: week[week.length - 1]["c"],
|
|
1574
|
+
t: week[week.length - 1]["t"],
|
|
1575
|
+
h: Math.max.apply(Math, week.map(function (item) { return item.h; })),
|
|
1576
|
+
l: Math.min.apply(Math, week.map(function (item) { return item.l; })),
|
|
1577
|
+
v: week.reduce(function (pre, current) { return pre + current.v; }, 0),
|
|
1578
|
+
};
|
|
1579
|
+
preList.week.push(weekData);
|
|
1580
|
+
}
|
|
1581
|
+
preList.dataset = dataset;
|
|
1582
|
+
return preList;
|
|
1607
1583
|
}
|
|
1608
1584
|
});
|
|
1609
1585
|
return Week;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ch20026103/anysis",
|
|
3
|
-
"version": "0.0.16
|
|
3
|
+
"version": "0.0.16",
|
|
4
4
|
"description": "provide many analyze methods in the library.",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"bugs": "git@github.com:cosmic1330/anysis/issues",
|
|
@@ -12,6 +12,21 @@
|
|
|
12
12
|
"module": "dist/esm/index.js",
|
|
13
13
|
"browser": "dist/umd/index.js",
|
|
14
14
|
"types": "dist/esm/index.d.ts",
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "pnpm clean && pnpm build:esm && pnpm build:cjs && pnpm build:umd",
|
|
17
|
+
"build:cjs": "tsc --module commonjs --target es5 --outDir dist/cjs",
|
|
18
|
+
"build:esm": "tsc --module esnext --target es5 --outDir dist/esm",
|
|
19
|
+
"build:umd": "rollup dist/esm/index.js --file dist/umd/index.js --format umd --name anysis",
|
|
20
|
+
"clean": "rimraf dist",
|
|
21
|
+
"lint": "eslint --fix \"**/*.{js,jsx,ts,tsx,mjs}\"",
|
|
22
|
+
"prepare": "pnpm exec husky install",
|
|
23
|
+
"prettier": "pnpm exec prettier --write .",
|
|
24
|
+
"prepublishOnly": "pnpm build",
|
|
25
|
+
"published": "npm publish",
|
|
26
|
+
"unpublished": "npm unpublish --force --registry http://localhost:4873 ",
|
|
27
|
+
"test": "vitest",
|
|
28
|
+
"demo": "node demo/main.js"
|
|
29
|
+
},
|
|
15
30
|
"lint-staged": {
|
|
16
31
|
"*.{js,jsx,ts,tsx,mjs}": [
|
|
17
32
|
"pnpm lint"
|
|
@@ -42,18 +57,5 @@
|
|
|
42
57
|
},
|
|
43
58
|
"vota": {
|
|
44
59
|
"node": "16.11.0"
|
|
45
|
-
},
|
|
46
|
-
"scripts": {
|
|
47
|
-
"build": "pnpm clean && pnpm build:esm && pnpm build:cjs && pnpm build:umd",
|
|
48
|
-
"build:cjs": "tsc --module commonjs --target es5 --outDir dist/cjs",
|
|
49
|
-
"build:esm": "tsc --module esnext --target es5 --outDir dist/esm",
|
|
50
|
-
"build:umd": "rollup dist/esm/index.js --file dist/umd/index.js --format umd --name anysis",
|
|
51
|
-
"clean": "rimraf dist",
|
|
52
|
-
"lint": "eslint --fix \"**/*.{js,jsx,ts,tsx,mjs}\"",
|
|
53
|
-
"prettier": "pnpm exec prettier --write .",
|
|
54
|
-
"published": "npm publish",
|
|
55
|
-
"unpublished": "npm unpublish --force --registry http://localhost:4873 ",
|
|
56
|
-
"test": "vitest",
|
|
57
|
-
"demo": "node demo/main.js"
|
|
58
60
|
}
|
|
59
|
-
}
|
|
61
|
+
}
|