가상투자 설정 수정
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
loadStrategies,
|
||||
loadLiveStrategySettings,
|
||||
saveLiveStrategySettings,
|
||||
type LiveStrategySettingsDto,
|
||||
type PaperSummaryDto,
|
||||
type StrategyDto,
|
||||
} from '../../utils/backendApi';
|
||||
import { loadVirtualSession } from '../../utils/virtualTradingStorage';
|
||||
import { fmtKrw } from '../TradeOrderPanel';
|
||||
import PaperSplitPanel from './PaperSplitPanel';
|
||||
|
||||
@@ -25,12 +25,22 @@ const PaperLeftStrategyTab: React.FC<Props> = ({
|
||||
}) => {
|
||||
const [strategies, setStrategies] = useState<StrategyDto[]>([]);
|
||||
const [settings, setSettings] = useState<LiveStrategySettingsDto | null>(null);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [virtualRunning, setVirtualRunning] = useState(() => loadVirtualSession().running);
|
||||
|
||||
useEffect(() => {
|
||||
loadStrategies().then(setStrategies).catch(() => setStrategies([]));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const refreshVirtual = () => setVirtualRunning(loadVirtualSession().running);
|
||||
window.addEventListener('gc_virtual_session_changed', refreshVirtual);
|
||||
window.addEventListener('storage', refreshVirtual);
|
||||
return () => {
|
||||
window.removeEventListener('gc_virtual_session_changed', refreshVirtual);
|
||||
window.removeEventListener('storage', refreshVirtual);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
loadLiveStrategySettings(market)
|
||||
@@ -47,26 +57,10 @@ const PaperLeftStrategyTab: React.FC<Props> = ({
|
||||
}
|
||||
});
|
||||
return () => { cancelled = true; };
|
||||
}, [market]);
|
||||
|
||||
const persist = useCallback(async (patch: Partial<LiveStrategySettingsDto>) => {
|
||||
if (!settings) return;
|
||||
const next = { ...settings, ...patch, market };
|
||||
const prev = settings;
|
||||
setSettings(next);
|
||||
setSaving(true);
|
||||
try {
|
||||
const saved = await saveLiveStrategySettings(next);
|
||||
if (saved) setSettings(saved);
|
||||
else setSettings(prev);
|
||||
} catch {
|
||||
setSettings(prev);
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
}, [settings, market]);
|
||||
}, [market, virtualRunning]);
|
||||
|
||||
const selected = strategies.find(s => s.id === settings?.strategyId);
|
||||
const execLabel = settings?.executionType === 'REALTIME_TICK' ? '실시간 틱 (3초)' : '봉 마감 직후';
|
||||
|
||||
const top = (
|
||||
<>
|
||||
@@ -79,55 +73,20 @@ const PaperLeftStrategyTab: React.FC<Props> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className="ptd-left-section">
|
||||
<label className="ptd-left-row">
|
||||
<span>전략 체크</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={settings?.isLiveCheck ?? false}
|
||||
disabled={saving}
|
||||
onChange={e => void persist({ isLiveCheck: e.target.checked })}
|
||||
/>
|
||||
</label>
|
||||
<label className="ptd-left-field">
|
||||
<span>전략 선택</span>
|
||||
<select
|
||||
className="ptd-left-select"
|
||||
value={settings?.strategyId ?? ''}
|
||||
disabled={saving}
|
||||
onChange={e => {
|
||||
const v = e.target.value;
|
||||
void persist({ strategyId: v ? Number(v) : null });
|
||||
}}
|
||||
>
|
||||
<option value="">— 선택 —</option>
|
||||
{strategies.map(s => (
|
||||
<option key={s.id} value={s.id}>{s.name}</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
{selected && (
|
||||
<p className="ptd-left-hint">
|
||||
실시간 전략·체크 대상 종목은 <strong>가상투자</strong> 화면에서 설정합니다.
|
||||
{virtualRunning ? ' (세션 실행 중)' : ''}
|
||||
</p>
|
||||
{settings?.isLiveCheck && selected && (
|
||||
<p className="ptd-left-hint">
|
||||
적용: {selected.name}
|
||||
{settings?.strategyCandleTypes?.length
|
||||
? ` · ${settings.strategyCandleTypes.join(', ')}`
|
||||
: ''}
|
||||
{market.replace(/^KRW-/, '')}: {selected.name} · {execLabel}
|
||||
</p>
|
||||
)}
|
||||
<label className="ptd-left-field">
|
||||
<span>실행 방식</span>
|
||||
<select
|
||||
className="ptd-left-select"
|
||||
value={settings?.executionType ?? 'CANDLE_CLOSE'}
|
||||
disabled={saving}
|
||||
onChange={e => void persist({ executionType: e.target.value as LiveStrategySettingsDto['executionType'] })}
|
||||
>
|
||||
<option value="CANDLE_CLOSE">봉 마감 직후</option>
|
||||
<option value="REALTIME_TICK">실시간 틱 (3초)</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<p className={`ptd-left-status ${paperAutoTradeEnabled ? 'ptd-left-status--on' : ''}`}>
|
||||
{paperAutoTradeEnabled ? '자동매매 ON' : '자동매매 OFF — 설정 탭에서 변경'}
|
||||
{paperAutoTradeEnabled
|
||||
? '자동매매 ON — 가상투자 Match 시 가상 계좌 자동 체결'
|
||||
: '자동매매 OFF — 가상투자 타이틀바에서 변경'}
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user