@ch20026103/anysis 0.0.11-alpha → 0.0.13-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 +13 -107
- package/dist/cjs/analyze/Angle/angle.test.js +17 -2
- 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 +66 -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 +1 -0
- package/dist/cjs/index.js +12 -7
- package/dist/cjs/stockSkills/boll.d.ts +1 -0
- package/dist/cjs/stockSkills/boll.js +0 -1
- package/dist/cjs/stockSkills/williams.d.ts +31 -2
- package/dist/cjs/stockSkills/williams.js +40 -4
- package/dist/cjs/stockSkills/williams.test.js +11 -0
- package/dist/esm/analyze/Angle/angle.test.js +17 -2
- 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 +60 -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 +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/stockSkills/boll.d.ts +1 -0
- package/dist/esm/stockSkills/boll.js +0 -1
- package/dist/esm/stockSkills/williams.d.ts +31 -2
- package/dist/esm/stockSkills/williams.js +40 -4
- package/dist/esm/stockSkills/williams.test.js +11 -0
- package/dist/umd/index.js +104 -6
- package/package.json +15 -17
package/demo/main.js
CHANGED
|
@@ -1,77 +1,24 @@
|
|
|
1
1
|
/* eslint @typescript-eslint/no-var-requires: "off" */
|
|
2
2
|
const axios = require("axios");
|
|
3
|
-
const {
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
const kd = new Kd();
|
|
7
|
-
const boll = new Boll();
|
|
8
|
-
const vma = new Vma();
|
|
9
|
-
const stockId = 1702;
|
|
10
|
-
// week
|
|
11
|
-
const { getWeekLine, Ma } = require("../dist/cjs/index.js");
|
|
12
|
-
const ma = new Ma();
|
|
13
|
-
|
|
14
|
-
function DemoDay() {
|
|
3
|
+
const { Williams } = require("../dist/cjs/index.js");
|
|
4
|
+
const williams = new Williams();
|
|
5
|
+
function DemoDay(stockId) {
|
|
15
6
|
axios
|
|
16
7
|
.get(
|
|
17
8
|
`https://tw.quote.finance.yahoo.net/quote/q?type=ta&perd=d&mkt=10&sym=${stockId}&v=1&callback=`
|
|
18
9
|
)
|
|
19
10
|
.then((res) => {
|
|
20
|
-
|
|
21
|
-
let
|
|
22
|
-
let
|
|
23
|
-
let
|
|
24
|
-
let
|
|
25
|
-
let bollData = boll.init(data[0]);
|
|
26
|
-
let vmaData = vma.init(data[0], 5);
|
|
27
|
-
let finallyData = [
|
|
28
|
-
{
|
|
29
|
-
...data[0],
|
|
30
|
-
vma: vmaData.vma,
|
|
31
|
-
ema12: macdData.ema12,
|
|
32
|
-
ema26: macdData.ema26,
|
|
33
|
-
macd: macdData.macd,
|
|
34
|
-
osc: macdData.osc,
|
|
35
|
-
dif: macdData.dif[macdData.dif.length - 1],
|
|
36
|
-
obv: obvData.obv,
|
|
37
|
-
obvMa: obvData.obvMa,
|
|
38
|
-
rsv: kdData.rsv,
|
|
39
|
-
k: kdData.k,
|
|
40
|
-
d: kdData.d,
|
|
41
|
-
"k-d": kdData["k-d"],
|
|
42
|
-
bollMa: bollData.bollMa,
|
|
43
|
-
bollUb: bollData.bollUb,
|
|
44
|
-
bollLb: bollData.bollLb,
|
|
45
|
-
},
|
|
46
|
-
];
|
|
47
|
-
|
|
11
|
+
res = res.data.replace(/^\(|\);$/g, "");
|
|
12
|
+
let parse = JSON.parse(res);
|
|
13
|
+
let data = parse.ta;
|
|
14
|
+
let williams9Data = williams.init(data[0], 9);
|
|
15
|
+
let williams18Data = williams.init(data[0], 18);
|
|
48
16
|
for (let i = 1; i < data.length; i++) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
kdData = kd.next(data[i], kdData, 9);
|
|
52
|
-
bollData = boll.next(data[i], bollData, 20);
|
|
53
|
-
vmaData = vma.next(data[i], vmaData, 5);
|
|
54
|
-
finallyData.push({
|
|
55
|
-
...data[i],
|
|
56
|
-
vma: vmaData.vma,
|
|
57
|
-
ema12: macdData.ema12,
|
|
58
|
-
ema26: macdData.ema26,
|
|
59
|
-
macd: macdData.macd,
|
|
60
|
-
osc: macdData.osc,
|
|
61
|
-
dif: macdData.dif[macdData.dif.length - 1],
|
|
62
|
-
obv: obvData.obv,
|
|
63
|
-
obvMa: obvData.obvMa,
|
|
64
|
-
rsv: kdData.rsv,
|
|
65
|
-
k: kdData.k,
|
|
66
|
-
d: kdData.d,
|
|
67
|
-
"k-d": kdData["k-d"],
|
|
68
|
-
bollMa: bollData.bollMa,
|
|
69
|
-
bollUb: bollData.bollUb,
|
|
70
|
-
bollLb: bollData.bollLb,
|
|
71
|
-
});
|
|
17
|
+
williams9Data = williams.next(data[i], williams9Data, 9);
|
|
18
|
+
williams18Data = williams.next(data[i], williams18Data, 18);
|
|
72
19
|
}
|
|
73
|
-
|
|
74
|
-
console.log(
|
|
20
|
+
console.log(williams9Data);
|
|
21
|
+
console.log(williams18Data);
|
|
75
22
|
})
|
|
76
23
|
.catch((error) => {
|
|
77
24
|
console.error(error);
|
|
@@ -81,45 +28,4 @@ function DemoDay() {
|
|
|
81
28
|
});
|
|
82
29
|
}
|
|
83
30
|
|
|
84
|
-
|
|
85
|
-
axios
|
|
86
|
-
.get(
|
|
87
|
-
`https://tw.quote.finance.yahoo.net/quote/q?type=ta&perd=d&mkt=10&sym=${stockId}&v=1&callback=`
|
|
88
|
-
)
|
|
89
|
-
.then((res) => {
|
|
90
|
-
let json = res.data.match(/"ta":(\S*),"ex"/)[1];
|
|
91
|
-
let data = JSON.parse(json);
|
|
92
|
-
// week
|
|
93
|
-
let weekLine = getWeekLine(data);
|
|
94
|
-
let weekMaData5 = ma.init(weekLine[0], 5);
|
|
95
|
-
let weekMaData10 = ma.init(weekLine[0], 10);
|
|
96
|
-
let weekMaData20 = ma.init(weekLine[0], 20);
|
|
97
|
-
for (let i = 1; i < weekLine.length; i++) {
|
|
98
|
-
weekMaData5 = ma.next(weekLine[i], weekMaData5, 5);
|
|
99
|
-
weekMaData10 = ma.next(weekLine[i], weekMaData10, 10);
|
|
100
|
-
weekMaData20 = ma.next(weekLine[i], weekMaData20, 20);
|
|
101
|
-
}
|
|
102
|
-
console.log({
|
|
103
|
-
t: weekMaData5.dataset[weekMaData5.dataset.length - 1].t,
|
|
104
|
-
ma5: weekMaData5.ma,
|
|
105
|
-
ma5ExclusionValue: weekMaData5.exclusionValue,
|
|
106
|
-
ma10: weekMaData10.ma,
|
|
107
|
-
ma10ExclusionValue: weekMaData10.exclusionValue,
|
|
108
|
-
ma20: weekMaData20.ma,
|
|
109
|
-
ma20ExclusionValue: weekMaData20.exclusionValue,
|
|
110
|
-
});
|
|
111
|
-
})
|
|
112
|
-
.catch((error) => {
|
|
113
|
-
console.error(error);
|
|
114
|
-
})
|
|
115
|
-
.finally(() => {
|
|
116
|
-
console.log("week done");
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// DemoDay();
|
|
121
|
-
|
|
122
|
-
const showWeek = true;
|
|
123
|
-
if (showWeek) {
|
|
124
|
-
DemoWeek();
|
|
125
|
-
}
|
|
31
|
+
DemoDay("2449");
|
|
@@ -7,14 +7,29 @@ describe("test Angle methods", function () {
|
|
|
7
7
|
var angle = (0, index_1.default)(y);
|
|
8
8
|
expect(angle).toEqual(45);
|
|
9
9
|
});
|
|
10
|
-
it("test
|
|
10
|
+
it("test [0, 200]", function () {
|
|
11
11
|
var y = [0, 200];
|
|
12
12
|
var angle = (0, index_1.default)(y);
|
|
13
13
|
expect(angle).toEqual(63.43494882292201);
|
|
14
14
|
});
|
|
15
|
-
it("test
|
|
15
|
+
it("test [0, 0]", function () {
|
|
16
16
|
var y = [0, 0];
|
|
17
17
|
var angle = (0, index_1.default)(y);
|
|
18
18
|
expect(angle).toEqual(0);
|
|
19
19
|
});
|
|
20
|
+
it("test [39.73, 48.15]", function () {
|
|
21
|
+
var y = [39.73, 48.15];
|
|
22
|
+
var angle = (0, index_1.default)(y);
|
|
23
|
+
expect(angle).toEqual(40.09737861178007);
|
|
24
|
+
});
|
|
25
|
+
it("test [15.46, 30.19]", function () {
|
|
26
|
+
var y = [15.46, 30.19];
|
|
27
|
+
var angle = (0, index_1.default)(y);
|
|
28
|
+
expect(angle).toEqual(55.82794164843938);
|
|
29
|
+
});
|
|
30
|
+
it("test [35.64, 37.09]", function () {
|
|
31
|
+
var y = [35.64, 37.09];
|
|
32
|
+
var angle = (0, index_1.default)(y);
|
|
33
|
+
expect(angle).toEqual(8.250387228905515);
|
|
34
|
+
});
|
|
20
35
|
});
|
|
@@ -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[]): Index[];
|
|
7
|
+
export declare function findTroughByGradient(prices: number[]): Index[];
|
|
8
|
+
export declare function SwingExtremes(y: number[], type: SwingExtremesType): Index[];
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
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) {
|
|
10
|
+
var peaks = [];
|
|
11
|
+
for (var i = 1; i < prices.length - 1; i++) {
|
|
12
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
13
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
14
|
+
if (prevGradient > 0 && nextGradient < 0) {
|
|
15
|
+
peaks.push(i);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return peaks;
|
|
19
|
+
}
|
|
20
|
+
exports.findPeaksByGradient = findPeaksByGradient;
|
|
21
|
+
function findTroughByGradient(prices) {
|
|
22
|
+
var peaks = [];
|
|
23
|
+
for (var i = 1; i < prices.length - 1; i++) {
|
|
24
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
25
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
26
|
+
if (prevGradient < 0 && nextGradient > 0) {
|
|
27
|
+
peaks.push(i);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return peaks;
|
|
31
|
+
}
|
|
32
|
+
exports.findTroughByGradient = findTroughByGradient;
|
|
33
|
+
function SwingExtremes(y, type) {
|
|
34
|
+
if (type === SwingExtremesType.Peak) {
|
|
35
|
+
var result = [];
|
|
36
|
+
var indexs = findPeaksByGradient(y);
|
|
37
|
+
result.push(indexs[0]);
|
|
38
|
+
for (var i = 1; i < indexs.length; i++) {
|
|
39
|
+
if (y[indexs[i]] > y[result[result.length - 1]]) {
|
|
40
|
+
result[result.length - 1] = indexs[i];
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
result.push(indexs[i]);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
if (type === SwingExtremesType.Trough) {
|
|
49
|
+
var result = [];
|
|
50
|
+
var indexs = findTroughByGradient(y);
|
|
51
|
+
result.push(indexs[0]);
|
|
52
|
+
for (var i = 1; i < indexs.length; i++) {
|
|
53
|
+
if (y[indexs[i]] < y[result[result.length - 1]]) {
|
|
54
|
+
result[result.length - 1] = indexs[i];
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
result.push(indexs[i]);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
throw new Error("Invalid SwingExtremesType");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
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([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,6 +1,7 @@
|
|
|
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, findPeaksByGradient, findTroughByGradient, SwingExtremesType, } 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";
|
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.SwingExtremesType = exports.findTroughByGradient = exports.findPeaksByGradient = 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, "findPeaksByGradient", { enumerable: true, get: function () { return index_js_3.findPeaksByGradient; } });
|
|
18
|
+
Object.defineProperty(exports, "findTroughByGradient", { enumerable: true, get: function () { return index_js_3.findTroughByGradient; } });
|
|
19
|
+
Object.defineProperty(exports, "SwingExtremesType", { enumerable: true, get: function () { return index_js_3.SwingExtremesType; } });
|
|
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");
|
|
@@ -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,9 @@
|
|
|
1
|
-
type
|
|
1
|
+
type DataType = {
|
|
2
2
|
h: number;
|
|
3
3
|
l: number;
|
|
4
4
|
c: number;
|
|
5
|
-
}
|
|
5
|
+
};
|
|
6
|
+
type ListType = DataType[];
|
|
6
7
|
type ResWilliams9Type = {
|
|
7
8
|
c: number;
|
|
8
9
|
williams9: number | null;
|
|
@@ -17,11 +18,39 @@ type ResAllWilliamsType = {
|
|
|
17
18
|
williams9: number | null;
|
|
18
19
|
}[];
|
|
19
20
|
interface WilliamsType {
|
|
21
|
+
init: (data: DataType, type: number) => {
|
|
22
|
+
dataset: ListType;
|
|
23
|
+
williams: number;
|
|
24
|
+
type: number;
|
|
25
|
+
};
|
|
26
|
+
next: (data: DataType, preList: {
|
|
27
|
+
dataset: ListType;
|
|
28
|
+
williams: number;
|
|
29
|
+
type: number;
|
|
30
|
+
}, type: number) => {
|
|
31
|
+
dataset: ListType;
|
|
32
|
+
williams: number;
|
|
33
|
+
type: number;
|
|
34
|
+
};
|
|
20
35
|
getWilliams9: (list: ListType) => ResWilliams9Type;
|
|
21
36
|
getWilliams18: (list: ListType) => ResWilliams18Type;
|
|
22
37
|
getAllWillams(list: ListType): ResAllWilliamsType;
|
|
23
38
|
}
|
|
24
39
|
export default class Williams implements WilliamsType {
|
|
40
|
+
init(data: DataType, type: number): {
|
|
41
|
+
dataset: DataType[];
|
|
42
|
+
williams: number;
|
|
43
|
+
type: number;
|
|
44
|
+
};
|
|
45
|
+
next(data: DataType, preList: {
|
|
46
|
+
dataset: ListType;
|
|
47
|
+
williams: number;
|
|
48
|
+
type: number;
|
|
49
|
+
}, type: number): {
|
|
50
|
+
dataset: ListType;
|
|
51
|
+
williams: number;
|
|
52
|
+
type: number;
|
|
53
|
+
};
|
|
25
54
|
getAllWillams(list: ListType): ResAllWilliamsType;
|
|
26
55
|
getWilliams9(list: ListType): ResWilliams9Type;
|
|
27
56
|
getWilliams18(list: ListType): ResWilliams18Type;
|
|
@@ -14,6 +14,42 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
14
14
|
var Williams = /** @class */ (function () {
|
|
15
15
|
function Williams() {
|
|
16
16
|
}
|
|
17
|
+
Object.defineProperty(Williams.prototype, "init", {
|
|
18
|
+
enumerable: false,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: function (data, type) {
|
|
22
|
+
return { dataset: [data], williams: 0, type: type };
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(Williams.prototype, "next", {
|
|
26
|
+
enumerable: false,
|
|
27
|
+
configurable: true,
|
|
28
|
+
writable: true,
|
|
29
|
+
value: function (data, preList, type) {
|
|
30
|
+
preList.dataset.push(data);
|
|
31
|
+
if (preList.dataset.length < type) {
|
|
32
|
+
return {
|
|
33
|
+
dataset: preList.dataset,
|
|
34
|
+
williams: 0,
|
|
35
|
+
type: type,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
if (preList.dataset.length > type) {
|
|
40
|
+
preList.dataset.shift();
|
|
41
|
+
}
|
|
42
|
+
var maxList = preList.dataset.map(function (item) { return item["h"]; });
|
|
43
|
+
var minList = preList.dataset.map(function (item) { return item["l"]; });
|
|
44
|
+
var max = Math.max.apply(Math, maxList);
|
|
45
|
+
var min = Math.min.apply(Math, minList);
|
|
46
|
+
var close_1 = data.c;
|
|
47
|
+
var williams = ((max - close_1) / (max - min)) * -100;
|
|
48
|
+
williams = Math.round(williams * 100) / 100;
|
|
49
|
+
return { dataset: preList.dataset, williams: williams, type: type };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
17
53
|
Object.defineProperty(Williams.prototype, "getAllWillams", {
|
|
18
54
|
enumerable: false,
|
|
19
55
|
configurable: true,
|
|
@@ -42,8 +78,8 @@ var Williams = /** @class */ (function () {
|
|
|
42
78
|
var minList = list.slice(i - 8, i).map(function (item) { return item["l"]; });
|
|
43
79
|
var max = Math.max.apply(Math, maxList);
|
|
44
80
|
var min = Math.min.apply(Math, minList);
|
|
45
|
-
var
|
|
46
|
-
var williams9 = ((max -
|
|
81
|
+
var close_2 = list[i]["c"];
|
|
82
|
+
var williams9 = ((max - close_2) / (max - min)) * -100;
|
|
47
83
|
res[i] = __assign(__assign({}, list[i]), { williams9: Math.round(williams9 * 100) / 100 });
|
|
48
84
|
}
|
|
49
85
|
}
|
|
@@ -64,8 +100,8 @@ var Williams = /** @class */ (function () {
|
|
|
64
100
|
var minList = list.slice(i - 17, i).map(function (item) { return item["l"]; });
|
|
65
101
|
var max = Math.max.apply(Math, maxList);
|
|
66
102
|
var min = Math.min.apply(Math, minList);
|
|
67
|
-
var
|
|
68
|
-
var williams18 = ((max -
|
|
103
|
+
var close_3 = list[i]["c"];
|
|
104
|
+
var williams18 = ((max - close_3) / (max - min)) * -100;
|
|
69
105
|
res[i] = __assign(__assign({}, list[i]), { williams18: Math.round(williams18 * 100) / 100 });
|
|
70
106
|
}
|
|
71
107
|
}
|
|
@@ -3,6 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
var williams_1 = require("./williams");
|
|
4
4
|
var test_data_test_1 = require("./test_data.test");
|
|
5
5
|
describe("test williams methods", function () {
|
|
6
|
+
it("test next()", function () {
|
|
7
|
+
var index = test_data_test_1.default.length - 1;
|
|
8
|
+
var williams = new williams_1.default();
|
|
9
|
+
var init = williams.init(test_data_test_1.default[0], 9);
|
|
10
|
+
var res = init;
|
|
11
|
+
for (var i = 1; i <= index; i++) {
|
|
12
|
+
var item = test_data_test_1.default[i];
|
|
13
|
+
res = williams.next(item, res, 9);
|
|
14
|
+
}
|
|
15
|
+
expect(res.williams).toEqual(-79.59);
|
|
16
|
+
});
|
|
6
17
|
it("test getWilliams9()", function () {
|
|
7
18
|
var williams = new williams_1.default();
|
|
8
19
|
expect(williams.getWilliams9(test_data_test_1.default)[test_data_test_1.default.length - 1]).toEqual({
|
|
@@ -5,14 +5,29 @@ describe("test Angle methods", function () {
|
|
|
5
5
|
var angle = Angle(y);
|
|
6
6
|
expect(angle).toEqual(45);
|
|
7
7
|
});
|
|
8
|
-
it("test
|
|
8
|
+
it("test [0, 200]", function () {
|
|
9
9
|
var y = [0, 200];
|
|
10
10
|
var angle = Angle(y);
|
|
11
11
|
expect(angle).toEqual(63.43494882292201);
|
|
12
12
|
});
|
|
13
|
-
it("test
|
|
13
|
+
it("test [0, 0]", function () {
|
|
14
14
|
var y = [0, 0];
|
|
15
15
|
var angle = Angle(y);
|
|
16
16
|
expect(angle).toEqual(0);
|
|
17
17
|
});
|
|
18
|
+
it("test [39.73, 48.15]", function () {
|
|
19
|
+
var y = [39.73, 48.15];
|
|
20
|
+
var angle = Angle(y);
|
|
21
|
+
expect(angle).toEqual(40.09737861178007);
|
|
22
|
+
});
|
|
23
|
+
it("test [15.46, 30.19]", function () {
|
|
24
|
+
var y = [15.46, 30.19];
|
|
25
|
+
var angle = Angle(y);
|
|
26
|
+
expect(angle).toEqual(55.82794164843938);
|
|
27
|
+
});
|
|
28
|
+
it("test [35.64, 37.09]", function () {
|
|
29
|
+
var y = [35.64, 37.09];
|
|
30
|
+
var angle = Angle(y);
|
|
31
|
+
expect(angle).toEqual(8.250387228905515);
|
|
32
|
+
});
|
|
18
33
|
});
|
|
@@ -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[]): Index[];
|
|
7
|
+
export declare function findTroughByGradient(prices: number[]): Index[];
|
|
8
|
+
export declare function SwingExtremes(y: number[], type: SwingExtremesType): Index[];
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export var SwingExtremesType;
|
|
2
|
+
(function (SwingExtremesType) {
|
|
3
|
+
SwingExtremesType["Peak"] = "Peak";
|
|
4
|
+
SwingExtremesType["Trough"] = "Trough";
|
|
5
|
+
})(SwingExtremesType || (SwingExtremesType = {}));
|
|
6
|
+
export function findPeaksByGradient(prices) {
|
|
7
|
+
var peaks = [];
|
|
8
|
+
for (var i = 1; i < prices.length - 1; i++) {
|
|
9
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
10
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
11
|
+
if (prevGradient > 0 && nextGradient < 0) {
|
|
12
|
+
peaks.push(i);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return peaks;
|
|
16
|
+
}
|
|
17
|
+
export function findTroughByGradient(prices) {
|
|
18
|
+
var peaks = [];
|
|
19
|
+
for (var i = 1; i < prices.length - 1; i++) {
|
|
20
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
21
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
22
|
+
if (prevGradient < 0 && nextGradient > 0) {
|
|
23
|
+
peaks.push(i);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return peaks;
|
|
27
|
+
}
|
|
28
|
+
export function SwingExtremes(y, type) {
|
|
29
|
+
if (type === SwingExtremesType.Peak) {
|
|
30
|
+
var result = [];
|
|
31
|
+
var indexs = findPeaksByGradient(y);
|
|
32
|
+
result.push(indexs[0]);
|
|
33
|
+
for (var i = 1; i < indexs.length; i++) {
|
|
34
|
+
if (y[indexs[i]] > y[result[result.length - 1]]) {
|
|
35
|
+
result[result.length - 1] = indexs[i];
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
result.push(indexs[i]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
if (type === SwingExtremesType.Trough) {
|
|
44
|
+
var result = [];
|
|
45
|
+
var indexs = findTroughByGradient(y);
|
|
46
|
+
result.push(indexs[0]);
|
|
47
|
+
for (var i = 1; i < indexs.length; i++) {
|
|
48
|
+
if (y[indexs[i]] < y[result[result.length - 1]]) {
|
|
49
|
+
result[result.length - 1] = indexs[i];
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
result.push(indexs[i]);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
throw new Error("Invalid SwingExtremesType");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -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([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,6 +1,7 @@
|
|
|
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, findPeaksByGradient, findTroughByGradient, SwingExtremesType, } 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";
|
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, findPeaksByGradient, findTroughByGradient, SwingExtremesType, } 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";
|
|
@@ -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,9 @@
|
|
|
1
|
-
type
|
|
1
|
+
type DataType = {
|
|
2
2
|
h: number;
|
|
3
3
|
l: number;
|
|
4
4
|
c: number;
|
|
5
|
-
}
|
|
5
|
+
};
|
|
6
|
+
type ListType = DataType[];
|
|
6
7
|
type ResWilliams9Type = {
|
|
7
8
|
c: number;
|
|
8
9
|
williams9: number | null;
|
|
@@ -17,11 +18,39 @@ type ResAllWilliamsType = {
|
|
|
17
18
|
williams9: number | null;
|
|
18
19
|
}[];
|
|
19
20
|
interface WilliamsType {
|
|
21
|
+
init: (data: DataType, type: number) => {
|
|
22
|
+
dataset: ListType;
|
|
23
|
+
williams: number;
|
|
24
|
+
type: number;
|
|
25
|
+
};
|
|
26
|
+
next: (data: DataType, preList: {
|
|
27
|
+
dataset: ListType;
|
|
28
|
+
williams: number;
|
|
29
|
+
type: number;
|
|
30
|
+
}, type: number) => {
|
|
31
|
+
dataset: ListType;
|
|
32
|
+
williams: number;
|
|
33
|
+
type: number;
|
|
34
|
+
};
|
|
20
35
|
getWilliams9: (list: ListType) => ResWilliams9Type;
|
|
21
36
|
getWilliams18: (list: ListType) => ResWilliams18Type;
|
|
22
37
|
getAllWillams(list: ListType): ResAllWilliamsType;
|
|
23
38
|
}
|
|
24
39
|
export default class Williams implements WilliamsType {
|
|
40
|
+
init(data: DataType, type: number): {
|
|
41
|
+
dataset: DataType[];
|
|
42
|
+
williams: number;
|
|
43
|
+
type: number;
|
|
44
|
+
};
|
|
45
|
+
next(data: DataType, preList: {
|
|
46
|
+
dataset: ListType;
|
|
47
|
+
williams: number;
|
|
48
|
+
type: number;
|
|
49
|
+
}, type: number): {
|
|
50
|
+
dataset: ListType;
|
|
51
|
+
williams: number;
|
|
52
|
+
type: number;
|
|
53
|
+
};
|
|
25
54
|
getAllWillams(list: ListType): ResAllWilliamsType;
|
|
26
55
|
getWilliams9(list: ListType): ResWilliams9Type;
|
|
27
56
|
getWilliams18(list: ListType): ResWilliams18Type;
|
|
@@ -12,6 +12,42 @@ var __assign = (this && this.__assign) || function () {
|
|
|
12
12
|
var Williams = /** @class */ (function () {
|
|
13
13
|
function Williams() {
|
|
14
14
|
}
|
|
15
|
+
Object.defineProperty(Williams.prototype, "init", {
|
|
16
|
+
enumerable: false,
|
|
17
|
+
configurable: true,
|
|
18
|
+
writable: true,
|
|
19
|
+
value: function (data, type) {
|
|
20
|
+
return { dataset: [data], williams: 0, type: type };
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(Williams.prototype, "next", {
|
|
24
|
+
enumerable: false,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
value: function (data, preList, type) {
|
|
28
|
+
preList.dataset.push(data);
|
|
29
|
+
if (preList.dataset.length < type) {
|
|
30
|
+
return {
|
|
31
|
+
dataset: preList.dataset,
|
|
32
|
+
williams: 0,
|
|
33
|
+
type: type,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
if (preList.dataset.length > type) {
|
|
38
|
+
preList.dataset.shift();
|
|
39
|
+
}
|
|
40
|
+
var maxList = preList.dataset.map(function (item) { return item["h"]; });
|
|
41
|
+
var minList = preList.dataset.map(function (item) { return item["l"]; });
|
|
42
|
+
var max = Math.max.apply(Math, maxList);
|
|
43
|
+
var min = Math.min.apply(Math, minList);
|
|
44
|
+
var close_1 = data.c;
|
|
45
|
+
var williams = ((max - close_1) / (max - min)) * -100;
|
|
46
|
+
williams = Math.round(williams * 100) / 100;
|
|
47
|
+
return { dataset: preList.dataset, williams: williams, type: type };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
15
51
|
Object.defineProperty(Williams.prototype, "getAllWillams", {
|
|
16
52
|
enumerable: false,
|
|
17
53
|
configurable: true,
|
|
@@ -40,8 +76,8 @@ var Williams = /** @class */ (function () {
|
|
|
40
76
|
var minList = list.slice(i - 8, i).map(function (item) { return item["l"]; });
|
|
41
77
|
var max = Math.max.apply(Math, maxList);
|
|
42
78
|
var min = Math.min.apply(Math, minList);
|
|
43
|
-
var
|
|
44
|
-
var williams9 = ((max -
|
|
79
|
+
var close_2 = list[i]["c"];
|
|
80
|
+
var williams9 = ((max - close_2) / (max - min)) * -100;
|
|
45
81
|
res[i] = __assign(__assign({}, list[i]), { williams9: Math.round(williams9 * 100) / 100 });
|
|
46
82
|
}
|
|
47
83
|
}
|
|
@@ -62,8 +98,8 @@ var Williams = /** @class */ (function () {
|
|
|
62
98
|
var minList = list.slice(i - 17, i).map(function (item) { return item["l"]; });
|
|
63
99
|
var max = Math.max.apply(Math, maxList);
|
|
64
100
|
var min = Math.min.apply(Math, minList);
|
|
65
|
-
var
|
|
66
|
-
var williams18 = ((max -
|
|
101
|
+
var close_3 = list[i]["c"];
|
|
102
|
+
var williams18 = ((max - close_3) / (max - min)) * -100;
|
|
67
103
|
res[i] = __assign(__assign({}, list[i]), { williams18: Math.round(williams18 * 100) / 100 });
|
|
68
104
|
}
|
|
69
105
|
}
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import Williams from "./williams";
|
|
2
2
|
import data from "./test_data.test";
|
|
3
3
|
describe("test williams methods", function () {
|
|
4
|
+
it("test next()", function () {
|
|
5
|
+
var index = data.length - 1;
|
|
6
|
+
var williams = new Williams();
|
|
7
|
+
var init = williams.init(data[0], 9);
|
|
8
|
+
var res = init;
|
|
9
|
+
for (var i = 1; i <= index; i++) {
|
|
10
|
+
var item = data[i];
|
|
11
|
+
res = williams.next(item, res, 9);
|
|
12
|
+
}
|
|
13
|
+
expect(res.williams).toEqual(-79.59);
|
|
14
|
+
});
|
|
4
15
|
it("test getWilliams9()", function () {
|
|
5
16
|
var williams = new Williams();
|
|
6
17
|
expect(williams.getWilliams9(data)[data.length - 1]).toEqual({
|
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,67 @@
|
|
|
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) {
|
|
130
|
+
var peaks = [];
|
|
131
|
+
for (var i = 1; i < prices.length - 1; i++) {
|
|
132
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
133
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
134
|
+
if (prevGradient > 0 && nextGradient < 0) {
|
|
135
|
+
peaks.push(i);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return peaks;
|
|
139
|
+
}
|
|
140
|
+
function findTroughByGradient(prices) {
|
|
141
|
+
var peaks = [];
|
|
142
|
+
for (var i = 1; i < prices.length - 1; i++) {
|
|
143
|
+
var prevGradient = prices[i] - prices[i - 1];
|
|
144
|
+
var nextGradient = prices[i + 1] - prices[i];
|
|
145
|
+
if (prevGradient < 0 && nextGradient > 0) {
|
|
146
|
+
peaks.push(i);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return peaks;
|
|
150
|
+
}
|
|
151
|
+
function SwingExtremes(y, type) {
|
|
152
|
+
if (type === exports.SwingExtremesType.Peak) {
|
|
153
|
+
var result = [];
|
|
154
|
+
var indexs = findPeaksByGradient(y);
|
|
155
|
+
result.push(indexs[0]);
|
|
156
|
+
for (var i = 1; i < indexs.length; i++) {
|
|
157
|
+
if (y[indexs[i]] > y[result[result.length - 1]]) {
|
|
158
|
+
result[result.length - 1] = indexs[i];
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
result.push(indexs[i]);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
if (type === exports.SwingExtremesType.Trough) {
|
|
167
|
+
var result = [];
|
|
168
|
+
var indexs = findTroughByGradient(y);
|
|
169
|
+
result.push(indexs[0]);
|
|
170
|
+
for (var i = 1; i < indexs.length; i++) {
|
|
171
|
+
if (y[indexs[i]] < y[result[result.length - 1]]) {
|
|
172
|
+
result[result.length - 1] = indexs[i];
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
result.push(indexs[i]);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
throw new Error("Invalid SwingExtremesType");
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
125
185
|
function movingAverages(arr, periods) {
|
|
126
186
|
var response = new Array(periods).fill(0);
|
|
127
187
|
for (var i = periods; i < arr.length; i++) {
|
|
@@ -280,7 +340,6 @@
|
|
|
280
340
|
var sumMa = list
|
|
281
341
|
.slice(i - (type - 1), i + 1)
|
|
282
342
|
.reduce(function (pre, current) { return pre + current.c; }, 0);
|
|
283
|
-
console.log("sumMa", sumMa);
|
|
284
343
|
var bollMa_2 = Math.round((sumMa / type) * 100) / 100;
|
|
285
344
|
// 標準差
|
|
286
345
|
var difference = res
|
|
@@ -1492,6 +1551,42 @@
|
|
|
1492
1551
|
var Williams = /** @class */ (function () {
|
|
1493
1552
|
function Williams() {
|
|
1494
1553
|
}
|
|
1554
|
+
Object.defineProperty(Williams.prototype, "init", {
|
|
1555
|
+
enumerable: false,
|
|
1556
|
+
configurable: true,
|
|
1557
|
+
writable: true,
|
|
1558
|
+
value: function (data, type) {
|
|
1559
|
+
return { dataset: [data], williams: 0, type: type };
|
|
1560
|
+
}
|
|
1561
|
+
});
|
|
1562
|
+
Object.defineProperty(Williams.prototype, "next", {
|
|
1563
|
+
enumerable: false,
|
|
1564
|
+
configurable: true,
|
|
1565
|
+
writable: true,
|
|
1566
|
+
value: function (data, preList, type) {
|
|
1567
|
+
preList.dataset.push(data);
|
|
1568
|
+
if (preList.dataset.length < type) {
|
|
1569
|
+
return {
|
|
1570
|
+
dataset: preList.dataset,
|
|
1571
|
+
williams: 0,
|
|
1572
|
+
type: type,
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
else {
|
|
1576
|
+
if (preList.dataset.length > type) {
|
|
1577
|
+
preList.dataset.shift();
|
|
1578
|
+
}
|
|
1579
|
+
var maxList = preList.dataset.map(function (item) { return item["h"]; });
|
|
1580
|
+
var minList = preList.dataset.map(function (item) { return item["l"]; });
|
|
1581
|
+
var max = Math.max.apply(Math, maxList);
|
|
1582
|
+
var min = Math.min.apply(Math, minList);
|
|
1583
|
+
var close_1 = data.c;
|
|
1584
|
+
var williams = ((max - close_1) / (max - min)) * -100;
|
|
1585
|
+
williams = Math.round(williams * 100) / 100;
|
|
1586
|
+
return { dataset: preList.dataset, williams: williams, type: type };
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
});
|
|
1495
1590
|
Object.defineProperty(Williams.prototype, "getAllWillams", {
|
|
1496
1591
|
enumerable: false,
|
|
1497
1592
|
configurable: true,
|
|
@@ -1520,8 +1615,8 @@
|
|
|
1520
1615
|
var minList = list.slice(i - 8, i).map(function (item) { return item["l"]; });
|
|
1521
1616
|
var max = Math.max.apply(Math, maxList);
|
|
1522
1617
|
var min = Math.min.apply(Math, minList);
|
|
1523
|
-
var
|
|
1524
|
-
var williams9 = ((max -
|
|
1618
|
+
var close_2 = list[i]["c"];
|
|
1619
|
+
var williams9 = ((max - close_2) / (max - min)) * -100;
|
|
1525
1620
|
res[i] = __assign(__assign({}, list[i]), { williams9: Math.round(williams9 * 100) / 100 });
|
|
1526
1621
|
}
|
|
1527
1622
|
}
|
|
@@ -1542,8 +1637,8 @@
|
|
|
1542
1637
|
var minList = list.slice(i - 17, i).map(function (item) { return item["l"]; });
|
|
1543
1638
|
var max = Math.max.apply(Math, maxList);
|
|
1544
1639
|
var min = Math.min.apply(Math, minList);
|
|
1545
|
-
var
|
|
1546
|
-
var williams18 = ((max -
|
|
1640
|
+
var close_3 = list[i]["c"];
|
|
1641
|
+
var williams18 = ((max - close_3) / (max - min)) * -100;
|
|
1547
1642
|
res[i] = __assign(__assign({}, list[i]), { williams18: Math.round(williams18 * 100) / 100 });
|
|
1548
1643
|
}
|
|
1549
1644
|
}
|
|
@@ -1598,6 +1693,7 @@
|
|
|
1598
1693
|
exports.Macd = MACD;
|
|
1599
1694
|
exports.Obv = Obv;
|
|
1600
1695
|
exports.Rsi = Rsi;
|
|
1696
|
+
exports.SwingExtremes = SwingExtremes;
|
|
1601
1697
|
exports.Vma = Vma;
|
|
1602
1698
|
exports.Williams = Williams;
|
|
1603
1699
|
exports.add = add;
|
|
@@ -1605,6 +1701,8 @@
|
|
|
1605
1701
|
exports.calculateDivisionFactor = calculateDivisionFactor;
|
|
1606
1702
|
exports.dateFormat = dateFormat;
|
|
1607
1703
|
exports.exponentialSmoothing = exponentialSmoothing;
|
|
1704
|
+
exports.findPeaksByGradient = findPeaksByGradient;
|
|
1705
|
+
exports.findTroughByGradient = findTroughByGradient;
|
|
1608
1706
|
exports.getWeekLine = getWeekLine;
|
|
1609
1707
|
exports.isJSON = isJSON;
|
|
1610
1708
|
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.13-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
|
+
}
|