Files
goldenChart/frontend/src/components/virtual/VirtualGridUnifiedHeader.tsx
T
2026-06-01 01:35:31 +09:00

164 lines
5.4 KiB
TypeScript

import React from 'react';
import type { StrategyDto } from '../../utils/backendApi';
import type { VirtualSessionConfig, VirtualCardViewMode } from '../../utils/virtualTradingStorage';
import type { VirtualCardDisplayMode } from './VirtualTargetCard';
import VirtualGridLayoutPicker from './VirtualGridLayoutPicker';
import type { TradeNotificationGridPresetId } from '../../utils/tradeNotificationGridPresets';
interface SessionProps {
session: Pick<VirtualSessionConfig, 'globalStrategyId' | 'executionType' | 'positionMode' | 'running'>;
strategies: StrategyDto[];
onStrategyChange: (strategyId: number | null) => void;
onExecutionTypeChange: (type: VirtualSessionConfig['executionType']) => void;
onPositionModeChange: (mode: VirtualSessionConfig['positionMode']) => void;
onStart: () => void;
onStop: () => void;
paperAutoTradeEnabled?: boolean;
onPaperAutoTradeEnabled?: (enabled: boolean) => void;
paperTradingEnabled?: boolean;
}
interface ViewProps {
session: Pick<VirtualSessionConfig, 'running'>;
viewMode: VirtualCardViewMode;
onViewModeChange: (mode: VirtualCardViewMode) => void;
globalDisplayMode?: VirtualCardDisplayMode;
onGlobalDisplayModeChange?: (mode: VirtualCardDisplayMode) => void;
showSignalChartToggle?: boolean;
gridPreset?: TradeNotificationGridPresetId;
onGridPresetChange?: (preset: TradeNotificationGridPresetId) => void;
showGridLayoutPicker?: boolean;
}
export const VirtualSessionHeaderControls: React.FC<SessionProps> = ({
session,
strategies,
onStrategyChange,
onExecutionTypeChange,
onPositionModeChange,
onStart,
onStop,
paperAutoTradeEnabled = false,
onPaperAutoTradeEnabled,
paperTradingEnabled = true,
}) => (
<div className="vtd-header-session vtd-header-session--compact">
<select
className="vtd-header-select vtd-header-select--strategy"
aria-label="투자전략"
value={session.globalStrategyId ?? ''}
onChange={e => {
const v = e.target.value;
onStrategyChange(v ? Number(v) : null);
}}
>
<option value="">전략 선택</option>
{strategies.map(s => (
<option key={s.id} value={s.id}>{s.name}</option>
))}
</select>
<select
className="vtd-header-select vtd-header-select--narrow"
aria-label="실행방식"
value={session.executionType}
onChange={e => onExecutionTypeChange(e.target.value as VirtualSessionConfig['executionType'])}
>
<option value="CANDLE_CLOSE"> 마감 직후</option>
<option value="REALTIME_TICK">실시간 </option>
</select>
<select
className="vtd-header-select vtd-header-select--narrow"
aria-label="시그널 모드"
value={session.positionMode}
onChange={e => onPositionModeChange(e.target.value as VirtualSessionConfig['positionMode'])}
>
<option value="LONG_ONLY">보유 자산 기준</option>
<option value="SIGNAL_ONLY">순수 지표 기준</option>
</select>
<select
className="vtd-header-select vtd-header-select--narrow"
aria-label="자동매매"
title={
!paperTradingEnabled
? '설정 › 가상투자에서 가상매매를 활성화하세요'
: undefined
}
value={paperAutoTradeEnabled ? 'on' : 'off'}
disabled={!paperTradingEnabled || !onPaperAutoTradeEnabled}
onChange={e => onPaperAutoTradeEnabled?.(e.target.value === 'on')}
>
<option value="off">자동매매 OFF</option>
<option value="on">자동매매 ON</option>
</select>
<div className="vtd-session-actions vtd-session-actions--compact">
<button
type="button"
className="bps-btn vtd-session-btn vtd-session-btn--start"
disabled={session.running}
onClick={onStart}
title="가상투자 시작"
>
시작
</button>
<button
type="button"
className="bps-btn bps-btn--danger vtd-session-btn"
disabled={!session.running}
onClick={onStop}
title="가상투자 종료"
>
종료
</button>
</div>
</div>
);
export const VirtualViewHeaderControls: React.FC<ViewProps> = ({
session,
viewMode,
onViewModeChange,
globalDisplayMode = 'signal',
onGlobalDisplayModeChange,
showSignalChartToggle = true,
gridPreset = '2x2',
onGridPresetChange,
showGridLayoutPicker = true,
}) => (
<div className="vtd-header-view vtd-header-view--compact">
{showGridLayoutPicker && onGridPresetChange && (
<VirtualGridLayoutPicker
value={gridPreset}
onChange={onGridPresetChange}
disabled={!showSignalChartToggle}
/>
)}
{showSignalChartToggle && onGlobalDisplayModeChange && (
<select
className="vtd-header-select vtd-header-select--narrow"
aria-label="신호 또는 차트"
value={globalDisplayMode}
onChange={e => onGlobalDisplayModeChange(e.target.value as VirtualCardDisplayMode)}
>
<option value="signal">신호</option>
<option value="chart">차트</option>
</select>
)}
<select
className="vtd-header-select vtd-header-select--narrow"
aria-label="카드 표시 방식"
value={viewMode}
onChange={e => onViewModeChange(e.target.value as VirtualCardViewMode)}
>
<option value="summary">요약표시</option>
<option value="detail">상세표시</option>
</select>
{session.running && (
<span className="vtd-grid-live" title="3초마다 갱신">실시간</span>
)}
</div>
);