feat(web): improve trader config UX for initial balance and prompt templates (#629 #630) (#673)

- Add onBlur validation for initial_balance input to enforce minimum of 100
- Add detailed prompt template descriptions with i18n support
- Fix Traditional Chinese to Simplified Chinese
- Extract hardcoded Chinese text to i18n translation system
- Add translation keys for all prompt templates and descriptions

Fixes #629, Fixes #630
This commit is contained in:
0xYYBB | ZYY | Bobo
2025-11-10 11:55:40 +08:00
committed by GitHub
parent c970a4da29
commit 7b0b19708e
2 changed files with 126 additions and 11 deletions

View File

@@ -417,6 +417,13 @@ export function TraderConfigModal({
Number(e.target.value)
)
}
onBlur={(e) => {
// Force minimum value on blur
const value = Number(e.target.value)
if (value < 100) {
handleInputChange('initial_balance', 100)
}
}}
className="w-full px-3 py-2 bg-[#0B0E11] border border-[#2B3139] rounded text-[#EAECEF] focus:border-[#F0B90B] focus:outline-none"
min="100"
step="0.01"
@@ -617,7 +624,7 @@ export function TraderConfigModal({
{/* 系统提示词模板选择 */}
<div>
<label className="text-sm text-[#EAECEF] block mb-2">
{t('systemPromptTemplate', language)}
</label>
<select
value={formData.system_prompt_template}
@@ -626,17 +633,75 @@ export function TraderConfigModal({
}
className="w-full px-3 py-2 bg-[#0B0E11] border border-[#2B3139] rounded text-[#EAECEF] focus:border-[#F0B90B] focus:outline-none"
>
{promptTemplates.map((template) => (
<option key={template.name} value={template.name}>
{template.name === 'default'
? 'Default (默认稳健)'
: template.name === 'aggressive'
? 'Aggressive (激进)'
: template.name.charAt(0).toUpperCase() +
template.name.slice(1)}
</option>
))}
{promptTemplates.map((template) => {
// Template name mapping with i18n
const getTemplateName = (name: string) => {
const keyMap: Record<string, string> = {
default: 'promptTemplateDefault',
adaptive: 'promptTemplateAdaptive',
adaptive_relaxed: 'promptTemplateAdaptiveRelaxed',
Hansen: 'promptTemplateHansen',
nof1: 'promptTemplateNof1',
taro_long_prompts: 'promptTemplateTaroLong',
}
const key = keyMap[name]
return key
? t(key, language)
: name.charAt(0).toUpperCase() + name.slice(1)
}
return (
<option key={template.name} value={template.name}>
{getTemplateName(template.name)}
</option>
)
})}
</select>
{/* 動態描述區域 */}
<div
className="mt-2 p-3 rounded"
style={{
background: 'rgba(240, 185, 11, 0.05)',
border: '1px solid rgba(240, 185, 11, 0.15)',
}}
>
<div
className="text-xs font-semibold mb-1"
style={{ color: '#F0B90B' }}
>
{(() => {
const titleKeyMap: Record<string, string> = {
default: 'promptDescDefault',
adaptive: 'promptDescAdaptive',
adaptive_relaxed: 'promptDescAdaptiveRelaxed',
Hansen: 'promptDescHansen',
nof1: 'promptDescNof1',
taro_long_prompts: 'promptDescTaroLong',
}
const key = titleKeyMap[formData.system_prompt_template]
return key
? t(key, language)
: t('promptDescDefault', language)
})()}
</div>
<div className="text-xs" style={{ color: '#848E9C' }}>
{(() => {
const contentKeyMap: Record<string, string> = {
default: 'promptDescDefaultContent',
adaptive: 'promptDescAdaptiveContent',
adaptive_relaxed: 'promptDescAdaptiveRelaxedContent',
Hansen: 'promptDescHansenContent',
nof1: 'promptDescNof1Content',
taro_long_prompts: 'promptDescTaroLongContent',
}
const key = contentKeyMap[formData.system_prompt_template]
return key
? t(key, language)
: t('promptDescDefaultContent', language)
})()}
</div>
</div>
<p className="text-xs text-[#848E9C] mt-1">
</p>

View File

@@ -280,6 +280,33 @@ export const translations = {
altcoinLeverageValidation: 'Altcoin leverage must be between 1-20x',
invalidSymbolFormat: 'Invalid symbol format: {symbol}, must end with USDT',
// System Prompt Templates
systemPromptTemplate: 'System Prompt Template',
promptTemplateDefault: 'Default Stable',
promptTemplateAdaptive: 'Conservative Strategy',
promptTemplateAdaptiveRelaxed: 'Aggressive Strategy',
promptTemplateHansen: 'Hansen Strategy',
promptTemplateNof1: 'NoF1 English Framework',
promptTemplateTaroLong: 'Taro Long Position',
promptDescDefault: '📊 Default Stable Strategy',
promptDescDefaultContent:
'Maximize Sharpe ratio, balanced risk-reward, suitable for beginners and stable long-term trading',
promptDescAdaptive: '🛡️ Conservative Strategy (v6.0.0)',
promptDescAdaptiveContent:
'Strict risk control, BTC mandatory confirmation, high win rate priority, suitable for conservative traders',
promptDescAdaptiveRelaxed: '⚡ Aggressive Strategy (v6.0.0)',
promptDescAdaptiveRelaxedContent:
'High-frequency trading, BTC optional confirmation, pursue trading opportunities, suitable for volatile markets',
promptDescHansen: '🎯 Hansen Strategy',
promptDescHansenContent:
'Hansen custom strategy, maximize Sharpe ratio, for professional traders',
promptDescNof1: '🌐 NoF1 English Framework',
promptDescNof1Content:
'Hyperliquid exchange specialist, English prompts, maximize risk-adjusted returns',
promptDescTaroLong: '📈 Taro Long Position Strategy',
promptDescTaroLongContent:
'Data-driven decisions, multi-dimensional validation, continuous learning evolution, long position specialist',
// Loading & Error
loading: 'Loading...',
loadingError: '⚠️ Failed to load AI learning data',
@@ -1043,6 +1070,29 @@ export const translations = {
altcoinLeverageValidation: '山寨币杠杆必须在1-20倍之间',
invalidSymbolFormat: '无效的币种格式:{symbol}必须以USDT结尾',
// System Prompt Templates
systemPromptTemplate: '系统提示词模板',
promptTemplateDefault: '默认稳健',
promptTemplateAdaptive: '保守策略',
promptTemplateAdaptiveRelaxed: '激进策略',
promptTemplateHansen: 'Hansen 策略',
promptTemplateNof1: 'NoF1 英文框架',
promptTemplateTaroLong: 'Taro 长仓',
promptDescDefault: '📊 默认稳健策略',
promptDescDefaultContent: '最大化夏普比率,平衡风险收益,适合新手和长期稳定交易',
promptDescAdaptive: '🛡️ 保守策略 (v6.0.0)',
promptDescAdaptiveContent: '严格风控BTC 强制确认,高胜率优先,适合保守型交易者',
promptDescAdaptiveRelaxed: '⚡ 激进策略 (v6.0.0)',
promptDescAdaptiveRelaxedContent:
'高频交易BTC 可选确认,追求交易机会,适合波动市场',
promptDescHansen: '🎯 Hansen 策略',
promptDescHansenContent: 'Hansen 定制策略,最大化夏普比率,专业交易者专用',
promptDescNof1: '🌐 NoF1 英文框架',
promptDescNof1Content:
'Hyperliquid 交易所专用,英文提示词,风险调整回报最大化',
promptDescTaroLong: '📈 Taro 长仓策略',
promptDescTaroLongContent: '数据驱动决策,多维度验证,持续学习进化,长仓专用',
// Loading & Error
loading: '加载中...',
loadingError: '⚠️ 加载AI学习数据失败',