Skip to content

Commit 8561d31

Browse files
feat: increase WASM engine history count and localize chart crosshair time display
1 parent 9112923 commit 8561d31

9 files changed

Lines changed: 66 additions & 138 deletions

File tree

src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ function App() {
6262
} = useWasmEngine({
6363
tickInterval: 100,
6464
dataSource,
65-
historyCount: 1440,
65+
historyCount: 5000,
6666
});
6767

6868
// 切换完成条件

src/components/Dashboard/Chart/LightweightChart/hooks/useUnifiedChartSetup.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,18 @@ export function useUnifiedChartSetup({
195195
vertLines: { color: CHART_COLORS.GRID },
196196
horzLines: { color: CHART_COLORS.GRID },
197197
},
198+
localization: {
199+
// 覆盖十字线浮窗的时间显示,从 UTC 转为当地时间
200+
timeFormatter: (time: Time) => {
201+
const d = new Date((time as number) * 1000);
202+
const yyyy = d.getFullYear();
203+
const mm = String(d.getMonth() + 1).padStart(2, '0');
204+
const dd = String(d.getDate()).padStart(2, '0');
205+
const HH = String(d.getHours()).padStart(2, '0');
206+
const MM = String(d.getMinutes()).padStart(2, '0');
207+
return `${yyyy}-${mm}-${dd} ${HH}:${MM}`;
208+
},
209+
},
198210
rightPriceScale: {
199211
borderColor: CHART_COLORS.BORDER,
200212
scaleMargins: { top: 0.1, bottom: 0.1 },

src/components/TradePanelConnected.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function TradePanelConnected({
3737
} = useWasmEngine({
3838
tickInterval: 100,
3939
dataSource,
40-
historyCount: 1440,
40+
historyCount: 5000,
4141
});
4242

4343
return (

src/hooks/tradingEngine/wasmSingleton.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,7 @@ export async function initWasmEngine(): Promise<MarketEngineInstance> {
5656
const wasmExports = await wasm.default();
5757
wasmSingleton.wasmInstance = wasmExports;
5858

59-
// 调试:检查 memory 是否存在
60-
const hasMemory = wasmExports && 'memory' in wasmExports;
61-
console.log(`[Wasm] wasmExports.memory 存在: ${hasMemory}`);
62-
if (hasMemory) {
63-
const mem = (wasmExports as { memory: WebAssembly.Memory }).memory;
64-
console.log(
65-
`[Wasm] 初始内存: ${(mem.buffer.byteLength / 1024 / 1024).toFixed(
66-
2,
67-
)} MB`,
68-
);
69-
}
59+
7060
}
7161

7262
const wasmMod = wasm as unknown as WasmModule;

src/hooks/useBinanceMarket.ts

Lines changed: 3 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -468,28 +468,9 @@ export function useBinanceMarket(
468468
prevKlineVolumeRef.current = volume;
469469
currentKlineVolumeRef.current = volume;
470470

471-
// 详细日志:记录每次 K 线更新(减少日志频率,只在重要时刻记录)
472-
if (k.x || isNewKline || Math.abs(volumeDelta) > 0.0001) {
473-
console.log(`[Binance] 📊 K线更新:`, {
474-
time: new Date(k.t).toLocaleTimeString(),
475-
price: price.toFixed(2),
476-
volume: volume.toFixed(4),
477-
volumeDelta: volumeDelta.toFixed(4),
478-
isFinished: k.x,
479-
isNewKline,
480-
interval: k.i,
481-
});
482-
}
483471

484-
// 如果 K 线已完结,记录日志
485-
if (k.x) {
486-
console.log(
487-
`[Binance] ✅ K 线完结: 总成交量=${volume.toFixed(4)}, 周期=${
488-
k.i
489-
}`,
490-
);
491-
// K 线完结后,下一根 K 线开始时 prevKlineVolumeRef 会重置为 0
492-
}
472+
473+
// K 线完结后,下一根 K 线开始时 prevKlineVolumeRef 会重置为 0
493474

494475
// 立即更新 OrderBook(包含成交量)
495476
// 注意:WASM 引擎的 Candle::update 会累加成交量
@@ -518,18 +499,6 @@ export function useBinanceMarket(
518499

519500
orderBook.volume = volumeToPass;
520501

521-
// 🔍 成交量追踪日志:K线更新
522-
console.log(`[VOL追踪] 📊 K线更新 → setLatestData:`, {
523-
volume: volumeToPass,
524-
volumeType: k.x
525-
? '增量(完结)'
526-
: isNewKline
527-
? '增量(新K线)'
528-
: '增量',
529-
klineFinished: k.x,
530-
isNewKline,
531-
orderBookHasVolume: orderBook.volume !== undefined,
532-
});
533502

534503
setLatestData(orderBook);
535504
}
@@ -578,12 +547,6 @@ export function useBinanceMarket(
578547
// 注意:真实的成交量数据只在 K 线更新时传递
579548
orderBook.volume = 0;
580549

581-
// 🔍 成交量追踪日志:深度更新
582-
console.log(`[VOL追踪] 📦 深度更新 → setLatestData:`, {
583-
volume: 0,
584-
currentKlineVolume: currentKlineVolumeRef.current,
585-
note: '传递 0 避免累加,真实成交量在 K 线更新时传递',
586-
});
587550

588551
setLatestData(orderBook);
589552
}
@@ -614,14 +577,7 @@ export function useBinanceMarket(
614577
// 注意:真实的成交量数据只在 K 线更新时传递
615578
orderBook.volume = 0;
616579

617-
// 🔍 成交量追踪日志:定时更新(减少频率,每10次记录一次)
618-
if (Math.random() < 0.1) {
619-
console.log(`[VOL追踪] ⏰ 定时更新 → setLatestData:`, {
620-
volume: 0,
621-
currentKlineVolume: currentKlineVolumeRef.current,
622-
note: '传递 0 避免累加,真实成交量在 K 线更新时传递',
623-
});
624-
}
580+
625581

626582
setLatestData(orderBook);
627583
}

src/hooks/useMarketData.ts

Lines changed: 6 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -110,25 +110,11 @@ export function useMarketData(
110110
// ========== 数据源切换时,强制停止旧数据流 ==========
111111
useEffect(() => {
112112
if (prevSourceRef.current !== source) {
113-
console.log(
114-
`[useMarketData] 🔄 数据源切换: ${prevSourceRef.current} -> ${source}`,
115-
);
116-
117113
// 强制停止旧数据源
118114
if (prevSourceRef.current === 'mock') {
119-
console.log('[useMarketData] ⏹️ 停止 MOCK 数据源');
120-
// 多次调用 stop 确保完全停止
121-
mockData.stop();
122-
// 延迟再次停止,确保 Worker 完全清理
123-
setTimeout(() => {
124-
if (mockData.isRunning) {
125-
console.warn('[useMarketData] ⚠️ MOCK 仍在运行,再次停止');
126-
mockData.stop();
127-
}
128-
}, 200);
115+
mockData.terminate();
129116
}
130117
if (prevSourceRef.current === 'binance') {
131-
console.log('[useMarketData] ⏹️ 停止 Binance 数据源');
132118
binanceData.stop();
133119
}
134120

@@ -138,51 +124,13 @@ export function useMarketData(
138124

139125
// ========== 持续监控:确保只有一个数据源在运行 ==========
140126
useEffect(() => {
141-
// 如果当前是 binance 模式,确保 mock 完全停止
142-
if (source === 'binance') {
143-
if (mockData.isRunning) {
144-
console.warn(
145-
'[useMarketData] ⚠️ LIVE 模式下检测到 MOCK 数据仍在运行,强制停止',
146-
);
147-
console.warn(
148-
'[useMarketData] 🔍 当前数据源:',
149-
source,
150-
'MOCK运行状态:',
151-
mockData.isRunning,
152-
'Binance运行状态:',
153-
binanceData.isRunning,
154-
);
155-
mockData.stop();
156-
}
157-
// 额外检查:确保返回的是 Binance 数据
158-
if (mockData.latestData && binanceData.latestData) {
159-
console.warn(
160-
'[useMarketData] ⚠️ 检测到两个数据源都有数据,当前应使用 Binance 数据',
161-
);
162-
console.warn(
163-
'[useMarketData] 🔍 MOCK数据:',
164-
mockData.latestData,
165-
'Binance数据:',
166-
binanceData.latestData,
167-
);
168-
}
127+
if (source === 'binance' && mockData.isRunning) {
128+
mockData.terminate();
169129
}
170-
// 如果当前是 mock 模式,确保 binance 完全停止
171-
if (source === 'mock') {
172-
if (binanceData.isRunning) {
173-
console.warn(
174-
'[useMarketData] ⚠️ MOCK 模式下检测到 Binance 数据仍在运行,强制停止',
175-
);
176-
binanceData.stop();
177-
}
130+
if (source === 'mock' && binanceData.isRunning) {
131+
binanceData.stop();
178132
}
179-
}, [
180-
source,
181-
mockData.isRunning,
182-
binanceData.isRunning,
183-
mockData,
184-
binanceData,
185-
]);
133+
}, [source, mockData.isRunning, binanceData.isRunning, mockData, binanceData]);
186134

187135
// ========== 根据数据源选择返回值 ==========
188136
const result = useMemo((): UseMarketDataReturn => {

src/hooks/useMockMarket.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,8 @@ export function useMockMarket(interval: number = 100) {
4848
if (type === 'DATA') {
4949
setLatestData(event.data.payload);
5050
} else if (type === 'HISTORY') {
51-
const t0 = performance.now();
52-
const candles = event.data.payload.candles;
53-
console.log(`[Perf] 📦 Worker 历史数据到达: ${candles.length} 根`);
54-
setHistoryCandles(candles);
51+
setHistoryCandles(event.data.payload.candles);
5552
setHistoryLoading(false);
56-
console.log(
57-
`[Perf] ✅ React state 更新: ${(performance.now() - t0).toFixed(
58-
0,
59-
)}ms`,
60-
);
6153
}
6254
};
6355

@@ -98,6 +90,18 @@ export function useMockMarket(interval: number = 100) {
9890
}
9991
}, []);
10092

93+
/**
94+
* 完全终止 Worker(切换数据源时调用)
95+
*/
96+
const terminate = useCallback(() => {
97+
if (workerRef.current) {
98+
workerRef.current.terminate();
99+
workerRef.current = null;
100+
setIsRunning(false);
101+
setLatestData(null);
102+
}
103+
}, []);
104+
101105
/**
102106
* 请求历史 K 线数据
103107
* @param timeframeSeconds - 时间周期 (秒),默认 1m = 60
@@ -108,7 +112,6 @@ export function useMockMarket(interval: number = 100) {
108112
timeframeSeconds: number = TIMEFRAME_1S_SECONDS,
109113
count: number = DEFAULT_HISTORY_COUNT,
110114
) => {
111-
console.log(`[Perf] 📤 请求历史数据: ${count} 根 K 线...`);
112115
const worker = initWorker();
113116
setHistoryLoading(true);
114117
const message: WorkerHistoryRequestMessage = {
@@ -137,6 +140,8 @@ export function useMockMarket(interval: number = 100) {
137140
isRunning,
138141
start,
139142
stop,
143+
/** 完全终止 Worker(切换数据源时调用) */
144+
terminate,
140145
/** 历史 K 线数据 */
141146
historyCandles,
142147
/** 历史数据加载中 */

src/hooks/useWasmEngine.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,7 @@ export function useWasmEngine(
222222
// ========== 数据源切换时重置状态 ==========
223223
useEffect(() => {
224224
if (prevDataSourceRef.current !== dataSource) {
225-
console.log(
226-
`[useWasmEngine] 数据源切换: ${prevDataSourceRef.current} -> ${dataSource}`,
227-
);
225+
228226

229227
// 清空 Rust 引擎内部历史,避免不同数据源之间的价格/成交量互相污染
230228
if (engineAlive.current && engineRef.current) {
@@ -255,15 +253,10 @@ export function useWasmEngine(
255253
// ========== Wasm 初始化 ==========
256254
useEffect(() => {
257255
let aborted = false;
258-
const t0 = performance.now();
259256

260257
const init = async () => {
261258
try {
262-
console.log('[Perf] ⏱️ 开始 WASM 初始化...');
263259
const engine = await initWasmEngine();
264-
console.log(
265-
`[Perf] ✅ WASM 初始化完成: ${(performance.now() - t0).toFixed(0)}ms`,
266-
);
267260

268261
if (aborted) return;
269262

@@ -294,7 +287,7 @@ export function useWasmEngine(
294287
aborted = true;
295288
engineAlive.current = false;
296289
engineRef.current = null;
297-
console.log('[useWasmEngine] 组件卸载,引擎保持活跃');
290+
298291
};
299292
}, []);
300293

@@ -515,7 +508,7 @@ export function useWasmEngine(
515508
try {
516509
const success = engineRef.current.set_timeframe(timeframe);
517510
if (success) {
518-
console.log(`[useWasmEngine] 时间周期已切换为 ${timeframe}`);
511+
519512

520513
// 立即获取新周期的 K 线数据
521514
try {

src/types/wasm.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,30 @@ export interface WasmMarketEngine {
427427
*/
428428
get_candle_count(timeframe: WasmTimeframe): number;
429429

430+
// ========== 历史数据加载方法 ==========
431+
432+
/**
433+
* 加载历史 K 线数据到指定时间周期
434+
*
435+
* @param timeframe - 时间周期字符串
436+
* @param candles - 历史 K 线数据数组
437+
* @returns 加载的 K 线数量
438+
*/
439+
load_history_candles(
440+
timeframe: WasmTimeframe,
441+
candles: import('./index').HistoryCandle[],
442+
): number;
443+
444+
/**
445+
* 加载 1s K 线并自动聚合到所有高周期 (1m/5m/15m/1H/4H/1D)
446+
*
447+
* @param candles - 1 秒粒度的历史 K 线数据
448+
* @returns 各周期名称及对应 K 线数量的数组
449+
*/
450+
load_history_1s_and_aggregate(
451+
candles: import('./index').HistoryCandle[],
452+
): [string, number][];
453+
430454
// ========== 模拟交易方法 ==========
431455

432456
/**

0 commit comments

Comments
 (0)