@ch20026103/anysis 0.0.14-alpha → 0.0.15-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,12 +1,12 @@
1
1
  /* eslint @typescript-eslint/no-var-requires: "off" */
2
2
  const axios = require("axios");
3
3
  const {
4
- Gold,
5
- SwingExtremesType,
6
- SwingExtremes,
4
+ Rsi,
7
5
  } = require("../dist/cjs/index.js");
8
6
 
9
- const gold = new Gold();
7
+
8
+ // 使用示例
9
+ const rsi = new Rsi();
10
10
  function DemoDay(stockId) {
11
11
  axios
12
12
  .get(
@@ -16,13 +16,13 @@ function DemoDay(stockId) {
16
16
  res = res.data.replace(/^\(|\);$/g, "");
17
17
  let parse = JSON.parse(res);
18
18
  let data = parse.ta;
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);
19
+ const rsis = rsi.calculateRSI(data, 5);
20
+ let rsi5Data = rsi.init(data[0],5);
21
+ for (let i = 1; i < data.length; i++) {
22
+ rsi5Data = rsi.next(data[i], rsi5Data, 5);
23
+ }
24
+ console.log("rsi", rsis[rsis.length - 2]);
25
+ console.log("rsi", rsi5Data);
26
26
  })
27
27
  .catch((error) => {
28
28
  console.error(error);
@@ -32,4 +32,4 @@ function DemoDay(stockId) {
32
32
  });
33
33
  }
34
34
 
