fix: Macro panel manage-only (not auto-open), Trump-only auto-trade copy, store docs
SystemControl was rendered as two per-system panels (Trump / Macro) that both flipped the SAME global auto_trade, and its copy claimed a "qualifying Macro Vibes signal auto-opens a trade". Both are wrong: bot_engine.process_post early-returns for System 2, so the auto_trade gate only ever fires for Trump (System 1). Macro Vibes is manage-only — it never auto-opens. - Macro (`system="btc"`) panel: replaced the misleading Auto-Trade ON/OFF toggle with a manage-only explainer (open on HL → /adopt via Telegram → bot manages exits) and a note that the Trump-page switch has no effect here. - Trump (`system="trump"`) panel: relabeled the switch "TRUMP (System 1)" and rewrote all copy/status lines to say Trump-only auto-open (was "GLOBAL (Trump + BTC)" / "both Trump & BTC"). - CLAUDE.md: corrected "No global store (no Redux/Zustand)" — the app DOES use a small Zustand store (store/dashboard.ts / useDashboardStore); documented what it holds and the guidance to keep it small. Note (not a bug): dashboard adopt/release is intentionally Telegram-only — there are no positions/adopt|hl|release client calls and the UI correctly points to the Telegram /adopt command. No dashboard wiring is "broken". tsc + next build clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -138,7 +138,11 @@ mutate the subscription.
|
||||
|
||||
## State management
|
||||
|
||||
- **No global store** (no Redux/Zustand). Tree-local state + props.
|
||||
- **One small global store** — `store/dashboard.ts` (Zustand, `useDashboardStore`).
|
||||
Holds cross-page UI/session state: selected post, chart asset/timeframe,
|
||||
wallet address, subscription + bot-readiness flags, masked HL key hint, and
|
||||
the live-price map. Everything else stays tree-local (state + props) — don't
|
||||
grow this store into a catch-all; page-specific data belongs in the page.
|
||||
- **SWR-style cache** in `lib/cache.ts` for the API-heavy pages.
|
||||
- **WebSocket** singleton via `WsProvider` — used by `SignalMonitor` and
|
||||
live price tickers.
|
||||
|
||||
@@ -134,6 +134,49 @@ export default function SystemControl({ system }: { system: 'trump' | 'btc' }) {
|
||||
const settingsHref = `/${locale}/settings#bot-config`
|
||||
const settingsLabel = system === 'trump' ? 'Trump Signal' : 'Macro Vibes'
|
||||
|
||||
// Macro Vibes (System 2) is MANAGE-ONLY by design — it NEVER auto-opens a
|
||||
// trade. bot_engine.process_post early-returns for sys2 sources, so the
|
||||
// master Auto-Trade switch only governs Trump (System 1). Presenting an
|
||||
// ON/OFF auto-trade toggle here would (a) falsely imply Macro signals
|
||||
// auto-open and (b) be a confusing second copy of the SAME global switch
|
||||
// shown on the Trump page. Show the adopt-only flow instead.
|
||||
if (system === 'btc') {
|
||||
const linkStyle: React.CSSProperties = {
|
||||
display: 'inline-flex', alignItems: 'center', gap: 8, padding: '8px 12px',
|
||||
borderRadius: 999, border: '1px solid var(--line)', background: 'var(--surface)',
|
||||
fontSize: 12, color: 'var(--ink)', textDecoration: 'none', fontWeight: 700,
|
||||
boxShadow: 'var(--shadow-1)',
|
||||
}
|
||||
return (
|
||||
<div className="card" style={{ padding: 0, marginBottom: 16, overflow: 'hidden' }}>
|
||||
<div style={{ padding: '14px 16px', background: s.soft,
|
||||
borderLeft: `4px solid ${s.accent}` }}>
|
||||
<div style={{ fontSize: 14, fontWeight: 700, color: s.accent }}>
|
||||
{s.idx} {s.name} — manage-only
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ padding: '16px', fontSize: 13, color: 'var(--ink-2)', lineHeight: 1.6 }}>
|
||||
<p style={{ margin: '0 0 10px' }}>
|
||||
<strong>Macro Vibes does not auto-open trades.</strong> When a bottom-reversal
|
||||
signal fires you get a Telegram alert. You open the position yourself on
|
||||
Hyperliquid, then hand it to the bot with <code>/adopt</code> — the bot then
|
||||
manages the exit (staged stop ladder, de-risk, pyramid, peak-trail).
|
||||
</p>
|
||||
<p style={{ margin: '0 0 12px', color: 'var(--ink-4)', fontSize: 12 }}>
|
||||
The Auto-Trade switch on the Trump page controls Trump (System 1)
|
||||
auto-opens only — it has no effect on Macro Vibes.
|
||||
</p>
|
||||
<Link href={settingsHref} style={linkStyle}>
|
||||
<span style={{ fontSize: 10, letterSpacing: '0.08em', textTransform: 'uppercase',
|
||||
color: 'var(--ink-4)' }}>Settings</span>
|
||||
<span>{settingsLabel}</span>
|
||||
<span aria-hidden="true">↗</span>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Wallet not connected: a previous version showed a giant full-width
|
||||
// "Connect a wallet..." card here, which was redundant with the navbar's
|
||||
// Connect button. The opposite extreme — rendering null — silently hid
|
||||
@@ -203,13 +246,13 @@ export default function SystemControl({ system }: { system: 'trump' | 'btc' }) {
|
||||
: `Circuit breaker tripped (${pub?.circuit_breaker_reason || 'risk limit'}). Turn Auto-Trade ON to acknowledge & resume.`
|
||||
} else if (!autoOn) {
|
||||
netMsg = isZh
|
||||
? 'Auto-Trade 当前为关闭(全局): Trump 和 BTC 信号仍会显示,但不会自动开仓。'
|
||||
: 'Auto-Trade is OFF (global) — Trump AND Macro Vibes signals are shown in the feed but NOT traded.'
|
||||
? 'Auto-Trade 当前为关闭: Trump 信号仍会显示,但不会自动开仓。'
|
||||
: 'Auto-Trade is OFF — Trump signals are shown in the feed but NOT traded.'
|
||||
} else {
|
||||
netOk = true
|
||||
netMsg = isZh
|
||||
? `Auto-Trade 已开启(全局,覆盖 Trump 和 BTC): 下一条合格信号会自动开出${paper ? '模拟' : '真实'}仓位。`
|
||||
: `Auto-Trade ON (global, both Trump & BTC) — will open a ${paper ? 'PAPER' : 'LIVE'} trade on the next qualifying signal.`
|
||||
? `Auto-Trade 已开启(Trump 系统①): 下一条合格 Trump 信号会自动开出${paper ? '模拟' : '真实'}仓位。`
|
||||
: `Auto-Trade ON (Trump / System 1) — will open a ${paper ? 'PAPER' : 'LIVE'} trade on the next qualifying Trump signal.`
|
||||
}
|
||||
|
||||
const Pill = ({ active, onClick, children, tone }: {
|
||||
@@ -245,21 +288,23 @@ export default function SystemControl({ system }: { system: 'trump' | 'btc' }) {
|
||||
<div>
|
||||
<div style={{ fontSize: 14, fontWeight: 700 }}>
|
||||
Auto-Trade <span style={{ fontSize: 10, fontWeight: 600,
|
||||
color: 'var(--ink-4)', marginLeft: 6 }}>{isZh ? '· 全局(Trump + BTC)' : '· GLOBAL (Trump + BTC)'}</span>
|
||||
color: 'var(--ink-4)', marginLeft: 6 }}>{isZh ? '· Trump 系统①' : '· TRUMP (System 1)'}</span>
|
||||
</div>
|
||||
<div style={{ fontSize: 11, color: 'var(--ink-4)', marginTop: 3, maxWidth: 480, lineHeight: 1.5 }}>
|
||||
{isZh ? (
|
||||
<>
|
||||
<strong>一个开关控制两套系统。</strong> 关闭时:信号仍会扫描并显示,但不会自动交易。
|
||||
开启时:满足条件的 Trump 或 BTC 信号都会自动开仓。无论开关状态如何,
|
||||
<strong>控制 Trump 信号是否自动开仓。</strong> 关闭时:信号仍会扫描并显示,但不会自动交易。
|
||||
开启时:满足条件的 Trump 信号会自动开仓。无论开关状态如何,
|
||||
已开仓位的止损和分级降风险都会继续保护持仓。
|
||||
(Macro Vibes 不自动开仓——见 Macro 页的 manage-only 说明。)
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<strong>One switch for both systems.</strong> OFF: signals scanned
|
||||
& shown in the feed, nothing traded. ON: a qualifying Trump OR
|
||||
Macro Vibes signal auto-opens a trade. Stop-loss / staged de-risk
|
||||
always protect open positions either way.
|
||||
<strong>Controls Trump (System 1) auto-opens.</strong> OFF: signals
|
||||
scanned & shown in the feed, nothing traded. ON: a qualifying
|
||||
Trump signal auto-opens a trade. Stop-loss / staged de-risk always
|
||||
protect open positions either way. (Macro Vibes is manage-only and
|
||||
never auto-opens — see its page.)
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user