@ch20026103/anysis 0.0.12-alpha → 0.0.14-alpha
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 +14 -10
- package/dist/cjs/analyze/Slope/index.js +0 -1
- package/dist/cjs/analyze/Slope/slope.test.js +10 -0
- package/dist/cjs/analyze/SwingExtremes/index.d.ts +9 -0
- package/dist/cjs/analyze/SwingExtremes/index.js +107 -0
- package/dist/cjs/analyze/SwingExtremes/index.test.d.ts +1 -0
- package/dist/cjs/analyze/SwingExtremes/index.test.js +26 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.js +12 -7
- package/dist/cjs/stockSkills/boll.d.ts +5 -4
- package/dist/cjs/stockSkills/boll.js +0 -1
- package/dist/cjs/stockSkills/ema.d.ts +32 -0
- package/dist/cjs/stockSkills/ema.js +38 -0
- package/dist/cjs/stockSkills/ema.test.js +11 -0
- package/dist/cjs/stockSkills/gold.d.ts +12 -11
- package/dist/cjs/stockSkills/gold.js +1 -14
- package/dist/cjs/stockSkills/gold.test.js +8 -10
- package/dist/esm/analyze/Slope/index.js +0 -1
- package/dist/esm/analyze/Slope/slope.test.js +10 -0
- package/dist/esm/analyze/SwingExtremes/index.d.ts +9 -0
- package/dist/esm/analyze/SwingExtremes/index.js +101 -0
- package/dist/esm/analyze/SwingExtremes/index.test.d.ts +1 -0
- package/dist/esm/analyze/SwingExtremes/index.test.js +24 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/stockSkills/boll.d.ts +5 -4
- package/dist/esm/stockSkills/boll.js +0 -1
- package/dist/esm/stockSkills/ema.d.ts +32 -0
- package/dist/esm/stockSkills/ema.js +38 -0
- package/dist/esm/stockSkills/ema.test.js +11 -0
- package/dist/esm/stockSkills/gold.d.ts +12 -11
- package/dist/esm/stockSkills/gold.js +1 -14
- package/dist/esm/stockSkills/gold.test.js +8 -10
- package/dist/umd/index.js +144 -16
- package/package.json +15 -17
package/demo/main.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
/* eslint @typescript-eslint/no-var-requires: "off" */
|
|
2
2
|
const axios = require("axios");
|
|
3
|
-
const {
|
|
4
|
-
|
|
3
|
+
const {
|
|
4
|
+
Gold,
|
|
5
|
+
SwingExtremesType,
|
|
6
|
+
SwingExtremes,
|
|
7
|
+
} = require("../dist/cjs/index.js");
|
|
8
|
+
|
|
9
|
+
const gold = new Gold();
|
|
5
10
|
function DemoDay(stockId) {
|
|
6
11
|
axios
|
|
7
12
|
.get(
|
|
@@ -11,14 +16,13 @@ function DemoDay(stockId) {
|
|
|
11
16
|
res = res.data.replace(/^\(|\);$/g, "");
|
|
12
17
|
let parse = JSON.parse(res);
|
|
13
18
|
let data = parse.ta;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
console.log(williams18Data);
|
|
19
|
+
const sortArray = [];
|
|
20
|
+
const hightPoints = SwingExtremes(data.map((data) => data.h), SwingExtremesType.Peak, 1);
|
|
21
|
+
const lowerPoints = SwingExtremes(data.map((data) => data.l), SwingExtremesType.Trough, 1);
|
|
22
|
+
console.log(hightPoints.map((item) => data[item]));
|
|
23
|
+
sortArray.push(...hightPoints);
|
|
24
|
+
sortArray.push(...lowerPoints);
|
|
25
|
+
sortArray.sort((a, b) => a - b);
|
|
22
26
|
})
|
|
23
27
|
.catch((error) => {
|
|
24
28
|
console.error(error);
|
|
@@ -5,7 +5,6 @@ function Slope(y) {
|
|
|
5
5
|
// 計算 x 和 y 的平均值
|
|
6
6
|
var y_mean = y.reduce(function (acc, cur) { return acc + cur; }) / y.length;
|
|
7
7
|
var increment = (0, calculateDivisionFactor_1.default)(y_mean);
|
|
8
|
-
console.log(y_mean, increment);
|
|
9
8
|
var x = Array.from({ length: y.length }, function (_, index) { return index * increment; });
|
|
10
9
|
var x_mean = x.reduce(function (acc, cur) { return acc + cur; }) / x.length;
|
|
11
10
|
// 計算斜率
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var simpleRegressoinModel_1 = require("../Regression/simpleRegressoinModel");
|
|
3
4
|
var index_1 = require("./index");
|
|
4
5
|
describe("test Slope methods", function () {
|
|
5
6
|
it("test 123456", function () {
|
|
@@ -27,4 +28,13 @@ describe("test Slope methods", function () {
|
|
|
27
28
|
var slope = (0, index_1.default)(y);
|
|
28
29
|
expect(slope).toEqual(2.142857142857143);
|
|
29
30
|
});
|
|
31
|
+
it("test simple regression", function () {
|
|
32
|
+
var y = [50, 30, 10, 60, 70, 40, 100];
|
|
33
|
+
var x = Array.from({ length: y.length }, function (_, index) { return index; });
|
|
34
|
+
var res = (0, simpleRegressoinModel_1.default)(x, y);
|
|
35
|
+
var new_y = x.map(function (y) { return res.predictModel(y); });
|
|
36
|
+
expect(res.description).toEqual("Y=26.785714285714292+8.214285714285714X");
|
|
37
|
+
var slope = (0, index_1.default)(new_y);
|
|
38
|
+
expect(slope).toEqual(0.8214285714285714);
|
|
39
|
+
});
|
|
30
40
|
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare enum SwingExtremesType {
|
|
2
|
+
Peak = "Peak",
|
|
3
|
+
Trough = "Trough"
|
|
4
|
+
}
|
|
5
|
+
type Index = number;
|
|
6
|
+
export declare function findPeaksByGradient(prices: number[], level?: number): Index[];
|
|
7
|
+
export declare function findTroughByGradient(prices: number[], level?: number): Index[];
|
|
8
|
+
export declare function SwingExtremes(y: number[], type: SwingExtremesType, level?: number): Index[];
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SwingExtremes = exports.findTroughByGradient = exports.findPeaksByGradient = exports.SwingExtremesType = void 0;
|
|
4
|
+
var SwingExtremesType;
|
|
5
|
+
(function (SwingExtremesType) {
|
|
6
|
+
SwingExtremesType["Peak"] = "Peak";
|
|
7
|
+
SwingExtremesType["Trough"] = "Trough";
|
|
8
|
+
})(SwingExtremesType = exports.SwingExtremesType || (exports.SwingExtremesType = {}));
|
|
9
|
+
function findPeaksByGradient(prices, level) {
|
|
10
|
+
if (level === void 0) { level = 1; }
|
|
11
|
+
var peaks = [];
|
|
12
|
+
for (var i = 1; i < prices.length - 1; i++) {
|
|
13
|
+
if (level === 1) {
|
|
14
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
15
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
16
|
+
if (prevGradient > 0 && nextGradient < 0) {
|
|
17
|
+
peaks.push(i);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else if (level === 2) {
|
|
21
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
22
|
+
var prev2Gradient = prices[i] - prices[i - 2];
|
|
23
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
24
|
+
var next2Gradient = prices[i + 2] - prices[i];
|
|
25
|
+
if (prevGradient > 0 &&
|
|
26
|
+
prev2Gradient > 0 &&
|
|
27
|
+
nextGradient < 0 &&
|
|
28
|
+
next2Gradient < 0) {
|
|
29
|
+
peaks.push(i);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return peaks;
|
|
34
|
+
}
|
|
35
|
+
exports.findPeaksByGradient = findPeaksByGradient;
|
|
36
|
+
function findTroughByGradient(prices, level) {
|
|
37
|
+
if (level === void 0) { level = 1; }
|
|
38
|
+
var troughs = [];
|
|
39
|
+
for (var i = 1; i < prices.length - 1; i++) {
|
|
40
|
+
if (level === 1) {
|
|
41
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
42
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
43
|
+
if (prevGradient < 0 && nextGradient > 0) {
|
|
44
|
+
troughs.push(i);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else if (level === 2) {
|
|
48
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
49
|
+
var prev2Gradient = prices[i] - prices[i - 2];
|
|
50
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
51
|
+
var next2Gradient = prices[i + 2] - prices[i];
|
|
52
|
+
if (prevGradient < 0 &&
|
|
53
|
+
prev2Gradient < 0 &&
|
|
54
|
+
nextGradient > 0 &&
|
|
55
|
+
next2Gradient > 0) {
|
|
56
|
+
troughs.push(i);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return troughs;
|
|
61
|
+
}
|
|
62
|
+
exports.findTroughByGradient = findTroughByGradient;
|
|
63
|
+
function SwingExtremes(y, type, level) {
|
|
64
|
+
if (level === void 0) { level = 1; }
|
|
65
|
+
if (type === SwingExtremesType.Peak) {
|
|
66
|
+
var result = [];
|
|
67
|
+
var indexs = findPeaksByGradient(y, level);
|
|
68
|
+
result.push(indexs[0]);
|
|
69
|
+
for (var i = 1; i < indexs.length; i++) {
|
|
70
|
+
if (y[indexs[i]] > y[result[result.length - 1]] &&
|
|
71
|
+
y[indexs[i]] > y[result[result.length - 2]]) {
|
|
72
|
+
result[result.length - 1] = indexs[i];
|
|
73
|
+
}
|
|
74
|
+
else if (y[indexs[i + 1]] < y[i] &&
|
|
75
|
+
y[indexs[i]] > y[result[result.length - 1]]) {
|
|
76
|
+
result.pop();
|
|
77
|
+
result.push(indexs[i]);
|
|
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;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
throw new Error("Invalid SwingExtremesType");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.SwingExtremes = SwingExtremes;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var index_1 = require("./index");
|
|
4
|
+
describe("test SwingExtremes", function () {
|
|
5
|
+
var prices;
|
|
6
|
+
beforeEach(function () {
|
|
7
|
+
prices = [10, 12, 11, 13, 15, 14, 16, 10, 8, 9, 11, 7, 5, 8, 4, 5];
|
|
8
|
+
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15
|
|
9
|
+
});
|
|
10
|
+
it("test findPeaksByGradient", function () {
|
|
11
|
+
var res = (0, index_1.findPeaksByGradient)(prices);
|
|
12
|
+
expect(res).toEqual([1, 4, 6, 10, 13]);
|
|
13
|
+
});
|
|
14
|
+
it("test findTroughByGradient", function () {
|
|
15
|
+
var res = (0, index_1.findTroughByGradient)(prices);
|
|
16
|
+
expect(res).toEqual([2, 5, 8, 12, 14]);
|
|
17
|
+
});
|
|
18
|
+
it("test SwingExtremes Peak", function () {
|
|
19
|
+
var res = (0, index_1.SwingExtremes)(prices, index_1.SwingExtremesType.Peak);
|
|
20
|
+
expect(res).toEqual([1, 6, 10, 13]);
|
|
21
|
+
});
|
|
22
|
+
it("test SwingExtremes Trough", function () {
|
|
23
|
+
var res = (0, index_1.SwingExtremes)(prices, index_1.SwingExtremesType.Trough);
|
|
24
|
+
expect(res).toEqual([2, 14]);
|
|
25
|
+
});
|
|
26
|
+
});
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
export { default as Angle } from "./analyze/Angle/index.js";
|
|
2
2
|
export { default as simpleRegressionModel } from "./analyze/Regression/simpleRegressoinModel.js";
|
|
3
3
|
export { default as slope } from "./analyze/Slope/index.js";
|
|
4
|
+
export { SwingExtremes, SwingExtremesType, findPeaksByGradient, findTroughByGradient, } from "./analyze/SwingExtremes/index.js";
|
|
4
5
|
export { exponentialSmoothing, movingAverages, weightMovingAverages, } from "./analyze/TimeSeries/R/index.js";
|
|
5
6
|
export { calcSeasonalIndicesNoTrend } from "./analyze/TimeSeries/RS/index.js";
|
|
6
7
|
export { default as Boll } from "./stockSkills/boll.js";
|
|
8
|
+
export type { BollResType } from "./stockSkills/boll.js";
|
|
7
9
|
export { default as Ema } from "./stockSkills/ema.js";
|
|
8
10
|
export { default as Gold } from "./stockSkills/gold.js";
|
|
11
|
+
export type { GetGoldResType } from "./stockSkills/gold.js";
|
|
9
12
|
export { default as Kd } from "./stockSkills/kd.js";
|
|
10
13
|
export { default as Ma } from "./stockSkills/ma.js";
|
|
11
14
|
export { default as Macd } from "./stockSkills/macd.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.Williams = exports.Vma = exports.getWeekLine = 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.slope = exports.simpleRegressionModel = exports.Angle = void 0;
|
|
3
|
+
exports.parseLsusbOutput = exports.isJSON = exports.calculateDivisionFactor = exports.minus = exports.add = exports.Williams = exports.Vma = exports.getWeekLine = 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副檔名**
|
|
@@ -12,12 +12,17 @@ var simpleRegressoinModel_js_1 = require("./analyze/Regression/simpleRegressoinM
|
|
|
12
12
|
Object.defineProperty(exports, "simpleRegressionModel", { enumerable: true, get: function () { return simpleRegressoinModel_js_1.default; } });
|
|
13
13
|
var index_js_2 = require("./analyze/Slope/index.js");
|
|
14
14
|
Object.defineProperty(exports, "slope", { enumerable: true, get: function () { return index_js_2.default; } });
|
|
15
|
-
var index_js_3 = require("./analyze/
|
|
16
|
-
Object.defineProperty(exports, "
|
|
17
|
-
Object.defineProperty(exports, "
|
|
18
|
-
Object.defineProperty(exports, "
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
var index_js_3 = require("./analyze/SwingExtremes/index.js");
|
|
16
|
+
Object.defineProperty(exports, "SwingExtremes", { enumerable: true, get: function () { return index_js_3.SwingExtremes; } });
|
|
17
|
+
Object.defineProperty(exports, "SwingExtremesType", { enumerable: true, get: function () { return index_js_3.SwingExtremesType; } });
|
|
18
|
+
Object.defineProperty(exports, "findPeaksByGradient", { enumerable: true, get: function () { return index_js_3.findPeaksByGradient; } });
|
|
19
|
+
Object.defineProperty(exports, "findTroughByGradient", { enumerable: true, get: function () { return index_js_3.findTroughByGradient; } });
|
|
20
|
+
var index_js_4 = require("./analyze/TimeSeries/R/index.js");
|
|
21
|
+
Object.defineProperty(exports, "exponentialSmoothing", { enumerable: true, get: function () { return index_js_4.exponentialSmoothing; } });
|
|
22
|
+
Object.defineProperty(exports, "movingAverages", { enumerable: true, get: function () { return index_js_4.movingAverages; } });
|
|
23
|
+
Object.defineProperty(exports, "weightMovingAverages", { enumerable: true, get: function () { return index_js_4.weightMovingAverages; } });
|
|
24
|
+
var index_js_5 = require("./analyze/TimeSeries/RS/index.js");
|
|
25
|
+
Object.defineProperty(exports, "calcSeasonalIndicesNoTrend", { enumerable: true, get: function () { return index_js_5.calcSeasonalIndicesNoTrend; } });
|
|
21
26
|
var boll_js_1 = require("./stockSkills/boll.js");
|
|
22
27
|
Object.defineProperty(exports, "Boll", { enumerable: true, get: function () { return boll_js_1.default; } });
|
|
23
28
|
var ema_js_1 = require("./stockSkills/ema.js");
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
type ItemType = {
|
|
2
2
|
c: number;
|
|
3
|
+
[key: string]: unknown;
|
|
3
4
|
};
|
|
4
5
|
type ListType = ItemType[];
|
|
5
|
-
type
|
|
6
|
-
|
|
6
|
+
export type BollResType = {
|
|
7
|
+
[key: string]: unknown;
|
|
7
8
|
bollMa: number | null;
|
|
8
9
|
bollUb: number | null;
|
|
9
10
|
bollLb: number | null;
|
|
@@ -26,7 +27,7 @@ interface BollType {
|
|
|
26
27
|
bollUb: number | null;
|
|
27
28
|
bollLb: number | null;
|
|
28
29
|
};
|
|
29
|
-
getBoll: (list: ListType, type: number) =>
|
|
30
|
+
getBoll: (list: ListType, type: number) => BollResType;
|
|
30
31
|
}
|
|
31
32
|
export default class Boll implements BollType {
|
|
32
33
|
init(data: ItemType): {
|
|
@@ -53,6 +54,6 @@ export default class Boll implements BollType {
|
|
|
53
54
|
bollUb: number;
|
|
54
55
|
bollLb: number;
|
|
55
56
|
};
|
|
56
|
-
getBoll(list: ListType, type: number):
|
|
57
|
+
getBoll(list: ListType, type: number): BollResType;
|
|
57
58
|
}
|
|
58
59
|
export {};
|
|
@@ -76,7 +76,6 @@ var Boll = /** @class */ (function () {
|
|
|
76
76
|
var sumMa = list
|
|
77
77
|
.slice(i - (type - 1), i + 1)
|
|
78
78
|
.reduce(function (pre, current) { return pre + current.c; }, 0);
|
|
79
|
-
console.log("sumMa", sumMa);
|
|
80
79
|
var bollMa_2 = Math.round((sumMa / type) * 100) / 100;
|
|
81
80
|
// 標準差
|
|
82
81
|
var difference = res
|
|
@@ -1,8 +1,40 @@
|
|
|
1
|
+
type ItemType = {
|
|
2
|
+
c: number;
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
};
|
|
5
|
+
type ListType = ItemType[];
|
|
1
6
|
interface EmaType {
|
|
7
|
+
init: (data: ItemType, type: number) => {
|
|
8
|
+
dataset: ListType;
|
|
9
|
+
ema: number;
|
|
10
|
+
type: number;
|
|
11
|
+
};
|
|
12
|
+
next: (data: ItemType, preList: {
|
|
13
|
+
dataset: ListType;
|
|
14
|
+
ema: number;
|
|
15
|
+
type: number;
|
|
16
|
+
}, type: number) => {
|
|
17
|
+
dataset: ListType;
|
|
18
|
+
ema: number;
|
|
19
|
+
type: number;
|
|
20
|
+
};
|
|
2
21
|
getStartEma: (list: number[], period: number) => number;
|
|
3
22
|
getEma: (list: number[], period: number) => (number | null)[];
|
|
4
23
|
}
|
|
5
24
|
export default class Ema implements EmaType {
|
|
25
|
+
init(data: ItemType, type: number): {
|
|
26
|
+
dataset: ListType;
|
|
27
|
+
ema: number;
|
|
28
|
+
type: number;
|
|
29
|
+
};
|
|
30
|
+
next(data: ItemType, preList: {
|
|
31
|
+
dataset: ListType;
|
|
32
|
+
ema: number;
|
|
33
|
+
}, type: number): {
|
|
34
|
+
dataset: ListType;
|
|
35
|
+
ema: number;
|
|
36
|
+
type: number;
|
|
37
|
+
};
|
|
6
38
|
getStartEma(list: number[], period: number): number;
|
|
7
39
|
getEma(list: number[], period: number): (number | null)[];
|
|
8
40
|
}
|
|
@@ -3,6 +3,44 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
var Ema = /** @class */ (function () {
|
|
4
4
|
function Ema() {
|
|
5
5
|
}
|
|
6
|
+
Object.defineProperty(Ema.prototype, "init", {
|
|
7
|
+
enumerable: false,
|
|
8
|
+
configurable: true,
|
|
9
|
+
writable: true,
|
|
10
|
+
value: function (data, type) {
|
|
11
|
+
return { dataset: [data], ema: 0, type: type };
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(Ema.prototype, "next", {
|
|
15
|
+
enumerable: false,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: function (data, preList, type) {
|
|
19
|
+
preList.dataset.push(data);
|
|
20
|
+
if (preList.dataset.length < type) {
|
|
21
|
+
return {
|
|
22
|
+
dataset: preList.dataset,
|
|
23
|
+
ema: 0,
|
|
24
|
+
type: type,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
else if (preList.dataset.length === type) {
|
|
28
|
+
var sum = preList.dataset.reduce(function (pre, current) { return pre + current.c; }, 0);
|
|
29
|
+
return {
|
|
30
|
+
dataset: preList.dataset,
|
|
31
|
+
ema: sum / type,
|
|
32
|
+
type: type,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
if (preList.dataset.length > type) {
|
|
37
|
+
preList.dataset.shift();
|
|
38
|
+
}
|
|
39
|
+
var ema = (data.c * 2 + (type - 1) * preList.ema) / (type + 1);
|
|
40
|
+
return { dataset: preList.dataset, ema: ema, type: type };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
6
44
|
Object.defineProperty(Ema.prototype, "getStartEma", {
|
|
7
45
|
enumerable: false,
|
|
8
46
|
configurable: true,
|
|
@@ -3,6 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
var ema_1 = require("./ema");
|
|
4
4
|
var test_data_test_1 = require("./test_data.test");
|
|
5
5
|
describe("test ema methods", function () {
|
|
6
|
+
it("test init & next", function () {
|
|
7
|
+
var index = test_data_test_1.default.length - 1;
|
|
8
|
+
var ema = new ema_1.default();
|
|
9
|
+
var init = ema.init(test_data_test_1.default[0], 5);
|
|
10
|
+
var res = init;
|
|
11
|
+
for (var i = 1; i <= index; i++) {
|
|
12
|
+
var item = test_data_test_1.default[i];
|
|
13
|
+
res = ema.next(item, res, 5);
|
|
14
|
+
}
|
|
15
|
+
expect(res.ema).toEqual(141.83482746491333);
|
|
16
|
+
});
|
|
6
17
|
it("test getEma5()", function () {
|
|
7
18
|
var ema = new ema_1.default();
|
|
8
19
|
var res = ema.getEma(test_data_test_1.default.map(function (item) { return item.c; }), 5);
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
type
|
|
2
|
-
highestPointDate: number;
|
|
3
|
-
lowestPointDate: number;
|
|
1
|
+
export type GetGoldResType = {
|
|
4
2
|
lowestPoint: number;
|
|
5
3
|
highestPoint: number;
|
|
6
4
|
superStrong: number;
|
|
@@ -15,33 +13,36 @@ type ListType = {
|
|
|
15
13
|
o: number;
|
|
16
14
|
c: number;
|
|
17
15
|
l: number;
|
|
16
|
+
[key: string]: unknown;
|
|
18
17
|
}[];
|
|
19
|
-
type
|
|
18
|
+
type FindHightestResType = {
|
|
20
19
|
[key: string]: {
|
|
21
20
|
h: number;
|
|
22
21
|
t: number;
|
|
23
22
|
o: number;
|
|
24
23
|
c: number;
|
|
25
24
|
l: number;
|
|
25
|
+
[key: string]: unknown;
|
|
26
26
|
};
|
|
27
27
|
};
|
|
28
|
-
type
|
|
28
|
+
type FindLowestResType = {
|
|
29
29
|
[key: string]: {
|
|
30
30
|
h: number;
|
|
31
31
|
t: number;
|
|
32
32
|
o: number;
|
|
33
33
|
c: number;
|
|
34
34
|
l: number;
|
|
35
|
+
[key: string]: unknown;
|
|
35
36
|
};
|
|
36
37
|
};
|
|
37
38
|
interface GoldType {
|
|
38
|
-
findHighPoint: (list: ListType) =>
|
|
39
|
-
findLowPoint: (list: ListType) =>
|
|
40
|
-
getGold: (
|
|
39
|
+
findHighPoint: (list: ListType) => FindHightestResType;
|
|
40
|
+
findLowPoint: (list: ListType) => FindLowestResType;
|
|
41
|
+
getGold: (highestPoint: number, lowestPoint: number) => GetGoldResType;
|
|
41
42
|
}
|
|
42
43
|
export default class Gold implements GoldType {
|
|
43
|
-
findHighPoint(list: ListType):
|
|
44
|
-
findLowPoint(list: ListType):
|
|
45
|
-
getGold(
|
|
44
|
+
findHighPoint(list: ListType): FindHightestResType;
|
|
45
|
+
findLowPoint(list: ListType): FindLowestResType;
|
|
46
|
+
getGold(highestPoint: number, lowestPoint: number): GetGoldResType;
|
|
46
47
|
}
|
|
47
48
|
export {};
|
|
@@ -184,21 +184,8 @@ var Gold = /** @class */ (function () {
|
|
|
184
184
|
enumerable: false,
|
|
185
185
|
configurable: true,
|
|
186
186
|
writable: true,
|
|
187
|
-
value: function (
|
|
188
|
-
var hightPoints = this.findHighPoint(list);
|
|
189
|
-
var lowPoints = this.findLowPoint(list);
|
|
190
|
-
var lastHightPointDate = Object.keys(hightPoints).slice(-1)[0] !==
|
|
191
|
-
list[list.length - 1].t.toString()
|
|
192
|
-
? Object.keys(hightPoints).slice(-1)[0]
|
|
193
|
-
: Object.keys(hightPoints).slice(-2)[0];
|
|
194
|
-
var lastLowPointDate = Object.keys(lowPoints).slice(-1)[0] !== list[list.length - 1].t.toString()
|
|
195
|
-
? Object.keys(lowPoints).slice(-1)[0]
|
|
196
|
-
: Object.keys(lowPoints).slice(-2)[0];
|
|
197
|
-
var highestPoint = hightPoints[lastHightPointDate].h;
|
|
198
|
-
var lowestPoint = lowPoints[lastLowPointDate].l;
|
|
187
|
+
value: function (highestPoint, lowestPoint) {
|
|
199
188
|
var res = {
|
|
200
|
-
highestPointDate: parseInt(lastHightPointDate),
|
|
201
|
-
lowestPointDate: parseInt(lastLowPointDate),
|
|
202
189
|
lowestPoint: lowestPoint,
|
|
203
190
|
highestPoint: highestPoint,
|
|
204
191
|
superStrong: Math.round((highestPoint - (highestPoint - lowestPoint) * 0.191) * 100) / 100,
|
|
@@ -29,17 +29,15 @@ describe("test Gold methods", function () {
|
|
|
29
29
|
});
|
|
30
30
|
it("test getGold(", function () {
|
|
31
31
|
var gold = new gold_1.default();
|
|
32
|
-
var allGold = gold.getGold(
|
|
32
|
+
var allGold = gold.getGold(139, 89.1);
|
|
33
33
|
expect(allGold).toEqual({
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
middle:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
superWeak: 139.83,
|
|
42
|
-
weak: 145.65,
|
|
34
|
+
lowestPoint: 89.1,
|
|
35
|
+
highestPoint: 139,
|
|
36
|
+
superStrong: 129.47,
|
|
37
|
+
strong: 119.94,
|
|
38
|
+
middle: 114.05,
|
|
39
|
+
weak: 108.16,
|
|
40
|
+
superWeak: 98.63,
|
|
43
41
|
});
|
|
44
42
|
});
|
|
45
43
|
});
|
|
@@ -3,7 +3,6 @@ export default function Slope(y) {
|
|
|
3
3
|
// 計算 x 和 y 的平均值
|
|
4
4
|
var y_mean = y.reduce(function (acc, cur) { return acc + cur; }) / y.length;
|
|
5
5
|
var increment = calculateDivisionFactor(y_mean);
|
|
6
|
-
console.log(y_mean, increment);
|
|
7
6
|
var x = Array.from({ length: y.length }, function (_, index) { return index * increment; });
|
|
8
7
|
var x_mean = x.reduce(function (acc, cur) { return acc + cur; }) / x.length;
|
|
9
8
|
// 計算斜率
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import simpleRegressoinModel from "../Regression/simpleRegressoinModel";
|
|
1
2
|
import Slope from "./index";
|
|
2
3
|
describe("test Slope methods", function () {
|
|
3
4
|
it("test 123456", function () {
|
|
@@ -25,4 +26,13 @@ describe("test Slope methods", function () {
|
|
|
25
26
|
var slope = Slope(y);
|
|
26
27
|
expect(slope).toEqual(2.142857142857143);
|
|
27
28
|
});
|
|
29
|
+
it("test simple regression", function () {
|
|
30
|
+
var y = [50, 30, 10, 60, 70, 40, 100];
|
|
31
|
+
var x = Array.from({ length: y.length }, function (_, index) { return index; });
|
|
32
|
+
var res = simpleRegressoinModel(x, y);
|
|
33
|
+
var new_y = x.map(function (y) { return res.predictModel(y); });
|
|
34
|
+
expect(res.description).toEqual("Y=26.785714285714292+8.214285714285714X");
|
|
35
|
+
var slope = Slope(new_y);
|
|
36
|
+
expect(slope).toEqual(0.8214285714285714);
|
|
37
|
+
});
|
|
28
38
|
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare enum SwingExtremesType {
|
|
2
|
+
Peak = "Peak",
|
|
3
|
+
Trough = "Trough"
|
|
4
|
+
}
|
|
5
|
+
type Index = number;
|
|
6
|
+
export declare function findPeaksByGradient(prices: number[], level?: number): Index[];
|
|
7
|
+
export declare function findTroughByGradient(prices: number[], level?: number): Index[];
|
|
8
|
+
export declare function SwingExtremes(y: number[], type: SwingExtremesType, level?: number): Index[];
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
export var SwingExtremesType;
|
|
2
|
+
(function (SwingExtremesType) {
|
|
3
|
+
SwingExtremesType["Peak"] = "Peak";
|
|
4
|
+
SwingExtremesType["Trough"] = "Trough";
|
|
5
|
+
})(SwingExtremesType || (SwingExtremesType = {}));
|
|
6
|
+
export function findPeaksByGradient(prices, level) {
|
|
7
|
+
if (level === void 0) { level = 1; }
|
|
8
|
+
var peaks = [];
|
|
9
|
+
for (var i = 1; i < prices.length - 1; i++) {
|
|
10
|
+
if (level === 1) {
|
|
11
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
12
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
13
|
+
if (prevGradient > 0 && nextGradient < 0) {
|
|
14
|
+
peaks.push(i);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
else if (level === 2) {
|
|
18
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
19
|
+
var prev2Gradient = prices[i] - prices[i - 2];
|
|
20
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
21
|
+
var next2Gradient = prices[i + 2] - prices[i];
|
|
22
|
+
if (prevGradient > 0 &&
|
|
23
|
+
prev2Gradient > 0 &&
|
|
24
|
+
nextGradient < 0 &&
|
|
25
|
+
next2Gradient < 0) {
|
|
26
|
+
peaks.push(i);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return peaks;
|
|
31
|
+
}
|
|
32
|
+
export function findTroughByGradient(prices, level) {
|
|
33
|
+
if (level === void 0) { level = 1; }
|
|
34
|
+
var troughs = [];
|
|
35
|
+
for (var i = 1; i < prices.length - 1; i++) {
|
|
36
|
+
if (level === 1) {
|
|
37
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
38
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
39
|
+
if (prevGradient < 0 && nextGradient > 0) {
|
|
40
|
+
troughs.push(i);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else if (level === 2) {
|
|
44
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
45
|
+
var prev2Gradient = prices[i] - prices[i - 2];
|
|
46
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
47
|
+
var next2Gradient = prices[i + 2] - prices[i];
|
|
48
|
+
if (prevGradient < 0 &&
|
|
49
|
+
prev2Gradient < 0 &&
|
|
50
|
+
nextGradient > 0 &&
|
|
51
|
+
next2Gradient > 0) {
|
|
52
|
+
troughs.push(i);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return troughs;
|
|
57
|
+
}
|
|
58
|
+
export function SwingExtremes(y, type, level) {
|
|
59
|
+
if (level === void 0) { level = 1; }
|
|
60
|
+
if (type === SwingExtremesType.Peak) {
|
|
61
|
+
var result = [];
|
|
62
|
+
var indexs = findPeaksByGradient(y, level);
|
|
63
|
+
result.push(indexs[0]);
|
|
64
|
+
for (var i = 1; i < indexs.length; i++) {
|
|
65
|
+
if (y[indexs[i]] > y[result[result.length - 1]] &&
|
|
66
|
+
y[indexs[i]] > y[result[result.length - 2]]) {
|
|
67
|
+
result[result.length - 1] = indexs[i];
|
|
68
|
+
}
|
|
69
|
+
else if (y[indexs[i + 1]] < y[i] &&
|
|
70
|
+
y[indexs[i]] > y[result[result.length - 1]]) {
|
|
71
|
+
result.pop();
|
|
72
|
+
result.push(indexs[i]);
|
|
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;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
throw new Error("Invalid SwingExtremesType");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { findPeaksByGradient, findTroughByGradient, SwingExtremes, SwingExtremesType, } from "./index";
|
|
2
|
+
describe("test SwingExtremes", function () {
|
|
3
|
+
var prices;
|
|
4
|
+
beforeEach(function () {
|
|
5
|
+
prices = [10, 12, 11, 13, 15, 14, 16, 10, 8, 9, 11, 7, 5, 8, 4, 5];
|
|
6
|
+
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15
|
|
7
|
+
});
|
|
8
|
+
it("test findPeaksByGradient", function () {
|
|
9
|
+
var res = findPeaksByGradient(prices);
|
|
10
|
+
expect(res).toEqual([1, 4, 6, 10, 13]);
|
|
11
|
+
});
|
|
12
|
+
it("test findTroughByGradient", function () {
|
|
13
|
+
var res = findTroughByGradient(prices);
|
|
14
|
+
expect(res).toEqual([2, 5, 8, 12, 14]);
|
|
15
|
+
});
|
|
16
|
+
it("test SwingExtremes Peak", function () {
|
|
17
|
+
var res = SwingExtremes(prices, SwingExtremesType.Peak);
|
|
18
|
+
expect(res).toEqual([1, 6, 10, 13]);
|
|
19
|
+
});
|
|
20
|
+
it("test SwingExtremes Trough", function () {
|
|
21
|
+
var res = SwingExtremes(prices, SwingExtremesType.Trough);
|
|
22
|
+
expect(res).toEqual([2, 14]);
|
|
23
|
+
});
|
|
24
|
+
});
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
export { default as Angle } from "./analyze/Angle/index.js";
|
|
2
2
|
export { default as simpleRegressionModel } from "./analyze/Regression/simpleRegressoinModel.js";
|
|
3
3
|
export { default as slope } from "./analyze/Slope/index.js";
|
|
4
|
+
export { SwingExtremes, SwingExtremesType, findPeaksByGradient, findTroughByGradient, } from "./analyze/SwingExtremes/index.js";
|
|
4
5
|
export { exponentialSmoothing, movingAverages, weightMovingAverages, } from "./analyze/TimeSeries/R/index.js";
|
|
5
6
|
export { calcSeasonalIndicesNoTrend } from "./analyze/TimeSeries/RS/index.js";
|
|
6
7
|
export { default as Boll } from "./stockSkills/boll.js";
|
|
8
|
+
export type { BollResType } from "./stockSkills/boll.js";
|
|
7
9
|
export { default as Ema } from "./stockSkills/ema.js";
|
|
8
10
|
export { default as Gold } from "./stockSkills/gold.js";
|
|
11
|
+
export type { GetGoldResType } from "./stockSkills/gold.js";
|
|
9
12
|
export { default as Kd } from "./stockSkills/kd.js";
|
|
10
13
|
export { default as Ma } from "./stockSkills/ma.js";
|
|
11
14
|
export { default as Macd } from "./stockSkills/macd.js";
|
package/dist/esm/index.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
export { default as Angle } from "./analyze/Angle/index.js";
|
|
7
7
|
export { default as simpleRegressionModel } from "./analyze/Regression/simpleRegressoinModel.js";
|
|
8
8
|
export { default as slope } from "./analyze/Slope/index.js";
|
|
9
|
+
export { SwingExtremes, SwingExtremesType, findPeaksByGradient, findTroughByGradient, } from "./analyze/SwingExtremes/index.js";
|
|
9
10
|
export { exponentialSmoothing, movingAverages, weightMovingAverages, } from "./analyze/TimeSeries/R/index.js";
|
|
10
11
|
export { calcSeasonalIndicesNoTrend } from "./analyze/TimeSeries/RS/index.js";
|
|
11
12
|
export { default as Boll } from "./stockSkills/boll.js";
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
type ItemType = {
|
|
2
2
|
c: number;
|
|
3
|
+
[key: string]: unknown;
|
|
3
4
|
};
|
|
4
5
|
type ListType = ItemType[];
|
|
5
|
-
type
|
|
6
|
-
|
|
6
|
+
export type BollResType = {
|
|
7
|
+
[key: string]: unknown;
|
|
7
8
|
bollMa: number | null;
|
|
8
9
|
bollUb: number | null;
|
|
9
10
|
bollLb: number | null;
|
|
@@ -26,7 +27,7 @@ interface BollType {
|
|
|
26
27
|
bollUb: number | null;
|
|
27
28
|
bollLb: number | null;
|
|
28
29
|
};
|
|
29
|
-
getBoll: (list: ListType, type: number) =>
|
|
30
|
+
getBoll: (list: ListType, type: number) => BollResType;
|
|
30
31
|
}
|
|
31
32
|
export default class Boll implements BollType {
|
|
32
33
|
init(data: ItemType): {
|
|
@@ -53,6 +54,6 @@ export default class Boll implements BollType {
|
|
|
53
54
|
bollUb: number;
|
|
54
55
|
bollLb: number;
|
|
55
56
|
};
|
|
56
|
-
getBoll(list: ListType, type: number):
|
|
57
|
+
getBoll(list: ListType, type: number): BollResType;
|
|
57
58
|
}
|
|
58
59
|
export {};
|
|
@@ -74,7 +74,6 @@ var Boll = /** @class */ (function () {
|
|
|
74
74
|
var sumMa = list
|
|
75
75
|
.slice(i - (type - 1), i + 1)
|
|
76
76
|
.reduce(function (pre, current) { return pre + current.c; }, 0);
|
|
77
|
-
console.log("sumMa", sumMa);
|
|
78
77
|
var bollMa_2 = Math.round((sumMa / type) * 100) / 100;
|
|
79
78
|
// 標準差
|
|
80
79
|
var difference = res
|
|
@@ -1,8 +1,40 @@
|
|
|
1
|
+
type ItemType = {
|
|
2
|
+
c: number;
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
};
|
|
5
|
+
type ListType = ItemType[];
|
|
1
6
|
interface EmaType {
|
|
7
|
+
init: (data: ItemType, type: number) => {
|
|
8
|
+
dataset: ListType;
|
|
9
|
+
ema: number;
|
|
10
|
+
type: number;
|
|
11
|
+
};
|
|
12
|
+
next: (data: ItemType, preList: {
|
|
13
|
+
dataset: ListType;
|
|
14
|
+
ema: number;
|
|
15
|
+
type: number;
|
|
16
|
+
}, type: number) => {
|
|
17
|
+
dataset: ListType;
|
|
18
|
+
ema: number;
|
|
19
|
+
type: number;
|
|
20
|
+
};
|
|
2
21
|
getStartEma: (list: number[], period: number) => number;
|
|
3
22
|
getEma: (list: number[], period: number) => (number | null)[];
|
|
4
23
|
}
|
|
5
24
|
export default class Ema implements EmaType {
|
|
25
|
+
init(data: ItemType, type: number): {
|
|
26
|
+
dataset: ListType;
|
|
27
|
+
ema: number;
|
|
28
|
+
type: number;
|
|
29
|
+
};
|
|
30
|
+
next(data: ItemType, preList: {
|
|
31
|
+
dataset: ListType;
|
|
32
|
+
ema: number;
|
|
33
|
+
}, type: number): {
|
|
34
|
+
dataset: ListType;
|
|
35
|
+
ema: number;
|
|
36
|
+
type: number;
|
|
37
|
+
};
|
|
6
38
|
getStartEma(list: number[], period: number): number;
|
|
7
39
|
getEma(list: number[], period: number): (number | null)[];
|
|
8
40
|
}
|
|
@@ -1,6 +1,44 @@
|
|
|
1
1
|
var Ema = /** @class */ (function () {
|
|
2
2
|
function Ema() {
|
|
3
3
|
}
|
|
4
|
+
Object.defineProperty(Ema.prototype, "init", {
|
|
5
|
+
enumerable: false,
|
|
6
|
+
configurable: true,
|
|
7
|
+
writable: true,
|
|
8
|
+
value: function (data, type) {
|
|
9
|
+
return { dataset: [data], ema: 0, type: type };
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(Ema.prototype, "next", {
|
|
13
|
+
enumerable: false,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true,
|
|
16
|
+
value: function (data, preList, type) {
|
|
17
|
+
preList.dataset.push(data);
|
|
18
|
+
if (preList.dataset.length < type) {
|
|
19
|
+
return {
|
|
20
|
+
dataset: preList.dataset,
|
|
21
|
+
ema: 0,
|
|
22
|
+
type: type,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
else if (preList.dataset.length === type) {
|
|
26
|
+
var sum = preList.dataset.reduce(function (pre, current) { return pre + current.c; }, 0);
|
|
27
|
+
return {
|
|
28
|
+
dataset: preList.dataset,
|
|
29
|
+
ema: sum / type,
|
|
30
|
+
type: type,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
if (preList.dataset.length > type) {
|
|
35
|
+
preList.dataset.shift();
|
|
36
|
+
}
|
|
37
|
+
var ema = (data.c * 2 + (type - 1) * preList.ema) / (type + 1);
|
|
38
|
+
return { dataset: preList.dataset, ema: ema, type: type };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
4
42
|
Object.defineProperty(Ema.prototype, "getStartEma", {
|
|
5
43
|
enumerable: false,
|
|
6
44
|
configurable: true,
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import Ema from "./ema";
|
|
2
2
|
import data from "./test_data.test";
|
|
3
3
|
describe("test ema methods", function () {
|
|
4
|
+
it("test init & next", function () {
|
|
5
|
+
var index = data.length - 1;
|
|
6
|
+
var ema = new Ema();
|
|
7
|
+
var init = ema.init(data[0], 5);
|
|
8
|
+
var res = init;
|
|
9
|
+
for (var i = 1; i <= index; i++) {
|
|
10
|
+
var item = data[i];
|
|
11
|
+
res = ema.next(item, res, 5);
|
|
12
|
+
}
|
|
13
|
+
expect(res.ema).toEqual(141.83482746491333);
|
|
14
|
+
});
|
|
4
15
|
it("test getEma5()", function () {
|
|
5
16
|
var ema = new Ema();
|
|
6
17
|
var res = ema.getEma(data.map(function (item) { return item.c; }), 5);
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
type
|
|
2
|
-
highestPointDate: number;
|
|
3
|
-
lowestPointDate: number;
|
|
1
|
+
export type GetGoldResType = {
|
|
4
2
|
lowestPoint: number;
|
|
5
3
|
highestPoint: number;
|
|
6
4
|
superStrong: number;
|
|
@@ -15,33 +13,36 @@ type ListType = {
|
|
|
15
13
|
o: number;
|
|
16
14
|
c: number;
|
|
17
15
|
l: number;
|
|
16
|
+
[key: string]: unknown;
|
|
18
17
|
}[];
|
|
19
|
-
type
|
|
18
|
+
type FindHightestResType = {
|
|
20
19
|
[key: string]: {
|
|
21
20
|
h: number;
|
|
22
21
|
t: number;
|
|
23
22
|
o: number;
|
|
24
23
|
c: number;
|
|
25
24
|
l: number;
|
|
25
|
+
[key: string]: unknown;
|
|
26
26
|
};
|
|
27
27
|
};
|
|
28
|
-
type
|
|
28
|
+
type FindLowestResType = {
|
|
29
29
|
[key: string]: {
|
|
30
30
|
h: number;
|
|
31
31
|
t: number;
|
|
32
32
|
o: number;
|
|
33
33
|
c: number;
|
|
34
34
|
l: number;
|
|
35
|
+
[key: string]: unknown;
|
|
35
36
|
};
|
|
36
37
|
};
|
|
37
38
|
interface GoldType {
|
|
38
|
-
findHighPoint: (list: ListType) =>
|
|
39
|
-
findLowPoint: (list: ListType) =>
|
|
40
|
-
getGold: (
|
|
39
|
+
findHighPoint: (list: ListType) => FindHightestResType;
|
|
40
|
+
findLowPoint: (list: ListType) => FindLowestResType;
|
|
41
|
+
getGold: (highestPoint: number, lowestPoint: number) => GetGoldResType;
|
|
41
42
|
}
|
|
42
43
|
export default class Gold implements GoldType {
|
|
43
|
-
findHighPoint(list: ListType):
|
|
44
|
-
findLowPoint(list: ListType):
|
|
45
|
-
getGold(
|
|
44
|
+
findHighPoint(list: ListType): FindHightestResType;
|
|
45
|
+
findLowPoint(list: ListType): FindLowestResType;
|
|
46
|
+
getGold(highestPoint: number, lowestPoint: number): GetGoldResType;
|
|
46
47
|
}
|
|
47
48
|
export {};
|
|
@@ -182,21 +182,8 @@ var Gold = /** @class */ (function () {
|
|
|
182
182
|
enumerable: false,
|
|
183
183
|
configurable: true,
|
|
184
184
|
writable: true,
|
|
185
|
-
value: function (
|
|
186
|
-
var hightPoints = this.findHighPoint(list);
|
|
187
|
-
var lowPoints = this.findLowPoint(list);
|
|
188
|
-
var lastHightPointDate = Object.keys(hightPoints).slice(-1)[0] !==
|
|
189
|
-
list[list.length - 1].t.toString()
|
|
190
|
-
? Object.keys(hightPoints).slice(-1)[0]
|
|
191
|
-
: Object.keys(hightPoints).slice(-2)[0];
|
|
192
|
-
var lastLowPointDate = Object.keys(lowPoints).slice(-1)[0] !== list[list.length - 1].t.toString()
|
|
193
|
-
? Object.keys(lowPoints).slice(-1)[0]
|
|
194
|
-
: Object.keys(lowPoints).slice(-2)[0];
|
|
195
|
-
var highestPoint = hightPoints[lastHightPointDate].h;
|
|
196
|
-
var lowestPoint = lowPoints[lastLowPointDate].l;
|
|
185
|
+
value: function (highestPoint, lowestPoint) {
|
|
197
186
|
var res = {
|
|
198
|
-
highestPointDate: parseInt(lastHightPointDate),
|
|
199
|
-
lowestPointDate: parseInt(lastLowPointDate),
|
|
200
187
|
lowestPoint: lowestPoint,
|
|
201
188
|
highestPoint: highestPoint,
|
|
202
189
|
superStrong: Math.round((highestPoint - (highestPoint - lowestPoint) * 0.191) * 100) / 100,
|
|
@@ -27,17 +27,15 @@ describe("test Gold methods", function () {
|
|
|
27
27
|
});
|
|
28
28
|
it("test getGold(", function () {
|
|
29
29
|
var gold = new Gold();
|
|
30
|
-
var allGold = gold.getGold(
|
|
30
|
+
var allGold = gold.getGold(139, 89.1);
|
|
31
31
|
expect(allGold).toEqual({
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
middle:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
superWeak: 139.83,
|
|
40
|
-
weak: 145.65,
|
|
32
|
+
lowestPoint: 89.1,
|
|
33
|
+
highestPoint: 139,
|
|
34
|
+
superStrong: 129.47,
|
|
35
|
+
strong: 119.94,
|
|
36
|
+
middle: 114.05,
|
|
37
|
+
weak: 108.16,
|
|
38
|
+
superWeak: 98.63,
|
|
41
39
|
});
|
|
42
40
|
});
|
|
43
41
|
});
|
package/dist/umd/index.js
CHANGED
|
@@ -112,7 +112,6 @@
|
|
|
112
112
|
// 計算 x 和 y 的平均值
|
|
113
113
|
var y_mean = y.reduce(function (acc, cur) { return acc + cur; }) / y.length;
|
|
114
114
|
var increment = calculateDivisionFactor(y_mean);
|
|
115
|
-
console.log(y_mean, increment);
|
|
116
115
|
var x = Array.from({ length: y.length }, function (_, index) { return index * increment; });
|
|
117
116
|
var x_mean = x.reduce(function (acc, cur) { return acc + cur; }) / x.length;
|
|
118
117
|
// 計算斜率
|
|
@@ -122,6 +121,108 @@
|
|
|
122
121
|
return slope;
|
|
123
122
|
}
|
|
124
123
|
|
|
124
|
+
exports.SwingExtremesType = void 0;
|
|
125
|
+
(function (SwingExtremesType) {
|
|
126
|
+
SwingExtremesType["Peak"] = "Peak";
|
|
127
|
+
SwingExtremesType["Trough"] = "Trough";
|
|
128
|
+
})(exports.SwingExtremesType || (exports.SwingExtremesType = {}));
|
|
129
|
+
function findPeaksByGradient(prices, level) {
|
|
130
|
+
if (level === void 0) { level = 1; }
|
|
131
|
+
var peaks = [];
|
|
132
|
+
for (var i = 1; i < prices.length - 1; i++) {
|
|
133
|
+
if (level === 1) {
|
|
134
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
135
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
136
|
+
if (prevGradient > 0 && nextGradient < 0) {
|
|
137
|
+
peaks.push(i);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else if (level === 2) {
|
|
141
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
142
|
+
var prev2Gradient = prices[i] - prices[i - 2];
|
|
143
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
144
|
+
var next2Gradient = prices[i + 2] - prices[i];
|
|
145
|
+
if (prevGradient > 0 &&
|
|
146
|
+
prev2Gradient > 0 &&
|
|
147
|
+
nextGradient < 0 &&
|
|
148
|
+
next2Gradient < 0) {
|
|
149
|
+
peaks.push(i);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return peaks;
|
|
154
|
+
}
|
|
155
|
+
function findTroughByGradient(prices, level) {
|
|
156
|
+
if (level === void 0) { level = 1; }
|
|
157
|
+
var troughs = [];
|
|
158
|
+
for (var i = 1; i < prices.length - 1; i++) {
|
|
159
|
+
if (level === 1) {
|
|
160
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
161
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
162
|
+
if (prevGradient < 0 && nextGradient > 0) {
|
|
163
|
+
troughs.push(i);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else if (level === 2) {
|
|
167
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
168
|
+
var prev2Gradient = prices[i] - prices[i - 2];
|
|
169
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
170
|
+
var next2Gradient = prices[i + 2] - prices[i];
|
|
171
|
+
if (prevGradient < 0 &&
|
|
172
|
+
prev2Gradient < 0 &&
|
|
173
|
+
nextGradient > 0 &&
|
|
174
|
+
next2Gradient > 0) {
|
|
175
|
+
troughs.push(i);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return troughs;
|
|
180
|
+
}
|
|
181
|
+
function SwingExtremes(y, type, level) {
|
|
182
|
+
if (level === void 0) { level = 1; }
|
|
183
|
+
if (type === exports.SwingExtremesType.Peak) {
|
|
184
|
+
var result = [];
|
|
185
|
+
var indexs = findPeaksByGradient(y, level);
|
|
186
|
+
result.push(indexs[0]);
|
|
187
|
+
for (var i = 1; i < indexs.length; i++) {
|
|
188
|
+
if (y[indexs[i]] > y[result[result.length - 1]] &&
|
|
189
|
+
y[indexs[i]] > y[result[result.length - 2]]) {
|
|
190
|
+
result[result.length - 1] = indexs[i];
|
|
191
|
+
}
|
|
192
|
+
else if (y[indexs[i + 1]] < y[i] &&
|
|
193
|
+
y[indexs[i]] > y[result[result.length - 1]]) {
|
|
194
|
+
result.pop();
|
|
195
|
+
result.push(indexs[i]);
|
|
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;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
throw new Error("Invalid SwingExtremesType");
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
125
226
|
function movingAverages(arr, periods) {
|
|
126
227
|
var response = new Array(periods).fill(0);
|
|
127
228
|
for (var i = periods; i < arr.length; i++) {
|
|
@@ -280,7 +381,6 @@
|
|
|
280
381
|
var sumMa = list
|
|
281
382
|
.slice(i - (type - 1), i + 1)
|
|
282
383
|
.reduce(function (pre, current) { return pre + current.c; }, 0);
|
|
283
|
-
console.log("sumMa", sumMa);
|
|
284
384
|
var bollMa_2 = Math.round((sumMa / type) * 100) / 100;
|
|
285
385
|
// 標準差
|
|
286
386
|
var difference = res
|
|
@@ -306,6 +406,44 @@
|
|
|
306
406
|
var Ema = /** @class */ (function () {
|
|
307
407
|
function Ema() {
|
|
308
408
|
}
|
|
409
|
+
Object.defineProperty(Ema.prototype, "init", {
|
|
410
|
+
enumerable: false,
|
|
411
|
+
configurable: true,
|
|
412
|
+
writable: true,
|
|
413
|
+
value: function (data, type) {
|
|
414
|
+
return { dataset: [data], ema: 0, type: type };
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
Object.defineProperty(Ema.prototype, "next", {
|
|
418
|
+
enumerable: false,
|
|
419
|
+
configurable: true,
|
|
420
|
+
writable: true,
|
|
421
|
+
value: function (data, preList, type) {
|
|
422
|
+
preList.dataset.push(data);
|
|
423
|
+
if (preList.dataset.length < type) {
|
|
424
|
+
return {
|
|
425
|
+
dataset: preList.dataset,
|
|
426
|
+
ema: 0,
|
|
427
|
+
type: type,
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
else if (preList.dataset.length === type) {
|
|
431
|
+
var sum = preList.dataset.reduce(function (pre, current) { return pre + current.c; }, 0);
|
|
432
|
+
return {
|
|
433
|
+
dataset: preList.dataset,
|
|
434
|
+
ema: sum / type,
|
|
435
|
+
type: type,
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
if (preList.dataset.length > type) {
|
|
440
|
+
preList.dataset.shift();
|
|
441
|
+
}
|
|
442
|
+
var ema = (data.c * 2 + (type - 1) * preList.ema) / (type + 1);
|
|
443
|
+
return { dataset: preList.dataset, ema: ema, type: type };
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
});
|
|
309
447
|
Object.defineProperty(Ema.prototype, "getStartEma", {
|
|
310
448
|
enumerable: false,
|
|
311
449
|
configurable: true,
|
|
@@ -598,21 +736,8 @@
|
|
|
598
736
|
enumerable: false,
|
|
599
737
|
configurable: true,
|
|
600
738
|
writable: true,
|
|
601
|
-
value: function (
|
|
602
|
-
var hightPoints = this.findHighPoint(list);
|
|
603
|
-
var lowPoints = this.findLowPoint(list);
|
|
604
|
-
var lastHightPointDate = Object.keys(hightPoints).slice(-1)[0] !==
|
|
605
|
-
list[list.length - 1].t.toString()
|
|
606
|
-
? Object.keys(hightPoints).slice(-1)[0]
|
|
607
|
-
: Object.keys(hightPoints).slice(-2)[0];
|
|
608
|
-
var lastLowPointDate = Object.keys(lowPoints).slice(-1)[0] !== list[list.length - 1].t.toString()
|
|
609
|
-
? Object.keys(lowPoints).slice(-1)[0]
|
|
610
|
-
: Object.keys(lowPoints).slice(-2)[0];
|
|
611
|
-
var highestPoint = hightPoints[lastHightPointDate].h;
|
|
612
|
-
var lowestPoint = lowPoints[lastLowPointDate].l;
|
|
739
|
+
value: function (highestPoint, lowestPoint) {
|
|
613
740
|
var res = {
|
|
614
|
-
highestPointDate: parseInt(lastHightPointDate),
|
|
615
|
-
lowestPointDate: parseInt(lastLowPointDate),
|
|
616
741
|
lowestPoint: lowestPoint,
|
|
617
742
|
highestPoint: highestPoint,
|
|
618
743
|
superStrong: Math.round((highestPoint - (highestPoint - lowestPoint) * 0.191) * 100) / 100,
|
|
@@ -1634,6 +1759,7 @@
|
|
|
1634
1759
|
exports.Macd = MACD;
|
|
1635
1760
|
exports.Obv = Obv;
|
|
1636
1761
|
exports.Rsi = Rsi;
|
|
1762
|
+
exports.SwingExtremes = SwingExtremes;
|
|
1637
1763
|
exports.Vma = Vma;
|
|
1638
1764
|
exports.Williams = Williams;
|
|
1639
1765
|
exports.add = add;
|
|
@@ -1641,6 +1767,8 @@
|
|
|
1641
1767
|
exports.calculateDivisionFactor = calculateDivisionFactor;
|
|
1642
1768
|
exports.dateFormat = dateFormat;
|
|
1643
1769
|
exports.exponentialSmoothing = exponentialSmoothing;
|
|
1770
|
+
exports.findPeaksByGradient = findPeaksByGradient;
|
|
1771
|
+
exports.findTroughByGradient = findTroughByGradient;
|
|
1644
1772
|
exports.getWeekLine = getWeekLine;
|
|
1645
1773
|
exports.isJSON = isJSON;
|
|
1646
1774
|
exports.minus = minus;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ch20026103/anysis",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14-alpha",
|
|
4
4
|
"description": "provide many analyze methods in the library.",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"bugs": "git@github.com:cosmic1330/anysis/issues",
|
|
@@ -12,21 +12,6 @@
|
|
|
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
|
-
},
|
|
30
15
|
"lint-staged": {
|
|
31
16
|
"*.{js,jsx,ts,tsx,mjs}": [
|
|
32
17
|
"pnpm lint"
|
|
@@ -57,5 +42,18 @@
|
|
|
57
42
|
},
|
|
58
43
|
"vota": {
|
|
59
44
|
"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"
|
|
60
58
|
}
|
|
61
|
-
}
|
|
59
|
+
}
|