@ch20026103/anysis 0.0.19-alpha1 → 0.0.19
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/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/stockSkills/dmi.d.ts +28 -0
- package/dist/cjs/stockSkills/dmi.js +206 -0
- package/dist/cjs/stockSkills/dmi.test.d.ts +1 -0
- package/dist/cjs/stockSkills/dmi.test.js +71 -0
- package/dist/cjs/stockSkills/ichimoku.d.ts +1 -1
- package/dist/cjs/stockSkills/ichimoku.js +8 -8
- package/dist/cjs/stockSkills/ichimoku.test.js +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/stockSkills/dmi.d.ts +28 -0
- package/dist/esm/stockSkills/dmi.js +204 -0
- package/dist/esm/stockSkills/dmi.test.d.ts +1 -0
- package/dist/esm/stockSkills/dmi.test.js +69 -0
- package/dist/esm/stockSkills/ichimoku.d.ts +1 -1
- package/dist/esm/stockSkills/ichimoku.js +8 -8
- package/dist/esm/stockSkills/ichimoku.test.js +4 -4
- package/dist/umd/index.js +267 -65
- package/package.json +1 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import Dmi from "./dmi";
|
|
2
|
+
import data from "./test_data.test";
|
|
3
|
+
describe("test dmi methods", function () {
|
|
4
|
+
it("test init & next", function () {
|
|
5
|
+
var dmi = new Dmi();
|
|
6
|
+
var period = 14;
|
|
7
|
+
// Calculate all values using loop
|
|
8
|
+
var results = dmi.calculateDmiValues(data, period);
|
|
9
|
+
var lastResult = results[results.length - 1];
|
|
10
|
+
// Verify consistency
|
|
11
|
+
// Re-run step-by-step
|
|
12
|
+
var state = dmi.init(data[0], period);
|
|
13
|
+
for (var i = 1; i < data.length; i++) {
|
|
14
|
+
state = dmi.next(data[i], state, period);
|
|
15
|
+
}
|
|
16
|
+
expect(state.pDi).toEqual(lastResult.pDi);
|
|
17
|
+
expect(state.mDi).toEqual(lastResult.mDi);
|
|
18
|
+
expect(state.adx).toEqual(lastResult.adx);
|
|
19
|
+
});
|
|
20
|
+
it("test values consistency (basic sanity)", function () {
|
|
21
|
+
// Generate a simple synthetic dataset where Trend is obvious
|
|
22
|
+
// Upward trend -> +DI should be high, -DI low
|
|
23
|
+
var upTrendData = [];
|
|
24
|
+
for (var i = 0; i < 50; i++) {
|
|
25
|
+
upTrendData.push({
|
|
26
|
+
c: 10 + i,
|
|
27
|
+
h: 11 + i,
|
|
28
|
+
l: 9 + i,
|
|
29
|
+
o: 10 + i,
|
|
30
|
+
v: 1000,
|
|
31
|
+
t: 20210101 + i,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
var dmi = new Dmi();
|
|
35
|
+
var res = dmi.calculateDmiValues(upTrendData, 14);
|
|
36
|
+
var last = res[res.length - 1];
|
|
37
|
+
// +DI should be dominant
|
|
38
|
+
expect(last.pDi).toBeGreaterThan(last.mDi);
|
|
39
|
+
// ADX should be high (strong trend)
|
|
40
|
+
expect(last.adx).toBeGreaterThan(20);
|
|
41
|
+
});
|
|
42
|
+
it("test flat trend", function () {
|
|
43
|
+
// Flat data
|
|
44
|
+
var flatData = [];
|
|
45
|
+
for (var i = 0; i < 50; i++) {
|
|
46
|
+
flatData.push({
|
|
47
|
+
c: 10,
|
|
48
|
+
h: 11,
|
|
49
|
+
l: 9,
|
|
50
|
+
o: 10,
|
|
51
|
+
v: 1000,
|
|
52
|
+
t: 20210101 + i,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
var dmi = new Dmi();
|
|
56
|
+
var res = dmi.calculateDmiValues(flatData, 14);
|
|
57
|
+
var last = res[res.length - 1];
|
|
58
|
+
// No directional movement
|
|
59
|
+
// h-ph = 0, pl-l = 0.
|
|
60
|
+
// +DM = 0, -DM = 0.
|
|
61
|
+
// +DI = 0, -DI = 0.
|
|
62
|
+
// ADX = 0?
|
|
63
|
+
// DX = 0.
|
|
64
|
+
expect(last.pDi).toEqual(0);
|
|
65
|
+
expect(last.mDi).toEqual(0);
|
|
66
|
+
// ADX might be 0 or close to 0
|
|
67
|
+
expect(last.adx).toEqual(0);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -15,7 +15,7 @@ interface IchimokuType {
|
|
|
15
15
|
init: (data: NewStockType) => IchimokuResType;
|
|
16
16
|
next: (data: NewStockType, preList: IchimokuResType) => IchimokuResType;
|
|
17
17
|
}
|
|
18
|
-
export default class
|
|
18
|
+
export default class Ichimoku implements IchimokuType {
|
|
19
19
|
init(data: NewStockType): IchimokuResType;
|
|
20
20
|
/**
|
|
21
21
|
* 優化說明:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var
|
|
2
|
-
function
|
|
1
|
+
var Ichimoku = /** @class */ (function () {
|
|
2
|
+
function Ichimoku() {
|
|
3
3
|
}
|
|
4
|
-
Object.defineProperty(
|
|
4
|
+
Object.defineProperty(Ichimoku.prototype, "init", {
|
|
5
5
|
enumerable: false,
|
|
6
6
|
configurable: true,
|
|
7
7
|
writable: true,
|
|
@@ -19,7 +19,7 @@ var IchimokuCloud = /** @class */ (function () {
|
|
|
19
19
|
* 如果你的框架 (如 React state) 強制要求 immutable,則需要改回 [...prev, data] 的寫法。
|
|
20
20
|
* 下面的寫法假設可以 Mutation (這在 Class 內部運算或 Backend 處理很常見)。
|
|
21
21
|
*/
|
|
22
|
-
Object.defineProperty(
|
|
22
|
+
Object.defineProperty(Ichimoku.prototype, "next", {
|
|
23
23
|
enumerable: false,
|
|
24
24
|
configurable: true,
|
|
25
25
|
writable: true,
|
|
@@ -36,7 +36,7 @@ var IchimokuCloud = /** @class */ (function () {
|
|
|
36
36
|
}
|
|
37
37
|
});
|
|
38
38
|
// 核心計算邏輯
|
|
39
|
-
Object.defineProperty(
|
|
39
|
+
Object.defineProperty(Ichimoku.prototype, "calcIchimoku", {
|
|
40
40
|
enumerable: false,
|
|
41
41
|
configurable: true,
|
|
42
42
|
writable: true,
|
|
@@ -64,7 +64,7 @@ var IchimokuCloud = /** @class */ (function () {
|
|
|
64
64
|
* 1. 移除 .slice(),避免產生 Garbage Collection。
|
|
65
65
|
* 2. 使用反向迴圈 (i--),通常在 JS 引擎中微幅快一點,且語意上是「從現在往回看」。
|
|
66
66
|
*/
|
|
67
|
-
Object.defineProperty(
|
|
67
|
+
Object.defineProperty(Ichimoku.prototype, "getMidPrice", {
|
|
68
68
|
enumerable: false,
|
|
69
69
|
configurable: true,
|
|
70
70
|
writable: true,
|
|
@@ -89,6 +89,6 @@ var IchimokuCloud = /** @class */ (function () {
|
|
|
89
89
|
return (maxH + minL) / 2;
|
|
90
90
|
}
|
|
91
91
|
});
|
|
92
|
-
return
|
|
92
|
+
return Ichimoku;
|
|
93
93
|
}());
|
|
94
|
-
export default
|
|
94
|
+
export default Ichimoku;
|
|
@@ -10,15 +10,15 @@ var __assign = (this && this.__assign) || function () {
|
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
12
|
import { beforeEach, describe, expect, it } from "vitest";
|
|
13
|
-
import
|
|
13
|
+
import Ichimoku from "./ichimoku";
|
|
14
14
|
// 輔助函式:快速產生測試用的假資料
|
|
15
15
|
var createStock = function (idx, override) {
|
|
16
16
|
return __assign({ t: idx, o: 100, c: 100, h: 100, l: 100, v: 1000 }, override);
|
|
17
17
|
};
|
|
18
|
-
describe("
|
|
18
|
+
describe("Ichimoku Algo", function () {
|
|
19
19
|
var ichimoku;
|
|
20
20
|
beforeEach(function () {
|
|
21
|
-
ichimoku = new
|
|
21
|
+
ichimoku = new Ichimoku();
|
|
22
22
|
});
|
|
23
23
|
describe("init", function () {
|
|
24
24
|
it("should initialize with correct structure", function () {
|
|
@@ -112,7 +112,7 @@ describe("IchimokuCloud Algo", function () {
|
|
|
112
112
|
// 注意:上面的 init 和 next 已經把資料寫死為 100 了,這在單元測試有點難搞
|
|
113
113
|
// 所以我們用更簡單的方法:在 next 過程中精準控制
|
|
114
114
|
// --- 重來:精準控制版 ---
|
|
115
|
-
var ichi = new
|
|
115
|
+
var ichi = new Ichimoku();
|
|
116
116
|
var r = ichi.init(createStock(0, { h: 120, l: 80 })); // Kijun Range: H=120, L=80
|
|
117
117
|
// 填滿中間 16 筆 (Index 1~16),數值平穩不影響極值,且不讓 Tenkan 抓到
|
|
118
118
|
for (var i = 1; i <= 16; i++) {
|