Skip to content

Commit

Permalink
refactor: apply the new accessor to replace length - 1 / length -2
Browse files Browse the repository at this point in the history
  • Loading branch information
Thrimbda committed Dec 21, 2023
1 parent 5a3462b commit bb3cafa
Show file tree
Hide file tree
Showing 20 changed files with 263 additions and 209 deletions.
21 changes: 12 additions & 9 deletions @libs/indicators/MAX.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,31 @@ export const useMAX = (source: Series, period: number) => {
// 单调队列: 保存当前窗口期内,比最新的元素小的元素的索引
const queue = useRef<number[]>([]);
useEffect(() => {
const i = source.length - 2;
if (i < 0) return;
const previousIndex = source.previousIndex;
if (previousIndex < 0) return;
// 从栈顶开始,移除所有小于当前值的元素
while (
queue.current.length > 0 &&
source[queue.current[queue.current.length - 1]] <= source[i]
source[queue.current[queue.current.length - 1]] <= source.previousValue
) {
queue.current.pop();
}
// 将当前值入栈
queue.current.push(i);
queue.current.push(previousIndex);
// 移除超出窗口期的元素 (通常一次只会移除一个)
while (queue.current.length > 0 && queue.current[0] <= i - period) {
while (
queue.current.length > 0 &&
queue.current[0] <= previousIndex - period
) {
queue.current.shift();
}
}, [source.length]);
useEffect(() => {
const i = source.length - 1;
if (i < 0) return;
const currentIndex = source.currentIndex;
if (currentIndex < 0) return;
// 队首元素即为当前窗口期内的最小值
MAX[i] = Math.max(
source[source.length - 1],
MAX[currentIndex] = Math.max(
source.currentValue,
source[queue.current[0]] || -Infinity
);
});
Expand Down
21 changes: 12 additions & 9 deletions @libs/indicators/MIN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,31 @@ export const useMIN = (source: Series, period: number) => {
// 单调队列: 保存当前窗口期内,比最新的元素小的元素的索引
const queue = useRef<number[]>([]);
useEffect(() => {
const i = source.length - 2;
if (i < 0) return;
const previousIndex = source.previousIndex;
if (previousIndex < 0) return;
// 从栈顶开始,移除所有大于当前值的元素
while (
queue.current.length > 0 &&
source[queue.current[queue.current.length - 1]] >= source[i]
source[queue.current[queue.current.length - 1]] >= source.previousValue
) {
queue.current.pop();
}
// 将当前值入栈
queue.current.push(i);
queue.current.push(previousIndex);
// 移除超出窗口期的元素 (通常一次只会移除一个)
while (queue.current.length > 0 && queue.current[0] <= i - period) {
while (
queue.current.length > 0 &&
queue.current[0] <= previousIndex - period
) {
queue.current.shift();
}
}, [source.length]);
useEffect(() => {
const i = source.length - 1;
if (i < 0) return;
const currentIndex = source.currentIndex;
if (currentIndex < 0) return;
// 队首元素即为当前窗口期内的最小值
MIN[i] = Math.min(
source[source.length - 1],
MIN[currentIndex] = Math.min(
source.currentValue,
source[queue.current[0]] || Infinity
);
});
Expand Down
6 changes: 3 additions & 3 deletions @libs/indicators/RANGE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ export const useRANGE = (source: Series, period: number) => {
chart: "new",
});
useEffect(() => {
const i = source.length - 1;
if (i < 0) return;
Range[i] = max[i] - min[i];
const currentIndex = source.currentIndex;
if (currentIndex < 0) return;
Range[currentIndex] = max.currentValue - min.currentValue;
});
return Range;
};
60 changes: 32 additions & 28 deletions @libs/indicators/SAR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,72 +22,76 @@ export const useSAR = (
const direction = useSeries("direction", high); // 1 for upward, -1 for downward, 0 for unknown

useEffect(() => {
const i = high.length - 1;
const i = high.currentIndex;
if (i < 0) return;

if (i === 0) {
MAX[i] = high[i];
MIN[i] = low[i];
MAX[i] = high.currentValue;
MIN[i] = low.currentValue;
AF[i] = start;
U[i] = high[i];
D[i] = low[i];
U[i] = high.currentValue;
D[i] = low.currentValue;
direction[i] = 0;
return;
}
// U[i] = U[i - 1];
// D[i] = D[i - 1];

if (direction[i - 1] !== 1) {
if (direction.previousValue !== 1) {
// 按下行处理

// 检查是否向上反转
if (high[i] >= U[i - 1]) {
if (high.currentValue >= U.previousValue) {
direction[i] = 1;
MAX[i] = high[i];
MIN[i] = low[i];
MAX[i] = high.currentValue;
MIN[i] = low.currentValue;
U[i] = NaN; // MAX[i];
D[i] = MIN[i - 1]; // 从上一个区间的最小值开始
D[i] = MIN.previousValue; // 从上一个区间的最小值开始
AF[i] = start;
return;
}
direction[i] = direction[i - 1];
direction[i] = direction.previousValue;
// 检查是否创新低
if (low[i] < MIN[i - 1]) {
AF[i] = Math.min(max, AF[i - 1] + increment);
if (low.currentValue < MIN.previousValue) {
AF[i] = Math.min(max, AF.previousValue + increment);
} else {
AF[i] = AF[i - 1];
AF[i] = AF.previousValue;
}
// 维护区间极值
MAX[i] = Math.max(MAX[i - 1], high[i]);
MIN[i] = Math.min(MIN[i - 1], low[i]);
MAX[i] = Math.max(MAX.previousValue, high.currentValue);
MIN[i] = Math.min(MIN.previousValue, low.currentValue);

U[i] = U[i - 1] + AF[i] * (MIN[i - 1] - U[i - 1]);
U[i] =
U.previousValue +
AF.currentValue * (MIN.previousValue - U.previousValue);
D[i] = NaN; // MIN[i];
} else {
// 按上行处理

// 检查是否向下反转
if (low[i] <= D[i - 1]) {
if (low.currentValue <= D.previousValue) {
direction[i] = -1;
MAX[i] = high[i];
MIN[i] = low[i];
MAX[i] = high.currentValue;
MIN[i] = low.currentValue;
AF[i] = start;
U[i] = MAX[i - 1]; // 从上一个区间的最大值开始
U[i] = MAX.previousValue; // 从上一个区间的最大值开始
D[i] = NaN; // MIN[i];
return;
}
direction[i] = direction[i - 1];
direction[i] = direction.previousValue;
// 检查是否创新高
if (high[i] < MAX[i - 1]) {
AF[i] = Math.min(max, AF[i - 1] + increment);
if (high.currentValue < MAX.previousValue) {
AF[i] = Math.min(max, AF.previousValue + increment);
} else {
AF[i] = AF[i - 1];
AF[i] = AF.previousValue;
}
// 维护区间极值
MAX[i] = Math.max(MAX[i - 1], high[i]);
MIN[i] = Math.min(MIN[i - 1], low[i]);
MAX[i] = Math.max(MAX.previousValue, high.currentValue);
MIN[i] = Math.min(MIN.previousValue, low.currentValue);
U[i] = NaN; //MAX[i];
D[i] = D[i - 1] + AF[i] * (MAX[i - 1] - D[i - 1]);
D[i] =
D.previousValue +
AF.currentValue * (MAX.previousValue - D.previousValue);
}
});
return { U, D, direction, MAX, MIN, AF };
Expand Down
14 changes: 7 additions & 7 deletions @libs/indicators/TD.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ export const useTD = (source: Series) => {
});

useEffect(() => {
const i = source.length - 1;
if (i < 0) return;
TD[i] = 0;
if (source[i] > source[i - 4]) {
TD[i] = Math.max(0, TD[i - 1] ?? 0) + 1;
const currentIndex = source.currentIndex;
if (currentIndex < 0) return;
TD[currentIndex] = 0;
if (source.currentValue > source[currentIndex - 4]) {
TD[currentIndex] = Math.max(0, TD.previousValue ?? 0) + 1;
}
if (source[i] < source[i - 4]) {
TD[i] = Math.min(0, TD[i - 1] ?? 0) - 1;
if (source.currentValue < source[currentIndex - 4]) {
TD[currentIndex] = Math.min(0, TD.previousValue ?? 0) - 1;
}
});

Expand Down
12 changes: 6 additions & 6 deletions @libs/indicators/ZIGZAG.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const useZigZag = (high: Series, low: Series, period: number) => {
useEffect(() => {
for (
let i = Math.max(0, lastLowPeak.length) - 1;
i < high.length - 1;
i < high.currentIndex;
i++
) {
if (i <= 0) {
Expand Down Expand Up @@ -100,11 +100,11 @@ export const useZigZag = (high: Series, low: Series, period: number) => {
}
}
if (high.length >= 1) {
lastHighPeak[high.length - 1] = NaN;
lastLowPeak[high.length - 1] = NaN;
currentZigzagValue[high.length - 1] = NaN;
lastZigzagValue[high.length - 1] = NaN;
secondLastZigzagValue[high.length - 1] = NaN;
lastHighPeak[high.currentIndex] = NaN;
lastLowPeak[high.currentIndex] = NaN;
currentZigzagValue[high.currentIndex] = NaN;
lastZigzagValue[high.currentIndex] = NaN;
secondLastZigzagValue[high.currentIndex] = NaN;
}
});

Expand Down
2 changes: 1 addition & 1 deletion @libs/utils/useSeriesMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const useSeriesMap = (
) => {
const series = useSeries(name, parent, tags);
useEffect(() => {
const i = parent.length - 1;
const i = parent.currentIndex;
if (i < 0) return;
series[i] = fn(i, series);
});
Expand Down
18 changes: 9 additions & 9 deletions @libs/utils/useThrottle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ export const useThrottle = (series: Series, period: number) => {
const ret = useSeries(`THROTTLE(${series.name},${period})`, series, {});
const openIdxRef = useRef(0);
useEffect(() => {
const i = series.length - 1;
if (i < 0) return;
if (i < openIdxRef.current) {
ret[i] = NaN;
const currentIndex = series.currentIndex;
if (currentIndex < 0) return;
if (currentIndex < openIdxRef.current) {
ret[currentIndex] = NaN;
return;
}
if (series[i - 1]) {
openIdxRef.current = i + period;
ret[i - 1] = series[i - 1];
ret[i] = NaN;
if (series[currentIndex - 1]) {
openIdxRef.current = currentIndex + period;
ret[currentIndex - 1] = series.previousValue;
ret[currentIndex] = NaN;
return;
}
ret[i] = series[i];
ret[currentIndex] = series.currentValue;
});
return ret;
};
16 changes: 8 additions & 8 deletions @libs/utils/useTopK.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,26 @@
export const useTopK = (series: Series, k: number, period: number) => {
const indexes = useRef<number[]>([]);
const ret = useSeries(`TOP_K(${series.name},${k},${period})`, series, {});
const i = series.length - 1;
const currentIndex = series.currentIndex;
useEffect(() => {
if (i < 0) return;
if (currentIndex < 0) return;
let isChanged = false;
// remove expired indexes
if (indexes.current[0] <= i - period) {
if (indexes.current[0] <= currentIndex - period) {
indexes.current.shift();
isChanged = true;
}
if (series[i - 1]) {
indexes.current.push(i - 1);
if (series.previousValue) {
indexes.current.push(currentIndex - 1);
isChanged = true;
}

if (isChanged) {
const sorted = [...indexes.current].sort((a, b) => series[b] - series[a]);
ret[i] = series[sorted[Math.min(k, sorted.length) - 1]];
ret[currentIndex] = series[sorted[Math.min(k, sorted.length) - 1]];
} else {
ret[i] = ret[i - 1] ?? NaN;
ret[currentIndex] = ret.previousValue ?? NaN;
}
}, [i]);
}, [currentIndex]);
return ret;
};
35 changes: 22 additions & 13 deletions @models/CCI-trending.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import {
*/
export default () => {
const { product_id, high, low, close } = useParamOHLC("SomeKey");
const idx = close.length - 2;

const cciFast = useCCI(high, low, close, 18);
const cciSlow = useCCI(high, low, close, 54);
Expand All @@ -48,42 +47,52 @@ export default () => {
accountInfo.account_id,
product_id
);
const stopLossPrice = useRef(close[idx] - 6 * atr108[idx]);
const stopLossPrice = useRef(close.previousValue - 6 * atr108.previousValue);

useEffect(() => {
if (idx < 108) return; // 确保ATR有足够的数据
if (close.previousIndex < 108) return; // 确保ATR有足够的数据

// 空头信号:当CCI快线进入正200以上,且下穿慢线时,建立空单。
if (cciFast[idx] > 200 && cciFast[idx] < cciSlow[idx]) {
if (
cciFast.previousValue > 200 &&
cciFast.previousValue < cciSlow.previousValue
) {
setTargetVolume(-1);
stopLossPrice.current = close[idx] + 6 * atr108[idx]; // 使用6倍ATR的值作为停损点位。
stopLossPrice.current = close.previousValue + 6 * atr108.previousValue; // 使用6倍ATR的值作为停损点位。
}

// 多头信号:当CCI快线进入负200以下,且上穿慢线时,建立多单。
if (cciFast[idx] < -200 && cciFast[idx] > cciSlow[idx]) {
if (
cciFast.previousValue < -200 &&
cciFast.previousValue > cciSlow.previousValue
) {
setTargetVolume(1);
stopLossPrice.current = close[idx] - 6 * atr108[idx]; // 使用6倍ATR的值作为停损点位。
stopLossPrice.current = close.previousValue - 6 * atr108.previousValue; // 使用6倍ATR的值作为停损点位。
}

// 多单平仓:当CCI快线进入正200以上,且下穿慢线时,平多单。
if (targetVolume > 0 && cciFast[idx] > 200 && cciFast[idx] < cciSlow[idx]) {
if (
targetVolume > 0 &&
cciFast.previousValue > 200 &&
cciFast.previousValue < cciSlow.previousValue
) {
setTargetVolume(0);
}
// 空单平仓:当CCI快线进入负200以下,且上穿慢线时,平空单。
if (
targetVolume < 0 &&
cciFast[idx] < -200 &&
cciFast[idx] > cciSlow[idx]
cciFast.previousValue < -200 &&
cciFast.previousValue > cciSlow.previousValue
) {
setTargetVolume(0);
}

// 停损条件
if (
(targetVolume > 0 && close[idx] < stopLossPrice.current) ||
(targetVolume < 0 && close[idx] > stopLossPrice.current)
(targetVolume > 0 && close.previousValue < stopLossPrice.current) ||
(targetVolume < 0 && close.previousValue > stopLossPrice.current)
) {
setTargetVolume(0);
}
}, [idx]);
}, [close.previousIndex]);
};
Loading

0 comments on commit bb3cafa

Please sign in to comment.