35
- DemoDay("2449");
35
+ DemoDay("2385");
@@ -1,32 +1,29 @@
1
- type ListType = {
1
+ type DataType = {
2
2
  c: number;
3
- }[];
4
- type ResRsi6Type = {
5
- c: number;
6
- rsi6: number | null;
7
- }[];
8
- type ResRsi12Type = {
9
- c: number;
10
- rsi12: number | null;
11
- }[];
12
- type ResAllRsiType = {
13
- c: number;
14
- rsi6: number | null;
15
- rsi12: number | null;
16
- }[];
17
- interface RsiType {
18
- getRsi6: (list: ListType) => ResRsi6Type;
19
- getRsi12: (list: ListType) => ResRsi12Type;
20
- getStartUpAvg: (list: ListType, count: number) => number;
21
- getStartDownAvg: (list: ListType, count: number) => number;
22
- getRsi: (UpAvg: number, DownAvg: number) => number;
23
- }
24
- export default class Rsi implements RsiType {
25
- getAllRsi(list: ListType): ResAllRsiType;
26
- getRsi6(list: ListType): ResRsi6Type;
27
- getRsi12(list: ListType): ResRsi12Type;
28
- getStartUpAvg(list: ListType, count: number): number;
29
- getStartDownAvg(list: ListType, count: number): number;
30
- getRsi(UpAvg: number, DownAvg: number): number;
3
+ [key: string]: unknown;
4
+ };
5
+ type ListType = DataType[];
6
+ export default class Rsi {
7
+ init(data: DataType, type: number): {
8
+ dataset: DataType[];
9
+ rsi: number;
10
+ type: number;
11
+ avgGain: number;
12
+ avgLoss: number;
13
+ };
14
+ next(data: DataType, preList: {
15
+ dataset: ListType;
16
+ rsi: number;
17
+ type: number;
18
+ avgGain: number;
19
+ avgLoss: number;
20
+ }, type: number): {
21
+ rsi: number;
22
+ type: number;
23
+ avgGain: number;
24
+ avgLoss: number;
25
+ dataset: ListType;
26
+ };
27
+ calculateRSI(prices: ListType, period?: number): number[];
31
28
  }
32
29
  export {};
@@ -14,130 +14,108 @@ Object.defineProperty(exports, "__esModule", { value: true });
14
14
  var Rsi = /** @class */ (function () {
15
15
  function Rsi() {
16
16
  }
17
- Object.defineProperty(Rsi.prototype, "getAllRsi", {
17
+ Object.defineProperty(Rsi.prototype, "init", {
18
18
  enumerable: false,
19
19
  configurable: true,
20
20
  writable: true,
21
- value: function (list) {
22
- var res = [];
23
- var rsi6 = this.getRsi6(list);
24
- var rsi12 = this.getRsi12(list);
25
- for (var i = 0; i < list.length; i++) {
26
- res[i] = Object.assign(list[i], rsi6[i], rsi12[i]);
27
- }
28
- return res;
21
+ value: function (data, type) {
22
+ return {
23
+ dataset: [data],
24
+ rsi: 0,
25
+ type: type,
26
+ avgGain: 0,
27
+ avgLoss: 0,
28
+ };
29
29
  }
30
30
  });
31
- Object.defineProperty(Rsi.prototype, "getRsi6", {
31
+ Object.defineProperty(Rsi.prototype, "next", {
32
32
  enumerable: false,
33
33
  configurable: true,
34
34
  writable: true,
35
- value: function (list) {
36
- var res = [];
37
- // 前5筆
38
- for (var i = 0; i < 5; i++) {
39
- res[i] = __assign(__assign({}, list[i]), { rsi6: null });
35
+ value: function (data, preList, type) {
36
+ preList.dataset.push(data);
37
+ if (preList.dataset.length < type + 1) {
38
+ return __assign(__assign({}, preList), { rsi: 0, type: type, avgGain: 0, avgLoss: 0 });
40
39
  }
41
- // 第6筆Rsi
42
- var beforeUpAvg = this.getStartUpAvg(list, 6);
43
- var beforeDownAvg = this.getStartDownAvg(list, 6);
44
- var firstRsi6 = this.getRsi(beforeUpAvg, beforeDownAvg);
45
- res[5] = __assign(__assign({}, list[5]), { rsi6: firstRsi6 });
46
- // else
47
- for (var i = 6; i < list.length; i++) {
48
- var minusU = 0;
49
- var minusD = 0;
50
- var minusC = list[i]["c"] - list[i - 1]["c"];
51
- if (minusC > 0) {
52
- minusU = minusC;
40
+ else {
41
+ // 计算初始增益和损失
42
+ var avgGain = 0;
43
+ var avgLoss = 0;
44
+ if (preList.dataset.length === type + 1) {
45
+ var gains = 0;
46
+ var losses = 0;
47
+ for (var i = 1; i <= type; i++) {
48
+ var change = preList.dataset[i].c - preList.dataset[i - 1].c;
49
+ if (change > 0) {
50
+ gains += change;
51
+ }
52
+ else {
53
+ losses -= change;
54
+ }
55
+ }
56
+ avgGain = gains / type;
57
+ avgLoss = losses / type;
53
58
  }
54
- else {
55
- minusD = minusC;
59
+ else if (preList.dataset.length > type + 1) {
60
+ preList.dataset.shift();
61
+ // 更新平均增益和平均损失
62
+ var change = preList.dataset[preList.dataset.length - 1].c -
63
+ preList.dataset[preList.dataset.length - 2].c;
64
+ avgGain =
65
+ (preList.avgGain * (type - 1) + (change > 0 ? change : 0)) / type;
66
+ avgLoss =
67
+ (preList.avgLoss * (type - 1) + (change < 0 ? -change : 0)) / type;
56
68
  }
57
- beforeUpAvg = (beforeUpAvg * 5) / 6 + minusU / 6;
58
- beforeDownAvg = (beforeDownAvg * 5) / 6 + Math.abs(minusD) / 6;
59
- var rsi6 = this.getRsi(beforeUpAvg, beforeDownAvg);
60
- res[i] = __assign(__assign({}, list[i]), { rsi6: Math.round(rsi6 * 100) / 100 });
69
+ // 计算RSI
70
+ var rs = avgGain / avgLoss;
71
+ var rsi = 100 - 100 / (1 + rs);
72
+ return __assign(__assign({}, preList), { type: type, rsi: rsi, avgGain: avgGain, avgLoss: avgLoss });
61
73
  }
62
- return res;
63
74
  }
64
75
  });
65
- Object.defineProperty(Rsi.prototype, "getRsi12", {
76
+ Object.defineProperty(Rsi.prototype, "calculateRSI", {
66
77
  enumerable: false,
67
78
  configurable: true,
68
79
  writable: true,
69
- value: function (list) {
70
- var res = [];
71
- // 前11筆
72
- for (var i = 0; i < 11; i++) {
73
- res[i] = __assign(__assign({}, list[i]), { rsi12: null });
80
+ value: function (prices, period) {
81
+ if (period === void 0) { period = 5; }
82
+ if (prices.length < period + 1) {
83
+ return [];
74
84
  }
75
- // 第12筆Rsi
76
- var beforeUpAvg = this.getStartUpAvg(list, 12);
77
- var beforeDownAvg = this.getStartDownAvg(list, 12);
78
- var firstRsi12 = this.getRsi(beforeUpAvg, beforeDownAvg);
79
- res[11] = __assign(__assign({}, list[11]), { rsi12: firstRsi12 });
80
- // else
81
- for (var i = 12; i < list.length; i++) {
82
- var minusU = 0;
83
- var minusD = 0;
84
- var minusC = list[i]["c"] - list[i - 1]["c"];
85
- if (minusC > 0) {
86
- minusU = minusC;
87
- }
88
- else {
89
- minusD = minusC;
90
- }
91
- beforeUpAvg = (beforeUpAvg * 11) / 12 + minusU / 12;
92
- beforeDownAvg = (beforeDownAvg * 11) / 12 + Math.abs(minusD) / 12;
93
- var rsi12 = this.getRsi(beforeUpAvg, beforeDownAvg);
94
- res[i] = __assign(__assign({}, list[i]), { rsi12: Math.round(rsi12 * 100) / 100 });
85
+ // 计算价格变化
86
+ var changes = [];
87
+ for (var i = 1; i < prices.length; i++) {
88
+ changes.push(prices[i].c - prices[i - 1].c);
95
89
  }
96
- return res;
97
- }
98
- });
99
- Object.defineProperty(Rsi.prototype, "getStartUpAvg", {
100
- enumerable: false,
101
- configurable: true,
102
- writable: true,
103
- value: function (list, count) {
104
- var start = list.slice(0, 5);
105
- var sum = 0;
106
- for (var i = 1; i < start.length; i++) {
107
- var minus = start[i]["c"] - start[i - 1]["c"];
108
- if (minus > 0) {
109
- sum += minus;
90
+ // 计算增益和损失
91
+ var gains = 0;
92
+ var losses = 0;
93
+ for (var i = 0; i < period; i++) {
94
+ if (changes[i] > 0) {
95
+ gains += changes[i];
110
96
  }
111
- }
112
- return sum / count;
113
- }
114
- });
115
- Object.defineProperty(Rsi.prototype, "getStartDownAvg", {
116
- enumerable: false,
117
- configurable: true,
118
- writable: true,
119
- value: function (list, count) {
120
- var start = list.slice(0, 5);
121
- var sum = 0;
122
- for (var i = 1; i < start.length; i++) {
123
- var minus = start[i]["c"] - start[i - 1]["c"];
124
- if (minus < 0) {
125
- sum += minus;
97
+ else {
98
+ losses -= changes[i];
126
99
  }
127
100
  }
128
- return Math.abs(sum / count);
129
- }
130
- });
131
- Object.defineProperty(Rsi.prototype, "getRsi", {
132
- enumerable: false,
133
- configurable: true,
134
- writable: true,
135
- value: function (UpAvg, DownAvg) {
136
- var res = 0;
137
- if (UpAvg + DownAvg !== 0) {
138
- res = (UpAvg / (UpAvg + DownAvg)) * 100;
101
+ // 计算初始平均增益和平均损失
102
+ var avgGain = gains / period;
103
+ var avgLoss = losses / period;
104
+ // 计算RSI
105
+ var rsis = [];
106
+ var rs = avgGain / avgLoss;
107
+ var rsi = 100 - 100 / (1 + rs);
108
+ rsis.push(rsi);
109
+ for (var i = period; i < changes.length; i++) {
110
+ // 更新平均增益和平均损失
111
+ var change = changes[i];
112
+ avgGain = (avgGain * (period - 1) + (change > 0 ? change : 0)) / period;
113
+ avgLoss = (avgLoss * (period - 1) + (change < 0 ? -change : 0)) / period;
114
+ var rs_1 = avgGain / avgLoss;
115
+ var rsi_1 = 100 - 100 / (1 + rs_1);
116
+ rsis.push(rsi_1);
139
117
  }
140
- return res;
118
+ return rsis;
141
119
  }
142
120
  });
143
121
  return Rsi;
@@ -3,28 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  var rsi_1 = require("./rsi");
4
4
  var test_data_test_1 = require("./test_data.test");
5
5
  describe("test rsi methods", function () {
6
- it("test getRsi6()", function () {
6
+ it("test init & next", function () {
7
7
  var rsi = new rsi_1.default();
8
- expect(rsi.getRsi6(test_data_test_1.default)[test_data_test_1.default.length - 1]).toEqual({
9
- c: 142,
10
- o: 138,
11
- t: 20211214,
12
- v: 16841,
13
- h: 143,
14
- l: 138,
15
- rsi6: 45.12,
16
- });
8
+ var result = rsi.init(test_data_test_1.default[0], 5);
9
+ for (var i = 1; i < test_data_test_1.default.length; i++) {
10
+ result = rsi.next(test_data_test_1.default[i], result, 5);
11
+ }
12
+ expect(result === null || result === void 0 ? void 0 : result.rsi).toEqual(44.72040034947733);
17
13
  });
18
- it("test getRsi12()", function () {
14
+ it("test calculateRSI()", function () {
19
15
  var rsi = new rsi_1.default();
20
- expect(rsi.getRsi12(test_data_test_1.default)[test_data_test_1.default.length - 1]).toEqual({
21
- c: 142,
22
- o: 138,
23
- t: 20211214,
24
- v: 16841,
25
- h: 143,
26
- l: 138,
27
- rsi12: 49.47,
28
- });
16
+ var result = rsi.calculateRSI(test_data_test_1.default, 5);
17
+ expect(result === null || result === void 0 ? void 0 : result[(result === null || result === void 0 ? void 0 : result.length) - 1]).toEqual(44.72040034947733);
29
18
  });
30
19
  });
@@ -1,32 +1,29 @@
1
- type ListType = {
1
+ type DataType = {
2
2
  c: number;
3
- }[];
4
- type ResRsi6Type = {
5
- c: number;
6
- rsi6: number | null;
7
- }[];
8
- type ResRsi12Type = {
9
- c: number;
10
- rsi12: number | null;
11
- }[];
12
- type ResAllRsiType = {
13
- c: number;
14
- rsi6: number | null;
15
- rsi12: number | null;
16
- }[];
17
- interface RsiType {
18
- getRsi6: (list: ListType) => ResRsi6Type;
19
- getRsi12: (list: ListType) => ResRsi12Type;
20
- getStartUpAvg: (list: ListType, count: number) => number;
21
- getStartDownAvg: (list: ListType, count: number) => number;
22
- getRsi: (UpAvg: number, DownAvg: number) => number;
23
- }
24
- export default class Rsi implements RsiType {
25
- getAllRsi(list: ListType): ResAllRsiType;
26
- getRsi6(list: ListType): ResRsi6Type;
27
- getRsi12(list: ListType): ResRsi12Type;
28
- getStartUpAvg(list: ListType, count: number): number;
29
- getStartDownAvg(list: ListType, count: number): number;
30
- getRsi(UpAvg: number, DownAvg: number): number;
3
+ [key: string]: unknown;
4
+ };
5
+ type ListType = DataType[];
6
+ export default class Rsi {
7
+ init(data: DataType, type: number): {
8
+ dataset: DataType[];
9
+ rsi: number;
10
+ type: number;
11
+ avgGain: number;
12
+ avgLoss: number;
13
+ };
14
+ next(data: DataType, preList: {
15
+ dataset: ListType;
16
+ rsi: number;
17
+ type: number;
18
+ avgGain: number;
19
+ avgLoss: number;
20
+ }, type: number): {
21
+ rsi: number;
22
+ type: number;
23
+ avgGain: number;
24
+ avgLoss: number;
25
+ dataset: ListType;
26
+ };
27
+ calculateRSI(prices: ListType, period?: number): number[];
31
28
  }
32
29
  export {};
@@ -12,130 +12,108 @@ var __assign = (this && this.__assign) || function () {
12
12
  var Rsi = /** @class */ (function () {
13
13
  function Rsi() {
14
14
  }
15
- Object.defineProperty(Rsi.prototype, "getAllRsi", {
15
+ Object.defineProperty(Rsi.prototype, "init", {
16
16
  enumerable: false,
17
17
  configurable: true,
18
18
  writable: true,
19
- value: function (list) {
20
- var res = [];
21
- var rsi6 = this.getRsi6(list);
22
- var rsi12 = this.getRsi12(list);
23
- for (var i = 0; i < list.length; i++) {
24
- res[i] = Object.assign(list[i], rsi6[i], rsi12[i]);
25
- }
26
- return res;
19
+ value: function (data, type) {
20
+ return {
21
+ dataset: [data],
22
+ rsi: 0,
23
+ type: type,
24
+ avgGain: 0,
25
+ avgLoss: 0,
26
+ };
27
27
  }
28
28
  });
29
- Object.defineProperty(Rsi.prototype, "getRsi6", {
29
+ Object.defineProperty(Rsi.prototype, "next", {
30
30
  enumerable: false,
31
31
  configurable: true,
32
32
  writable: true,
33
- value: function (list) {
34
- var res = [];
35
- // 前5筆
36
- for (var i = 0; i < 5; i++) {
37
- res[i] = __assign(__assign({}, list[i]), { rsi6: null });
33
+ value: function (data, preList, type) {
34
+ preList.dataset.push(data);
35
+ if (preList.dataset.length < type + 1) {
36
+ return __assign(__assign({}, preList), { rsi: 0, type: type, avgGain: 0, avgLoss: 0 });
38
37
  }
39
- // 第6筆Rsi
40
- var beforeUpAvg = this.getStartUpAvg(list, 6);
41
- var beforeDownAvg = this.getStartDownAvg(list, 6);
42
- var firstRsi6 = this.getRsi(beforeUpAvg, beforeDownAvg);
43
- res[5] = __assign(__assign({}, list[5]), { rsi6: firstRsi6 });
44
- // else
45
- for (var i = 6; i < list.length; i++) {
46
- var minusU = 0;
47
- var minusD = 0;
48
- var minusC = list[i]["c"] - list[i - 1]["c"];
49
- if (minusC > 0) {
50
- minusU = minusC;
38
+ else {
39
+ // 计算初始增益和损失
40
+ var avgGain = 0;
41
+ var avgLoss = 0;
42
+ if (preList.dataset.length === type + 1) {
43
+ var gains = 0;
44
+ var losses = 0;
45
+ for (var i = 1; i <= type; i++) {
46
+ var change = preList.dataset[i].c - preList.dataset[i - 1].c;
47
+ if (change > 0) {
48
+ gains += change;
49
+ }
50
+ else {
51
+ losses -= change;
52
+ }
53
+ }
54
+ avgGain = gains / type;
55
+ avgLoss = losses / type;
51
56
  }
52
- else {
53
- minusD = minusC;
57
+ else if (preList.dataset.length > type + 1) {
58
+ preList.dataset.shift();
59
+ // 更新平均增益和平均损失
60
+ var change = preList.dataset[preList.dataset.length - 1].c -
61
+ preList.dataset[preList.dataset.length - 2].c;
62
+ avgGain =
63
+ (preList.avgGain * (type - 1) + (change > 0 ? change : 0)) / type;
64
+ avgLoss =
65
+ (preList.avgLoss * (type - 1) + (change < 0 ? -change : 0)) / type;
54
66
  }
55
- beforeUpAvg = (beforeUpAvg * 5) / 6 + minusU / 6;
56
- beforeDownAvg = (beforeDownAvg * 5) / 6 + Math.abs(minusD) / 6;
57
- var rsi6 = this.getRsi(beforeUpAvg, beforeDownAvg);
58
- res[i] = __assign(__assign({}, list[i]), { rsi6: Math.round(rsi6 * 100) / 100 });
67
+ // 计算RSI
68
+ var rs = avgGain / avgLoss;
69
+ var rsi = 100 - 100 / (1 + rs);
70
+ return __assign(__assign({}, preList), { type: type, rsi: rsi, avgGain: avgGain, avgLoss: avgLoss });
59
71
  }
60
- return res;
61
72
  }
62
73
  });
63
- Object.defineProperty(Rsi.prototype, "getRsi12", {
74
+ Object.defineProperty(Rsi.prototype, "calculateRSI", {
64
75
  enumerable: false,
65
76
  configurable: true,
66
77
  writable: true,
67
- value: function (list) {
68
- var res = [];
69
- // 前11筆
70
- for (var i = 0; i < 11; i++) {
71
- res[i] = __assign(__assign({}, list[i]), { rsi12: null });
78
+ value: function (prices, period) {
79
+ if (period === void 0) { period = 5; }
80
+ if (prices.length < period + 1) {
81
+ return [];
72
82
  }
73
- // 第12筆Rsi
74
- var beforeUpAvg = this.getStartUpAvg(list, 12);
75
- var beforeDownAvg = this.getStartDownAvg(list, 12);
76
- var firstRsi12 = this.getRsi(beforeUpAvg, beforeDownAvg);
77
- res[11] = __assign(__assign({}, list[11]), { rsi12: firstRsi12 });
78
- // else
79
- for (var i = 12; i < list.length; i++) {
80
- var minusU = 0;
81
- var minusD = 0;
82
- var minusC = list[i]["c"] - list[i - 1]["c"];
83
- if (minusC > 0) {
84
- minusU = minusC;
85
- }
86
- else {
87
- minusD = minusC;
88
- }
89
- beforeUpAvg = (beforeUpAvg * 11) / 12 + minusU / 12;
90
- beforeDownAvg = (beforeDownAvg * 11) / 12 + Math.abs(minusD) / 12;
91
- var rsi12 = this.getRsi(beforeUpAvg, beforeDownAvg);
92
- res[i] = __assign(__assign({}, list[i]), { rsi12: Math.round(rsi12 * 100) / 100 });
83
+ // 计算价格变化
84
+ var changes = [];
85
+ for (var i = 1; i < prices.length; i++) {
86
+ changes.push(prices[i].c - prices[i - 1].c);
93
87
  }
94
- return res;
95
- }
96
- });
97
- Object.defineProperty(Rsi.prototype, "getStartUpAvg", {
98
- enumerable: false,
99
- configurable: true,
100
- writable: true,
101
- value: function (list, count) {
102
- var start = list.slice(0, 5);
103
- var sum = 0;
104
- for (var i = 1; i < start.length; i++) {
105
- var minus = start[i]["c"] - start[i - 1]["c"];
106
- if (minus > 0) {
107
- sum += minus;
88
+ // 计算增益和损失
89
+ var gains = 0;
90
+ var losses = 0;
91
+ for (var i = 0; i < period; i++) {
92
+ if (changes[i] > 0) {
93
+ gains += changes[i];
108
94
  }
109
- }
110
- return sum / count;
111
- }
112
- });
113
- Object.defineProperty(Rsi.prototype, "getStartDownAvg", {
114
- enumerable: false,
115
- configurable: true,
116
- writable: true,
117
- value: function (list, count) {
118
- var start = list.slice(0, 5);
119
- var sum = 0;
120
- for (var i = 1; i < start.length; i++) {
121
- var minus = start[i]["c"] - start[i - 1]["c"];
122
- if (minus < 0) {
123
- sum += minus;
95
+ else {
96
+ losses -= changes[i];
124
97
  }
125
98
  }
126
- return Math.abs(sum / count);
127
- }
128
- });
129
- Object.defineProperty(Rsi.prototype, "getRsi", {
130
- enumerable: false,
131
- configurable: true,
132
- writable: true,
133
- value: function (UpAvg, DownAvg) {
134
- var res = 0;
135
- if (UpAvg + DownAvg !== 0) {
136
- res = (UpAvg / (UpAvg + DownAvg)) * 100;
99
+ // 计算初始平均增益和平均损失
100
+ var avgGain = gains / period;
101
+ var avgLoss = losses / period;
102
+ // 计算RSI
103
+ var rsis = [];
104
+ var rs = avgGain / avgLoss;
105
+ var rsi = 100 - 100 / (1 + rs);
106
+ rsis.push(rsi);
107
+ for (var i = period; i < changes.length; i++) {
108
+ // 更新平均增益和平均损失
109
+ var change = changes[i];
110
+ avgGain = (avgGain * (period - 1) + (change > 0 ? change : 0)) / period;
111
+ avgLoss = (avgLoss * (period - 1) + (change < 0 ? -change : 0)) / period;
112
+ var rs_1 = avgGain / avgLoss;
113
+ var rsi_1 = 100 - 100 / (1 + rs_1);
114
+ rsis.push(rsi_1);
137
115
  }
138
- return res;
116
+ return rsis;
139
117
  }
140
118
  });
141
119
  return Rsi;
@@ -1,28 +1,17 @@
1
1
  import Rsi from "./rsi";
2
2
  import data from "./test_data.test";
3
3
  describe("test rsi methods", function () {
4
- it("test getRsi6()", function () {
4
+ it("test init & next", function () {
5
5
  var rsi = new Rsi();
6
- expect(rsi.getRsi6(data)[data.length - 1]).toEqual({
7
- c: 142,
8
- o: 138,
9
- t: 20211214,
10
- v: 16841,
11
- h: 143,
12
- l: 138,
13
- rsi6: 45.12,
14
- });
6
+ var result = rsi.init(data[0], 5);
7
+ for (var i = 1; i < data.length; i++) {
8
+ result = rsi.next(data[i], result, 5);
9
+ }
10
+ expect(result === null || result === void 0 ? void 0 : result.rsi).toEqual(44.72040034947733);
15
11
  });
16
- it("test getRsi12()", function () {
12
+ it("test calculateRSI()", function () {
17
13
  var rsi = new Rsi();
18
- expect(rsi.getRsi12(data)[data.length - 1]).toEqual({
19
- c: 142,
20
- o: 138,
21
- t: 20211214,
22
- v: 16841,
23
- h: 143,
24
- l: 138,
25
- rsi12: 49.47,
26
- });
14
+ var result = rsi.calculateRSI(data, 5);
15
+ expect(result === null || result === void 0 ? void 0 : result[(result === null || result === void 0 ? void 0 : result.length) - 1]).toEqual(44.72040034947733);
27
16
  });
28
17
  });
package/dist/umd/index.js CHANGED
@@ -1386,130 +1386,108 @@
1386
1386
  var Rsi = /** @class */ (function () {
1387
1387
  function Rsi() {
1388
1388
  }
1389
- Object.defineProperty(Rsi.prototype, "getAllRsi", {
1389
+ Object.defineProperty(Rsi.prototype, "init", {
1390
1390
  enumerable: false,
1391
1391
  configurable: true,
1392
1392
  writable: true,
1393
- value: function (list) {
1394
- var res = [];
1395
- var rsi6 = this.getRsi6(list);
1396
- var rsi12 = this.getRsi12(list);
1397
- for (var i = 0; i < list.length; i++) {
1398
- res[i] = Object.assign(list[i], rsi6[i], rsi12[i]);
1399
- }
1400
- return res;
1393
+ value: function (data, type) {
1394
+ return {
1395
+ dataset: [data],
1396
+ rsi: 0,
1397
+ type: type,
1398
+ avgGain: 0,
1399
+ avgLoss: 0,
1400
+ };
1401
1401
  }
1402
1402
  });
1403
- Object.defineProperty(Rsi.prototype, "getRsi6", {
1403
+ Object.defineProperty(Rsi.prototype, "next", {
1404
1404
  enumerable: false,
1405
1405
  configurable: true,
1406
1406
  writable: true,
1407
- value: function (list) {
1408
- var res = [];
1409
- // 前5筆
1410
- for (var i = 0; i < 5; i++) {
1411
- res[i] = __assign$1(__assign$1({}, list[i]), { rsi6: null });
1407
+ value: function (data, preList, type) {
1408
+ preList.dataset.push(data);
1409
+ if (preList.dataset.length < type + 1) {
1410
+ return __assign$1(__assign$1({}, preList), { rsi: 0, type: type, avgGain: 0, avgLoss: 0 });
1412
1411
  }
1413
- // 第6筆Rsi
1414
- var beforeUpAvg = this.getStartUpAvg(list, 6);
1415
- var beforeDownAvg = this.getStartDownAvg(list, 6);
1416
- var firstRsi6 = this.getRsi(beforeUpAvg, beforeDownAvg);
1417
- res[5] = __assign$1(__assign$1({}, list[5]), { rsi6: firstRsi6 });
1418
- // else
1419
- for (var i = 6; i < list.length; i++) {
1420
- var minusU = 0;
1421
- var minusD = 0;
1422
- var minusC = list[i]["c"] - list[i - 1]["c"];
1423
- if (minusC > 0) {
1424
- minusU = minusC;
1412
+ else {
1413
+ // 计算初始增益和损失
1414
+ var avgGain = 0;
1415
+ var avgLoss = 0;
1416
+ if (preList.dataset.length === type + 1) {
1417
+ var gains = 0;
1418
+ var losses = 0;
1419
+ for (var i = 1; i <= type; i++) {
1420
+ var change = preList.dataset[i].c - preList.dataset[i - 1].c;
1421
+ if (change > 0) {
1422
+ gains += change;
1423
+ }
1424
+ else {
1425
+ losses -= change;
1426
+ }
1427
+ }
1428
+ avgGain = gains / type;
1429
+ avgLoss = losses / type;
1425
1430
  }
1426
- else {
1427
- minusD = minusC;
1431
+ else if (preList.dataset.length > type + 1) {
1432
+ preList.dataset.shift();
1433
+ // 更新平均增益和平均损失
1434
+ var change = preList.dataset[preList.dataset.length - 1].c -
1435
+ preList.dataset[preList.dataset.length - 2].c;
1436
+ avgGain =
1437
+ (preList.avgGain * (type - 1) + (change > 0 ? change : 0)) / type;
1438
+ avgLoss =
1439
+ (preList.avgLoss * (type - 1) + (change < 0 ? -change : 0)) / type;
1428
1440
  }
1429
- beforeUpAvg = (beforeUpAvg * 5) / 6 + minusU / 6;
1430
- beforeDownAvg = (beforeDownAvg * 5) / 6 + Math.abs(minusD) / 6;
1431
- var rsi6 = this.getRsi(beforeUpAvg, beforeDownAvg);
1432
- res[i] = __assign$1(__assign$1({}, list[i]), { rsi6: Math.round(rsi6 * 100) / 100 });
1441
+ // 计算RSI
1442
+ var rs = avgGain / avgLoss;
1443
+ var rsi = 100 - 100 / (1 + rs);
1444
+ return __assign$1(__assign$1({}, preList), { type: type, rsi: rsi, avgGain: avgGain, avgLoss: avgLoss });
1433
1445
  }
1434
- return res;
1435
1446
  }
1436
1447
  });
1437
- Object.defineProperty(Rsi.prototype, "getRsi12", {
1448
+ Object.defineProperty(Rsi.prototype, "calculateRSI", {
1438
1449
  enumerable: false,
1439
1450
  configurable: true,
1440
1451
  writable: true,
1441
- value: function (list) {
1442
- var res = [];
1443
- // 前11筆
1444
- for (var i = 0; i < 11; i++) {
1445
- res[i] = __assign$1(__assign$1({}, list[i]), { rsi12: null });
1452
+ value: function (prices, period) {
1453
+ if (period === void 0) { period = 5; }
1454
+ if (prices.length < period + 1) {
1455
+ return [];
1446
1456
  }
1447
- // 第12筆Rsi
1448
- var beforeUpAvg = this.getStartUpAvg(list, 12);
1449
- var beforeDownAvg = this.getStartDownAvg(list, 12);
1450
- var firstRsi12 = this.getRsi(beforeUpAvg, beforeDownAvg);
1451
- res[11] = __assign$1(__assign$1({}, list[11]), { rsi12: firstRsi12 });
1452
- // else
1453
- for (var i = 12; i < list.length; i++) {
1454
- var minusU = 0;
1455
- var minusD = 0;
1456
- var minusC = list[i]["c"] - list[i - 1]["c"];
1457
- if (minusC > 0) {
1458
- minusU = minusC;
1459
- }
1460
- else {
1461
- minusD = minusC;
1462
- }
1463
- beforeUpAvg = (beforeUpAvg * 11) / 12 + minusU / 12;
1464
- beforeDownAvg = (beforeDownAvg * 11) / 12 + Math.abs(minusD) / 12;
1465
- var rsi12 = this.getRsi(beforeUpAvg, beforeDownAvg);
1466
- res[i] = __assign$1(__assign$1({}, list[i]), { rsi12: Math.round(rsi12 * 100) / 100 });
1457
+ // 计算价格变化
1458
+ var changes = [];
1459
+ for (var i = 1; i < prices.length; i++) {
1460
+ changes.push(prices[i].c - prices[i - 1].c);
1467
1461
  }
1468
- return res;
1469
- }
1470
- });
1471
- Object.defineProperty(Rsi.prototype, "getStartUpAvg", {
1472
- enumerable: false,
1473
- configurable: true,
1474
- writable: true,
1475
- value: function (list, count) {
1476
- var start = list.slice(0, 5);
1477
- var sum = 0;
1478
- for (var i = 1; i < start.length; i++) {
1479
- var minus = start[i]["c"] - start[i - 1]["c"];
1480
- if (minus > 0) {
1481
- sum += minus;
1462
+ // 计算增益和损失
1463
+ var gains = 0;
1464
+ var losses = 0;
1465
+ for (var i = 0; i < period; i++) {
1466
+ if (changes[i] > 0) {
1467
+ gains += changes[i];
1482
1468
  }
1483
- }
1484
- return sum / count;
1485
- }
1486
- });
1487
- Object.defineProperty(Rsi.prototype, "getStartDownAvg", {
1488
- enumerable: false,
1489
- configurable: true,
1490
- writable: true,
1491
- value: function (list, count) {
1492
- var start = list.slice(0, 5);
1493
- var sum = 0;
1494
- for (var i = 1; i < start.length; i++) {
1495
- var minus = start[i]["c"] - start[i - 1]["c"];
1496
- if (minus < 0) {
1497
- sum += minus;
1469
+ else {
1470
+ losses -= changes[i];
1498
1471
  }
1499
1472
  }
1500
- return Math.abs(sum / count);
1501
- }
1502
- });
1503
- Object.defineProperty(Rsi.prototype, "getRsi", {
1504
- enumerable: false,
1505
- configurable: true,
1506
- writable: true,
1507
- value: function (UpAvg, DownAvg) {
1508
- var res = 0;
1509
- if (UpAvg + DownAvg !== 0) {
1510
- res = (UpAvg / (UpAvg + DownAvg)) * 100;
1473
+ // 计算初始平均增益和平均损失
1474
+ var avgGain = gains / period;
1475
+ var avgLoss = losses / period;
1476
+ // 计算RSI
1477
+ var rsis = [];
1478
+ var rs = avgGain / avgLoss;
1479
+ var rsi = 100 - 100 / (1 + rs);
1480
+ rsis.push(rsi);
1481
+ for (var i = period; i < changes.length; i++) {
1482
+ // 更新平均增益和平均损失
1483
+ var change = changes[i];
1484
+ avgGain = (avgGain * (period - 1) + (change > 0 ? change : 0)) / period;
1485
+ avgLoss = (avgLoss * (period - 1) + (change < 0 ? -change : 0)) / period;
1486
+ var rs_1 = avgGain / avgLoss;
1487
+ var rsi_1 = 100 - 100 / (1 + rs_1);
1488
+ rsis.push(rsi_1);
1511
1489
  }
1512
- return res;
1490
+ return rsis;
1513
1491
  }
1514
1492
  });
1515
1493
  return Rsi;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ch20026103/anysis",
3
- "version": "0.0.14-alpha",
3
+ "version": "0.0.15-alpha",
4
4
  "description": "provide many analyze methods in the library.",
5
5
  "keywords": [],
6
6
  "bugs": "git@github.com:cosmic1330/anysis/issues",