(sb *strings.Builder, accountEquity float64, riskControl store.RiskControlConfig, tradeFiPositionValueRatio float64, singleSymbol bool, primarySymbol string, zh bool)
| 318 | } |
| 319 | |
| 320 | func writeVergexOutputFormat(sb *strings.Builder, accountEquity float64, riskControl store.RiskControlConfig, tradeFiPositionValueRatio float64, singleSymbol bool, primarySymbol string, zh bool) { |
| 321 | exampleSymbol := "xyz:NVDA" |
| 322 | secondSymbol := "xyz:AAPL" |
| 323 | if singleSymbol && strings.TrimSpace(primarySymbol) != "" { |
| 324 | exampleSymbol = primarySymbol |
| 325 | secondSymbol = primarySymbol |
| 326 | } |
| 327 | positionSize := accountEquity * tradeFiPositionValueRatio |
| 328 | leverage := riskControl.AltcoinMaxLeverage |
| 329 | if leverage <= 0 { |
| 330 | leverage = 1 |
| 331 | } |
| 332 | |
| 333 | sb.WriteString("# Output Format (Strictly Follow)\n\n") |
| 334 | if zh { |
| 335 | sb.WriteString("Use XML tags <reasoning> and <decision> to separate concise analysis from the decision JSON.\n\n") |
| 336 | sb.WriteString("Direction must be data-driven: use `open_long` for confirmed upside structures and `open_short` for confirmed downside structures; never default to long-only or short-only behavior.\n\n") |
| 337 | if !singleSymbol { |
| 338 | sb.WriteString("This cycle you MUST include at least one `open_long` (pick the strongest net-inflow / bullish name) AND at least one `open_short` (pick the strongest net-outflow / bearish name); omit a side only if no suitable name exists for it.\n\n") |
| 339 | } |
| 340 | } else { |
| 341 | sb.WriteString("Use XML tags <reasoning> and <decision> to separate concise analysis from the decision JSON.\n\n") |
| 342 | sb.WriteString("Direction must be data-driven: use `open_long` for confirmed upside structures and `open_short` for confirmed downside structures; never default to long-only or short-only behavior.\n\n") |
| 343 | if !singleSymbol { |
| 344 | sb.WriteString("This cycle you MUST include at least one `open_long` (pick the strongest net-inflow / bullish name) AND at least one `open_short` (pick the strongest net-outflow / bearish name); omit a side only if no suitable name exists for it.\n\n") |
| 345 | } |
| 346 | } |
| 347 | sb.WriteString("<reasoning>\n") |
| 348 | if zh { |
| 349 | sb.WriteString("Briefly state whether Claw402 ranking, Signal Lab, heatmap and candles agree; if data is missing or conflicting, explain why you wait.\n") |
| 350 | } else { |
| 351 | sb.WriteString("Briefly state whether Claw402 ranking, Signal Lab, heatmap and candles agree; if data is missing or conflicting, explain why you wait.\n") |
| 352 | } |
| 353 | sb.WriteString("</reasoning>\n\n") |
| 354 | sb.WriteString("<decision>\n") |
| 355 | sb.WriteString("```json\n[\n") |
| 356 | if singleSymbol { |
| 357 | sb.WriteString(fmt.Sprintf(" {\"symbol\": \"%s\", \"action\": \"open_short\", \"leverage\": %d, \"position_size_usd\": %.0f, \"stop_loss\": 0, \"take_profit\": 0, \"confidence\": 85, \"risk_usd\": 0}\n", exampleSymbol, leverage, positionSize)) |
| 358 | } else { |
| 359 | sb.WriteString(fmt.Sprintf(" {\"symbol\": \"%s\", \"action\": \"open_long\", \"leverage\": %d, \"position_size_usd\": %.0f, \"stop_loss\": 0, \"take_profit\": 0, \"confidence\": 85, \"risk_usd\": 0},\n", exampleSymbol, leverage, positionSize)) |
| 360 | sb.WriteString(fmt.Sprintf(" {\"symbol\": \"%s\", \"action\": \"open_short\", \"leverage\": %d, \"position_size_usd\": %.0f, \"stop_loss\": 0, \"take_profit\": 0, \"confidence\": 85, \"risk_usd\": 0}\n", secondSymbol, leverage, positionSize)) |
| 361 | } |
| 362 | sb.WriteString("]\n```\n") |
| 363 | sb.WriteString("</decision>\n\n") |
| 364 | |
| 365 | if zh { |
| 366 | sb.WriteString("## Field Requirements\n\n") |
| 367 | sb.WriteString("- `action`: open_long | open_short | close_long | close_short | hold | wait\n") |
| 368 | sb.WriteString(fmt.Sprintf("- `confidence`: 0-100; recommended ≥ %d to open\n", riskControl.MinConfidence)) |
| 369 | sb.WriteString("- Required when opening: leverage, position_size_usd, stop_loss, take_profit, confidence, risk_usd\n") |
| 370 | sb.WriteString("- All numeric values must be calculated numbers, not formulas.\n") |
| 371 | if singleSymbol { |
| 372 | sb.WriteString(fmt.Sprintf("- This strategy trades only `%s`; JSON symbol must match it exactly.\n", exampleSymbol)) |
| 373 | } else { |
| 374 | sb.WriteString("- JSON symbols must exactly match current candidates or existing positions; keep `xyz:` on XYZ instruments, and do not add `xyz:` or `USDT` to core crypto symbols.\n") |
| 375 | } |
| 376 | sb.WriteString("\n") |
| 377 | } else { |
no outgoing calls
no test coverage detected