refactor: remove mock trading functionality from backend and frontend

Removes all mock price simulation features:
- Delete MockPriceManager from backend/data/
- Remove mock_mode, enable_mock, is_mock_mode flags from services
- Remove mock CLI options and config
- Remove mock mode UI components and state from frontend
- Update tests to remove mock references

Now system supports only live and backtest modes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-26 13:38:51 +08:00
parent fecf8a9466
commit 9bcc4221a4
21 changed files with 56 additions and 709 deletions

View File

@@ -291,7 +291,6 @@ export default function LiveTradingApp() {
financial_datasets: 'FINANCIAL DATASETS',
local_csv: 'CSV',
polygon: 'POLYGON',
mock: 'MOCK',
backtest: 'BACKTEST',
}), []);
@@ -415,7 +414,6 @@ export default function LiveTradingApp() {
pollIntervalDraft={runtimeControls.pollIntervalDraft}
startDateDraft={runtimeControls.startDateDraft}
endDateDraft={runtimeControls.endDateDraft}
enableMockDraft={runtimeControls.enableMockDraft}
watchlistDraftSymbols={runtimeControls.watchlistDraftSymbols}
watchlistInputValue={runtimeControls.watchlistInputValue}
watchlistSuggestions={runtimeControls.watchlistSuggestions}
@@ -432,7 +430,6 @@ export default function LiveTradingApp() {
onPollIntervalChange={runtimeControls.setPollIntervalDraft}
onStartDateChange={runtimeControls.setStartDateDraft}
onEndDateChange={runtimeControls.setEndDateDraft}
onEnableMockChange={runtimeControls.setEnableMockDraft}
onWatchlistInputChange={runtimeControls.handleWatchlistInputChange}
onWatchlistInputKeyDown={runtimeControls.handleWatchlistInputKeyDown}
onWatchlistAdd={runtimeControls.handleWatchlistAdd}

View File

@@ -72,7 +72,6 @@ export default function AppShell({
pollIntervalDraft,
startDateDraft,
endDateDraft,
enableMockDraft,
watchlistDraftSymbols,
watchlistInputValue,
watchlistSuggestions,
@@ -89,7 +88,6 @@ export default function AppShell({
onPollIntervalChange,
onStartDateChange,
onEndDateChange,
onEnableMockChange,
onWatchlistInputChange,
onWatchlistInputKeyDown,
onWatchlistAdd,
@@ -186,44 +184,6 @@ export default function AppShell({
<Header />
<div className="header-right" style={{ display: 'flex', alignItems: 'center', gap: 24, marginLeft: 'auto', flexWrap: 'wrap', minWidth: 0 }}>
{/* Mock Mode Indicator */}
{virtualTime && (
<div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '4px 10px', borderRadius: 4, background: '#FF9800', border: '1px solid #FFB74D' }}>
<span style={{ fontSize: '14px' }}></span>
<span style={{ fontSize: '11px', fontWeight: 600, color: '#FFFFFF', fontFamily: '"Courier New", monospace', letterSpacing: '0.5px' }}>
模拟模式
</span>
</div>
)}
{/* Clock Display (only in Mock mode) */}
{virtualTime && (
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 2, padding: '4px 12px', borderRadius: 4, background: '#1A237E', border: '1px solid #3F51B5' }}>
<span style={{ fontSize: '11px', color: '#999', fontFamily: '"Courier New", monospace', textTransform: 'uppercase', letterSpacing: '0.5px' }}>虚拟时间</span>
<span style={{ fontSize: '14px', fontWeight: 700, color: '#FFFFFF', fontFamily: '"Courier New", monospace', letterSpacing: '1px' }}>
{now.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false })}
</span>
<span style={{ fontSize: '10px', color: '#999', fontFamily: '"Courier New", monospace' }}>
{now.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })}
</span>
</div>
{/* Fast Forward Button (only in Mock mode) */}
<button
onClick={() => {
if (agentRequests?.clientRef?.current) {
agentRequests.clientRef.current.send({ type: 'fast_forward_time', minutes: 30 });
}
}}
style={{ padding: '6px 12px', borderRadius: 4, background: '#3F51B5', border: '1px solid #5C6BC0', color: '#FFFFFF', fontSize: '12px', fontFamily: '"Courier New", monospace', fontWeight: 600, cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 4, textTransform: 'uppercase', letterSpacing: '0.5px' }}
title="快进30分钟 (Mock模式)"
>
+30min
</button>
</div>
)}
{/* Unified Status Indicator */}
<div className="header-status-inline">
<span className={`status-dot ${isConnected ? (isUpdating ? 'updating' : 'live') : 'offline'}`} />
@@ -320,7 +280,6 @@ export default function AppShell({
pollInterval={pollIntervalDraft}
startDate={startDateDraft}
endDate={endDateDraft}
enableMock={enableMockDraft}
watchlistSymbols={watchlistDraftSymbols}
watchlistInputValue={watchlistInputValue}
watchlistSuggestions={watchlistSuggestions}
@@ -339,7 +298,6 @@ export default function AppShell({
onPollIntervalChange={onPollIntervalChange}
onStartDateChange={onStartDateChange}
onEndDateChange={onEndDateChange}
onEnableMockChange={onEnableMockChange}
onWatchlistInputChange={onWatchlistInputChange}
onWatchlistInputKeyDown={onWatchlistInputKeyDown}
onWatchlistAdd={onWatchlistAdd}

View File

@@ -5,10 +5,10 @@ import { formatNumber, formatFullNumber } from '../utils/formatters';
/**
* Helper function to get the start time of the most recent trading session
* Trading session: 22:30 - next day 05:00
* @param {Date|null} virtualTime - Virtual time from server (for mock mode), or null to use real time
* @param {Date|null} virtualTime - Virtual time from server, or null to use real time
*/
function getRecentTradingSessionStart(virtualTime = null) {
// Use virtual time if provided (for mock mode), otherwise use real time
// Use virtual time if provided, otherwise use real time
let now;
if (virtualTime) {
// Ensure virtualTime is a valid Date object

View File

@@ -30,7 +30,6 @@ export default function RuntimeSettingsPanel({
pollInterval,
startDate,
endDate,
enableMock,
watchlistSymbols,
watchlistInputValue,
watchlistSuggestions,
@@ -49,7 +48,6 @@ export default function RuntimeSettingsPanel({
onPollIntervalChange,
onStartDateChange,
onEndDateChange,
onEnableMockChange,
onWatchlistInputChange,
onWatchlistInputKeyDown,
onWatchlistAdd,
@@ -580,21 +578,6 @@ export default function RuntimeSettingsPanel({
}}
/>
</label>
<label style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 2 }}>
<input
type="checkbox"
checked={enableMock}
onChange={(e) => onEnableMockChange(e.target.checked)}
style={{
width: 16,
height: 16,
accentColor: '#0D47A1',
cursor: 'pointer'
}}
/>
<span style={{ fontSize: '11px', color: '#111111', fontWeight: 700 }}>启用模拟数据 (Mock)</span>
</label>
</div>
)}

View File

@@ -63,8 +63,6 @@ export function useRuntimeControls({ clientRef, currentTickers, addSystemMessage
setStartDateDraft,
endDateDraft,
setEndDateDraft,
enableMockDraft,
setEnableMockDraft,
runtimeConfigFeedback,
setRuntimeConfigFeedback,
isRuntimeConfigSaving,
@@ -400,7 +398,6 @@ export function useRuntimeControls({ clientRef, currentTickers, addSystemMessage
poll_interval: Number(pollIntervalDraft) || Number(DEFAULT_POLL_INTERVAL),
start_date: startDateDraft || null,
end_date: endDateDraft || null,
enable_mock: Boolean(enableMockDraft)
});
setIsRuntimeConfigSaving(false);
@@ -424,7 +421,6 @@ export function useRuntimeControls({ clientRef, currentTickers, addSystemMessage
addSystemMessage,
clientRef,
enableMemoryDraft,
enableMockDraft,
endDateDraft,
initialCashDraft,
intervalMinutesDraft,
@@ -463,11 +459,9 @@ export function useRuntimeControls({ clientRef, currentTickers, addSystemMessage
setPollIntervalDraft(DEFAULT_POLL_INTERVAL);
setStartDateDraft("");
setEndDateDraft("");
setEnableMockDraft(false);
setRuntimeConfigFeedback(null);
}, [
setEnableMemoryDraft,
setEnableMockDraft,
setEndDateDraft,
setInitialCashDraft,
setIntervalMinutesDraft,
@@ -542,7 +536,6 @@ export function useRuntimeControls({ clientRef, currentTickers, addSystemMessage
pollIntervalDraft,
startDateDraft,
endDateDraft,
enableMockDraft,
runtimeConfigFeedback,
isRuntimeConfigSaving,
isWatchlistSavingRef,
@@ -582,7 +575,6 @@ export function useRuntimeControls({ clientRef, currentTickers, addSystemMessage
setPollIntervalDraft,
setStartDateDraft,
setEndDateDraft,
setEnableMockDraft,
setIsWatchlistSaving,
setIsRuntimeConfigSaving
};

View File

@@ -225,18 +225,9 @@ export function useWebSocketConnection({
setTickers((prevTickers) => buildTickersFromSymbols(state.tickers, prevTickers));
}
const isMockMode = state.is_mock_mode === true;
if (state.market_status) {
setMarketStatus(state.market_status);
if (isMockMode && state.market_status.current_time) {
try {
setVirtualTime(new Date(state.market_status.current_time));
} catch (error) {
console.error('Error parsing virtual time from market_status:', error);
}
} else {
setVirtualTime(null);
}
setVirtualTime(null);
}
if (state.trading_days_total) {
@@ -783,18 +774,13 @@ export function useWebSocketConnection({
if (e.beijing_time_str) {
const statusEmoji = { market_open: '📊', off_market: '⏸️', non_trading_day: '📅', trade_execution: '💼' };
const emoji = statusEmoji[e.status] || '⏰';
const isMockMode = e.is_mock_mode === true;
let logMessage = `${emoji} ${isMockMode ? '虚拟时间' : '时间'}: ${e.beijing_time_str} | 状态: ${e.status}`;
let logMessage = `${emoji} 时间: ${e.beijing_time_str} | 状态: ${e.status}`;
if (e.hours_to_open !== undefined) logMessage += ` | 距离开盘: ${e.hours_to_open}小时`;
if (e.hours_to_trade !== undefined) logMessage += ` | 距离交易: ${e.hours_to_trade}小时`;
if (e.trading_date) logMessage += ` | 交易日: ${e.trading_date}`;
console.log(logMessage);
if (isMockMode && e.beijing_time) {
try { setVirtualTime(new Date(e.beijing_time)); } catch (error) { console.error('Error parsing virtual time:', error); }
} else {
setVirtualTime(null);
}
setVirtualTime(null);
}
if (e.market_status) setMarketStatus(e.market_status);
},

View File

@@ -75,7 +75,6 @@ export const useRuntimeStore = create((set) => ({
pollIntervalDraft: '10',
startDateDraft: '',
endDateDraft: '',
enableMockDraft: false,
setLaunchModeDraft: (launchModeDraft) => set((state) => ({ launchModeDraft: resolveValue(launchModeDraft, state.launchModeDraft) })),
setRestoreRunIdDraft: (restoreRunIdDraft) => set((state) => ({ restoreRunIdDraft: resolveValue(restoreRunIdDraft, state.restoreRunIdDraft) })),
setRuntimeHistoryRuns: (runtimeHistoryRuns) => set((state) => ({ runtimeHistoryRuns: resolveValue(runtimeHistoryRuns, state.runtimeHistoryRuns) })),
@@ -90,7 +89,6 @@ export const useRuntimeStore = create((set) => ({
setPollIntervalDraft: (pollIntervalDraft) => set((state) => ({ pollIntervalDraft: resolveValue(pollIntervalDraft, state.pollIntervalDraft) })),
setStartDateDraft: (startDateDraft) => set((state) => ({ startDateDraft: resolveValue(startDateDraft, state.startDateDraft) })),
setEndDateDraft: (endDateDraft) => set((state) => ({ endDateDraft: resolveValue(endDateDraft, state.endDateDraft) })),
setEnableMockDraft: (enableMockDraft) => set((state) => ({ enableMockDraft: resolveValue(enableMockDraft, state.enableMockDraft) })),
// Runtime config feedback
runtimeConfigFeedback: null,