fix(web): source simple trigger market price

This commit is contained in:
root 2026-05-06 00:05:28 +00:00
parent 00c117321d
commit b7044a1eae

View File

@ -140,6 +140,8 @@ export function SimpleView() {
const normalizedSymbol = draft.symbol.trim().toUpperCase();
const livePrice = normalizedSymbol ? Number(botState.symbols?.[normalizedSymbol]?.price || 0) : 0;
const computedTriggerPrice = computeSimpleTriggerPrice(draft);
const resolvedMarketPrice = parsePositiveNumber(draft.currentMarketPrice);
const marketPriceSource = livePrice > 0 ? 'live' : (resolvedMarketPrice !== null ? 'recent_close' : null);
const triggerOptions = draft.side === 'buy'
? [
@ -176,11 +178,23 @@ export function SimpleView() {
}, [draft.side, draft.triggerMode]);
useEffect(() => {
if (draft.triggerMode !== 'drop_percent' || !livePrice || draft.currentMarketPrice.trim()) {
if (draft.triggerMode !== 'drop_percent' || !livePrice) {
return;
}
setDraft(prev => ({ ...prev, currentMarketPrice: livePrice.toFixed(4) }));
}, [draft.triggerMode, draft.currentMarketPrice, livePrice]);
setDraft(prev => (
prev.currentMarketPrice === livePrice.toFixed(4)
? prev
: { ...prev, currentMarketPrice: livePrice.toFixed(4) }
));
}, [draft.triggerMode, livePrice]);
useEffect(() => {
if (draft.triggerMode !== 'drop_percent' || !normalizedSymbol || livePrice > 0 || draft.currentMarketPrice.trim() || loadingPrice) {
return;
}
void handleLoadMarketPrice();
}, [draft.triggerMode, normalizedSymbol, livePrice]);
const rulePreview = useMemo(() => {
if (!normalizedSymbol || computedTriggerPrice === null) return null;
@ -207,7 +221,7 @@ export function SimpleView() {
throw new Error(`No recent market price found for ${normalizedSymbol}`);
}
updateDraft('currentMarketPrice', latestClose.toFixed(4));
setMessage(`Loaded current market price for ${normalizedSymbol}`);
setMessage(`Loaded market price for ${normalizedSymbol}`);
} catch (err: any) {
setError(err?.message ?? 'Failed to load current market price');
} finally {
@ -387,15 +401,22 @@ export function SimpleView() {
<div style={{ display: 'flex', gap: 8 }}>
<input
value={draft.currentMarketPrice}
onChange={e => updateDraft('currentMarketPrice', e.target.value)}
placeholder="e.g. 212.42"
inputMode="decimal"
style={{ flex: 1, border: '1px solid #D1D5DB', borderRadius: 10, padding: '10px 12px', fontSize: 14 }}
readOnly
placeholder={normalizedSymbol ? 'Loading market price…' : 'Enter symbol first'}
style={{
flex: 1,
border: '1px solid #D1D5DB',
borderRadius: 10,
padding: '10px 12px',
fontSize: 14,
background: '#F9FAFB',
color: draft.currentMarketPrice ? '#111827' : '#6B7280',
}}
/>
<button
type="button"
onClick={handleLoadMarketPrice}
disabled={loadingPrice}
disabled={loadingPrice || !normalizedSymbol}
style={{
border: '1px solid #D1D5DB',
borderRadius: 10,
@ -403,15 +424,17 @@ export function SimpleView() {
padding: '0 12px',
fontSize: 12,
fontWeight: 800,
color: '#374151',
cursor: loadingPrice ? 'wait' : 'pointer',
color: loadingPrice || !normalizedSymbol ? '#9CA3AF' : '#374151',
cursor: loadingPrice ? 'wait' : (!normalizedSymbol ? 'not-allowed' : 'pointer'),
}}
>
<RefreshCw size={14} style={{ animation: loadingPrice ? 'spin 1s linear infinite' : 'none' }} />
</button>
</div>
{livePrice > 0 && (
<small style={{ color: '#6B7280' }}>Live feed price in app state: {livePrice.toFixed(4)}</small>
{marketPriceSource && (
<small style={{ color: '#6B7280' }}>
Source: {marketPriceSource === 'live' ? 'live market feed' : 'recent market close'}
</small>
)}
</label>
<label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>