diff --git a/store/strategy.go b/store/strategy.go index 573deb48..7888ce1f 100644 --- a/store/strategy.go +++ b/store/strategy.go @@ -12,7 +12,7 @@ import ( // Hard limits to prevent token explosion in AI requests const ( - MaxCandidateCoins = 50 + MaxCandidateCoins = 10 MaxPositions = 3 MaxTimeframes = 4 MinKlineCount = 10 diff --git a/web/src/components/strategy/CoinSourceEditor.tsx b/web/src/components/strategy/CoinSourceEditor.tsx index 14cf1936..20ba3465 100644 --- a/web/src/components/strategy/CoinSourceEditor.tsx +++ b/web/src/components/strategy/CoinSourceEditor.tsx @@ -33,16 +33,16 @@ export function CoinSourceEditor({ let totalLimit = 0 if (config.use_ai500) { - sources.push(`AI500(${config.ai500_limit || 10})`) - totalLimit += config.ai500_limit || 10 + sources.push(`AI500(${config.ai500_limit || 3})`) + totalLimit += config.ai500_limit || 3 } if (config.use_oi_top) { - sources.push(`${ts(coinSource.oiIncreaseShort, language)}(${config.oi_top_limit || 10})`) - totalLimit += config.oi_top_limit || 10 + sources.push(`${ts(coinSource.oiIncreaseShort, language)}(${config.oi_top_limit || 3})`) + totalLimit += config.oi_top_limit || 3 } if (config.use_oi_low) { - sources.push(`${ts(coinSource.oiDecreaseShort, language)}(${config.oi_low_limit || 10})`) - totalLimit += config.oi_low_limit || 10 + sources.push(`${ts(coinSource.oiDecreaseShort, language)}(${config.oi_low_limit || 3})`) + totalLimit += config.oi_low_limit || 3 } if ((config.static_coins || []).length > 0) { sources.push(`${ts(coinSource.custom, language)}(${config.static_coins?.length || 0})`) @@ -71,7 +71,7 @@ export function CoinSourceEditor({ return xyzDexAssets.has(base) } - const MAX_STATIC_COINS = 50 + const MAX_STATIC_COINS = 10 const showToast = (msg: string) => { const toast = document.createElement('div') @@ -327,13 +327,13 @@ export function CoinSourceEditor({ {ts(coinSource.ai500Limit, language)}: !disabled && - onChange({ ...config, ai500_limit: parseInt(val) || 10 }) + onChange({ ...config, ai500_limit: parseInt(val) || 3 }) } disabled={disabled} - options={[3, 5, 10, 20, 30, 40, 50].map(n => ({ value: n, label: String(n) }))} + options={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => ({ value: n, label: String(n) }))} className="px-3 py-1.5 rounded bg-nofx-bg border border-nofx-gold/20 text-nofx-text" /> @@ -381,13 +381,13 @@ export function CoinSourceEditor({ {ts(coinSource.oiTopLimit, language)}: !disabled && - onChange({ ...config, oi_top_limit: parseInt(val) || 10 }) + onChange({ ...config, oi_top_limit: parseInt(val) || 3 }) } disabled={disabled} - options={[3, 5, 10, 20, 30, 40, 50].map(n => ({ value: n, label: String(n) }))} + options={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => ({ value: n, label: String(n) }))} className="px-3 py-1.5 rounded bg-nofx-bg border border-nofx-gold/20 text-nofx-text" /> @@ -435,13 +435,13 @@ export function CoinSourceEditor({ {ts(coinSource.oiLowLimit, language)}: !disabled && - onChange({ ...config, oi_low_limit: parseInt(val) || 10 }) + onChange({ ...config, oi_low_limit: parseInt(val) || 3 }) } disabled={disabled} - options={[3, 5, 10, 20, 30, 40, 50].map(n => ({ value: n, label: String(n) }))} + options={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => ({ value: n, label: String(n) }))} className="px-3 py-1.5 rounded bg-nofx-bg border border-nofx-gold/20 text-nofx-text" /> @@ -492,10 +492,10 @@ export function CoinSourceEditor({
Limit: !disabled && onChange({ ...config, ai500_limit: parseInt(val) || 10 })} + value={config.ai500_limit || 3} + onChange={(val) => !disabled && onChange({ ...config, ai500_limit: parseInt(val) || 3 })} disabled={disabled} - options={[3, 5, 10, 20, 30, 40, 50].map(n => ({ value: n, label: String(n) }))} + options={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => ({ value: n, label: String(n) }))} className="px-2 py-1 rounded text-xs bg-nofx-bg border border-nofx-gold/20 text-nofx-text" />
@@ -532,10 +532,10 @@ export function CoinSourceEditor({
Limit: !disabled && onChange({ ...config, oi_top_limit: parseInt(val) || 10 })} + value={config.oi_top_limit || 3} + onChange={(val) => !disabled && onChange({ ...config, oi_top_limit: parseInt(val) || 3 })} disabled={disabled} - options={[3, 5, 10, 20, 30, 40, 50].map(n => ({ value: n, label: String(n) }))} + options={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => ({ value: n, label: String(n) }))} className="px-2 py-1 rounded text-xs bg-nofx-bg border border-nofx-gold/20 text-nofx-text" />
@@ -572,10 +572,10 @@ export function CoinSourceEditor({
Limit: !disabled && onChange({ ...config, oi_low_limit: parseInt(val) || 10 })} + value={config.oi_low_limit || 3} + onChange={(val) => !disabled && onChange({ ...config, oi_low_limit: parseInt(val) || 3 })} disabled={disabled} - options={[3, 5, 10, 20, 30, 40, 50].map(n => ({ value: n, label: String(n) }))} + options={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => ({ value: n, label: String(n) }))} className="px-2 py-1 rounded text-xs bg-nofx-bg border border-nofx-gold/20 text-nofx-text" />
diff --git a/web/src/components/ui/select.tsx b/web/src/components/ui/select.tsx index ae1e13dc..a7e4699c 100644 --- a/web/src/components/ui/select.tsx +++ b/web/src/components/ui/select.tsx @@ -1,4 +1,4 @@ -import { useRef, useState, useEffect, useCallback } from 'react' +import { useRef, useState, useLayoutEffect, useCallback } from 'react' import { createPortal } from 'react-dom' import { ChevronDown } from 'lucide-react' import { cn } from '../../lib/cn' @@ -30,7 +30,7 @@ export function NofxSelect({ value, onChange, options, disabled, className, styl setPos({ top: rect.bottom + 4, left: rect.left, width: rect.width }) }, []) - useEffect(() => { + useLayoutEffect(() => { if (!open) return updatePos() const handleClose = (e: MouseEvent) => { @@ -39,7 +39,10 @@ export function NofxSelect({ value, onChange, options, disabled, className, styl if (dropdownRef.current?.contains(target)) return setOpen(false) } - const handleScroll = () => setOpen(false) + const handleScroll = (e: Event) => { + if (dropdownRef.current?.contains(e.target as Node)) return + setOpen(false) + } document.addEventListener('mousedown', handleClose) window.addEventListener('scroll', handleScroll, true) return () => {