============================================================================ Prompt Building - System Prompt ============================================================================ BuildSystemPrompt builds System Prompt according to strategy configuration
(accountEquity float64, variant string)
| 16 | |
| 17 | // BuildSystemPrompt builds System Prompt according to strategy configuration |
| 18 | func (e *StrategyEngine) BuildSystemPrompt(accountEquity float64, variant string) string { |
| 19 | var sb strings.Builder |
| 20 | riskControl := e.config.RiskControl |
| 21 | promptSections := e.config.PromptSections |
| 22 | // System prompts are intentionally English-only. UI copy can be localized, |
| 23 | // but the model contract should stay language-stable for an international |
| 24 | // open-source project and for reproducible trading behavior. |
| 25 | lang := LangEnglish |
| 26 | zh := false |
| 27 | singleSymbol, primarySymbol := e.singleSymbolInfo() |
| 28 | |
| 29 | if e.usesVergexSignalPrompt() { |
| 30 | return e.buildVergexSystemPrompt(accountEquity, variant, lang, zh, singleSymbol, primarySymbol) |
| 31 | } |
| 32 | |
| 33 | // 0. Data Dictionary & Schema (ensure AI understands all fields) |
| 34 | sb.WriteString(GetSchemaPrompt(lang)) |
| 35 | sb.WriteString("\n\n") |
| 36 | sb.WriteString("---\n\n") |
| 37 | |
| 38 | // 1. Role definition (editable; falls back to a generic intro in the |
| 39 | // correct language so we don't mix EN headings with ZH custom text). |
| 40 | roleDefinition := englishOnlyPromptSection(promptSections.RoleDefinition) |
| 41 | if roleDefinition != "" { |
| 42 | sb.WriteString(roleDefinition) |
| 43 | sb.WriteString("\n\n") |
| 44 | } else if zh { |
| 45 | sb.WriteString("# You are a professional Hyperliquid USDC multi-asset trading AI\n\n") |
| 46 | sb.WriteString("Your task is to make trading decisions based on the provided market data.\n\n") |
| 47 | } else { |
| 48 | sb.WriteString("# You are a professional Hyperliquid USDC multi-asset trading AI\n\n") |
| 49 | sb.WriteString("Your task is to make trading decisions based on the provided market data.\n\n") |
| 50 | } |
| 51 | |
| 52 | // 2. Trading mode variant |
| 53 | writeModeVariant(&sb, variant, zh) |
| 54 | |
| 55 | // 3. Hard constraints (risk control). |
| 56 | // |
| 57 | // `singleSymbol` is true for strategies that deliberately trade just one |
| 58 | // instrument (the quick-create flow, single-asset templates). For those, |
| 59 | // the "BTC/ETH vs Altcoin" two-tier categorization is irrelevant and |
| 60 | // actively misleading — we surface a single position-value limit instead. |
| 61 | btcEthPosValueRatio := riskControl.BTCETHMaxPositionValueRatio |
| 62 | if btcEthPosValueRatio <= 0 { |
| 63 | btcEthPosValueRatio = 5.0 |
| 64 | } |
| 65 | altcoinPosValueRatio := riskControl.AltcoinMaxPositionValueRatio |
| 66 | if altcoinPosValueRatio <= 0 { |
| 67 | altcoinPosValueRatio = 1.0 |
| 68 | } |
| 69 | |
| 70 | writeHardConstraints(&sb, accountEquity, riskControl, btcEthPosValueRatio, altcoinPosValueRatio, singleSymbol, primarySymbol, zh) |
| 71 | |
| 72 | // 4. Trading frequency (editable) |
| 73 | tradingFrequency := englishOnlyPromptSection(promptSections.TradingFrequency) |
| 74 | if tradingFrequency != "" { |
| 75 | sb.WriteString(tradingFrequency) |