@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 CHANGED
@@ -1,77 +1,24 @@
1
1
  /* eslint @typescript-eslint/no-var-requires: "off" */
2
2
  const axios = require("axios");
3
- const { Obv, Macd, Kd, Boll, Vma } = require("../dist/cjs/index.js");
4
- const obv = new Obv();
5
- const macd = new Macd();
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
- let json = res.data.match(/"ta":(\S*),"ex"/)[1];
21
- let data = JSON.parse(json).slice(0, -21);
22
- let obvData = obv.init(data[0], 5);
23
- let macdData = macd.init(data[0]);
24
- let kdData = kd.init(data[0]);
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
- obvData = obv.next(data[i], obvData, 5);
50
- macdData = macd.next(data[i], macdData);
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(finallyData[finallyData.length - 1]);
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
- function DemoWeek() {
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 (0,0) (1,10)", function () {
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 (0,0) (1,0)", function () {
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
+ });
@@ -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/TimeSeries/R/index.js");
16
- Object.defineProperty(exports, "exponentialSmoothing", { enumerable: true, get: function () { return index_js_3.exponentialSmoothing; } });
17
- Object.defineProperty(exports, "movingAverages", { enumerable: true, get: function () { return index_js_3.movingAverages; } });
18
- Object.defineProperty(exports, "weightMovingAverages", { enumerable: true, get: function () { return index_js_3.weightMovingAverages; } });
19
- var index_js_4 = require("./analyze/TimeSeries/RS/index.js");
20
- Object.defineProperty(exports, "calcSeasonalIndicesNoTrend", { enumerable: true, get: function () { return index_js_4.calcSeasonalIndicesNoTrend; } });
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");
@@ -1,5 +1,6 @@
1
1
  type ItemType = {
2
2
  c: number;
3
+ [key: string]: unknown;
3
4
  };
4
5
  type ListType = ItemType[];
5
6
  type ResBoll = {
@@ -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 ListType = {
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 close_1 = list[i]["c"];
46
- var williams9 = ((max - close_1) / (max - min)) * -100;
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 close_2 = list[i]["c"];
68
- var williams18 = ((max - close_2) / (max - min)) * -100;
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 (0,0) (1,10)", function () {
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 (0,0) (1,0)", function () {
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
+ });
@@ -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";
@@ -1,5 +1,6 @@
1
1
  type ItemType = {
2
2
  c: number;
3
+ [key: string]: unknown;
3
4
  };
4
5
  type ListType = ItemType[];
5
6
  type ResBoll = {
@@ -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 ListType = {
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 close_1 = list[i]["c"];
44
- var williams9 = ((max - close_1) / (max - min)) * -100;
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 close_2 = list[i]["c"];
66
- var williams18 = ((max - close_2) / (max - min)) * -100;
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 close_1 = list[i]["c"];
1524
- var williams9 = ((max - close_1) / (max - min)) * -100;
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 close_2 = list[i]["c"];
1546
- var williams18 = ((max - close_2) / (max - min)) * -100;
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.11-alpha",
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
+ }