모의투자 로직 변경
This commit is contained in:
+61
-13
@@ -86,6 +86,13 @@ import LiveStrategyPanel from './components/LiveStrategyPanel';
|
||||
import { TradeNotificationProvider } from './contexts/TradeNotificationContext';
|
||||
import { VerificationIssueNotificationProvider } from './contexts/VerificationIssueNotificationContext';
|
||||
import { LiveSignalNotifier, type LiveSignalNotifierHandle } from './components/LiveSignalNotifier';
|
||||
import { FormalLoginGate } from './components/FormalLoginGate';
|
||||
import {
|
||||
isFormalLogin,
|
||||
isTradingMenuPage,
|
||||
isTradingSettingsCategory,
|
||||
FORMAL_LOGIN_REQUIRED_MSG,
|
||||
} from './utils/tradingAccess';
|
||||
import { NotifyTopMenuBar, ChartToolbarNotify } from './components/NotifyUiBindings';
|
||||
import { AppNotificationLayer } from './components/AppNotificationLayer';
|
||||
import TradeNotificationListPage from './components/TradeNotificationListPage';
|
||||
@@ -163,7 +170,13 @@ function App() {
|
||||
const [guestMode, setGuestMode] = useState(() =>
|
||||
isAppEntered() && !getAuthSession(),
|
||||
);
|
||||
const formalLogin = isFormalLogin(authUser, guestMode);
|
||||
const [loginOpen, setLoginOpen] = useState(false);
|
||||
|
||||
const requireFormalLogin = useCallback(() => {
|
||||
window.alert(FORMAL_LOGIN_REQUIRED_MSG);
|
||||
setLoginOpen(true);
|
||||
}, []);
|
||||
const [appDownloadOpen, setAppDownloadOpen] = useState(false);
|
||||
|
||||
// 전역 지표 파라미터 + 시각 설정 DB 동기화
|
||||
@@ -593,13 +606,17 @@ function App() {
|
||||
}, []);
|
||||
|
||||
const guardedSetMenuPage = useCallback((page: MenuPage) => {
|
||||
if (!formalLogin && isTradingMenuPage(page)) {
|
||||
requireFormalLogin();
|
||||
return;
|
||||
}
|
||||
if (page === 'notifications' && !canMenu('notifications')) return;
|
||||
if (page !== 'notifications' && !canMenu(page)) {
|
||||
setMenuPage(firstAllowedTopMenu(menuPermissions));
|
||||
return;
|
||||
}
|
||||
setMenuPage(page);
|
||||
}, [canMenu, menuPermissions]);
|
||||
}, [canMenu, menuPermissions, formalLogin, requireFormalLogin]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!menuPermsLoaded) return;
|
||||
@@ -814,12 +831,13 @@ function App() {
|
||||
|
||||
/** STOMP 구독 대상 — 가상투자 실행 중이면 투자대상 종목, 아니면 관심종목 */
|
||||
const monitoredMarkets = useMemo(() => {
|
||||
if (!formalLogin) return [];
|
||||
if (isVirtualActive) return virtualMonitoredMarkets;
|
||||
if (!appDefaults.liveStrategyCheck || !appDefaults.liveStrategyId) return [];
|
||||
const set = new Set(watchlist);
|
||||
if (symbol) set.add(symbol);
|
||||
return [...set];
|
||||
}, [isVirtualActive, virtualMonitoredMarkets, watchlist, symbol, appDefaults.liveStrategyCheck, appDefaults.liveStrategyId]);
|
||||
}, [formalLogin, isVirtualActive, virtualMonitoredMarkets, watchlist, symbol, appDefaults.liveStrategyCheck, appDefaults.liveStrategyId]);
|
||||
|
||||
const [marketSubscriptions, setMarketSubscriptions] = useState<{ market: string; candleType: string }[]>([]);
|
||||
|
||||
@@ -1693,7 +1711,7 @@ function App() {
|
||||
markets={monitoredMarkets}
|
||||
marketSubscriptions={liveStompSubscriptions}
|
||||
activeMarket={symbol}
|
||||
enabled={monitoredMarkets.length > 0}
|
||||
enabled={formalLogin && monitoredMarkets.length > 0}
|
||||
popupEnabled={appDefaults.tradeAlertPopup ?? true}
|
||||
chartMarkersActive={menuPage === 'chart'}
|
||||
onMarkersChange={markers => {
|
||||
@@ -1737,19 +1755,26 @@ function App() {
|
||||
)}
|
||||
|
||||
{menuPage === 'strategy' && (
|
||||
<StrategyPage theme={theme} activeIndicators={indicators} />
|
||||
formalLogin
|
||||
? <StrategyPage theme={theme} activeIndicators={indicators} />
|
||||
: <FormalLoginGate onLogin={requireFormalLogin} />
|
||||
)}
|
||||
|
||||
{menuPage === 'strategy-editor' && (
|
||||
<StrategyEditorPage theme={theme} />
|
||||
formalLogin
|
||||
? <StrategyEditorPage theme={theme} />
|
||||
: <FormalLoginGate onLogin={requireFormalLogin} />
|
||||
)}
|
||||
|
||||
{/* ── 백테스팅 이력 화면 ─────────────────────────────────────────── */}
|
||||
{menuPage === 'backtest' && (
|
||||
<BacktestHistoryPage theme={theme} />
|
||||
formalLogin
|
||||
? <BacktestHistoryPage theme={theme} />
|
||||
: <FormalLoginGate onLogin={requireFormalLogin} />
|
||||
)}
|
||||
|
||||
{menuPage === 'paper' && (
|
||||
formalLogin ? (
|
||||
<PaperTradingPage
|
||||
theme={theme}
|
||||
tickers={marketTickers}
|
||||
@@ -1759,6 +1784,7 @@ function App() {
|
||||
paperAutoTradeEnabled={paperAutoTradeEnabled}
|
||||
onPaperOrderFilled={handlePaperOrderFilled}
|
||||
onOpenSettings={() => {
|
||||
if (!formalLogin) { requireFormalLogin(); return; }
|
||||
setSettingsInitialCategory('paper');
|
||||
setMenuPage('settings');
|
||||
}}
|
||||
@@ -1767,9 +1793,13 @@ function App() {
|
||||
setMenuPage('chart');
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<FormalLoginGate onLogin={requireFormalLogin} title="투자관리" />
|
||||
)
|
||||
)}
|
||||
|
||||
{menuPage === 'virtual' && (
|
||||
formalLogin ? (
|
||||
<VirtualTradingPage
|
||||
theme={theme}
|
||||
tickers={marketTickers}
|
||||
@@ -1780,6 +1810,9 @@ function App() {
|
||||
onPaperAutoTradeEnabled={v => saveAppDef({ paperAutoTradeEnabled: v })}
|
||||
onPaperOrderFilled={handlePaperOrderFilled}
|
||||
/>
|
||||
) : (
|
||||
<FormalLoginGate onLogin={requireFormalLogin} title="가상매매" />
|
||||
)
|
||||
)}
|
||||
|
||||
{menuPage === 'trend-search' && (
|
||||
@@ -1802,6 +1835,7 @@ function App() {
|
||||
|
||||
{/* ── 설정 화면 ──────────────────────────────────────────────────── */}
|
||||
{menuPage === 'notifications' && canMenu('notifications') && (
|
||||
formalLogin ? (
|
||||
<TradeNotificationListPage
|
||||
theme={theme}
|
||||
tickers={marketTickers}
|
||||
@@ -1814,10 +1848,15 @@ function App() {
|
||||
setMenuPage('chart');
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<FormalLoginGate onLogin={requireFormalLogin} title="알림목록" />
|
||||
)
|
||||
)}
|
||||
|
||||
{menuPage === 'settings' && canMenu('settings') && (
|
||||
<SettingsPage
|
||||
isFormalLogin={formalLogin}
|
||||
onRequireFormalLogin={requireFormalLogin}
|
||||
theme={theme}
|
||||
menuPermissions={menuPermissions}
|
||||
magnetMode={magnetMode}
|
||||
@@ -2034,7 +2073,7 @@ function App() {
|
||||
backtestActive={btMatchesChart}
|
||||
backtestRunning={btRunning}
|
||||
backtestRunningId={undefined}
|
||||
onRunBacktest={menuPage === 'chart' && layoutDef.count === 1
|
||||
onRunBacktest={menuPage === 'chart' && layoutDef.count === 1 && formalLogin
|
||||
? async (opts) => {
|
||||
if (opts.strategyName) setBtStrategyName(opts.strategyName);
|
||||
if (useUpbit && (isLoading || bars.length === 0)) return;
|
||||
@@ -2066,16 +2105,25 @@ function App() {
|
||||
if (appDefaults.btAutoPopup) setShowBtResult(true);
|
||||
}
|
||||
: undefined}
|
||||
onOpenBtSettings={() => setShowBtSettings(true)}
|
||||
onOpenBtResults={() => setShowBtResult(true)}
|
||||
onOpenBtSettings={() => {
|
||||
if (!formalLogin) { requireFormalLogin(); return; }
|
||||
setShowBtSettings(true);
|
||||
}}
|
||||
onOpenBtResults={() => {
|
||||
if (!formalLogin) { requireFormalLogin(); return; }
|
||||
setShowBtResult(true);
|
||||
}}
|
||||
hasBtResult={btMatchesChart}
|
||||
onClearBtMarkers={() => {
|
||||
btMarkerPayloadRef.current = null;
|
||||
btClear();
|
||||
managerRef.current?.clearBacktestMarkers();
|
||||
}}
|
||||
onToggleLiveStrategy={() => setShowLivePanel(v => !v)}
|
||||
liveStrategyActive={showLivePanel || monitoredMarkets.length > 0}
|
||||
onToggleLiveStrategy={() => {
|
||||
if (!formalLogin) { requireFormalLogin(); return; }
|
||||
setShowLivePanel(v => !v);
|
||||
}}
|
||||
liveStrategyActive={formalLogin && (showLivePanel || monitoredMarkets.length > 0)}
|
||||
showChartQuote={useUpbit}
|
||||
chartLiveQuote={liveQuote}
|
||||
chartQuoteLoading={isLoading}
|
||||
@@ -2584,8 +2632,8 @@ function App() {
|
||||
onMarketSelect={handleTradeMarketSelect}
|
||||
availableKrw={paperCashBalance}
|
||||
availableCoinQty={paperCoinQty}
|
||||
paperTradingEnabled={paperTradingEnabled}
|
||||
paperAutoTradeEnabled={paperAutoTradeEnabled}
|
||||
paperTradingEnabled={formalLogin && paperTradingEnabled}
|
||||
paperAutoTradeEnabled={formalLogin && paperAutoTradeEnabled}
|
||||
onPaperOrderFilled={() => {
|
||||
refreshPaperAccount(symbol);
|
||||
handlePaperOrderFilled();
|
||||
|
||||
Reference in New Issue
Block a user