mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-06-06 05:51:19 +08:00
feat(strategy): English-only XYZ stock prompt + flat-account aggression + tier promote
The strategy prompt the LLM saw for a Chinese-language single-symbol US stock trader was an incoherent zh/en patchwork — schema in Chinese, role definition in English, hard constraints in English, custom prompt back in Chinese — with crypto-flavored BTC/ETH vs Altcoin labelling that made no sense for ARM-USDC. The LLM responded by being conservative and boring. When it finally tried to open, the validator rejected the order because the validator classified the stock as an altcoin (1x equity cap = 112 USDT max) while the prompt said 5x cap (= 559 USDT). - kernel/engine_prompt.go (BuildSystemPrompt): all eight prompt sections now respect e.GetLanguage() consistently. For single-symbol Hyperliquid XYZ assets (US stocks, commodities, forex) we additionally force the language to English regardless of the strategy's stored language — US-equity reasoning lands better in English and prevents the language-mix incoherence. The Hard Constraints section drops the BTC/ETH vs Altcoin two-tier split when the strategy trades a single instrument and shows one Position Value Limit line tagged with the actual symbol. The JSON example uses that symbol instead of the legacy BTCUSDT/ETHUSDT. The legacy stored custom_prompt (which was Chinese for stock quick-creates) is replaced for XYZ assets by buildXYZStockCustomPrompt — a built-in English long-only stock briefing that includes a Flat-Account Rule: when Current Positions is None, the agent MUST open a long this cycle (size 40-60% probing if technicals are mixed, 80-100% on a confirmed breakout). This is the "be in the market, not on the sidelines" stance the quick-trade flow needed; wait/hold are reserved for when a position already exists. - kernel/engine_position.go + trader/auto_trader_risk.go + agent/trade.go: Hyperliquid XYZ assets now use the BTC/ETH higher tier rather than the altcoin tier in all three position-value enforcement points. A shared isMajorAsset / isMajorTradeSymbol helper treats BTC/ETH crypto perps AND any IsXyzDexAsset symbol as the higher tier. With 5x equity cap, the AI's confident-open decisions on US stocks now pass validation instead of erroring out with "altcoin single coin position value cannot exceed 112 USDT". Net result: on a flat US-stock single-symbol trader, the agent opens a sized position with stop-loss and take-profit on the very first flat cycle, manages it (trail / partial / cut), and reports honestly to the user. The "agent does nothing" complaint is closed.
This commit is contained in:
@@ -3,6 +3,7 @@ package kernel
|
||||
import (
|
||||
"fmt"
|
||||
"nofx/logger"
|
||||
"nofx/market"
|
||||
)
|
||||
|
||||
// ============================================================================
|
||||
@@ -33,10 +34,18 @@ func validateDecision(d *Decision, accountEquity float64, btcEthLeverage, altcoi
|
||||
}
|
||||
|
||||
if d.Action == "open_long" || d.Action == "open_short" {
|
||||
// Asset tiering for validation:
|
||||
// - BTC/ETH crypto perps use the BTC/ETH tier (typically 5x equity).
|
||||
// - Hyperliquid XYZ assets (US equities, commodities, forex) are
|
||||
// also treated as the higher tier — they are not crypto altcoins
|
||||
// and the user's quick-trade flow shows them at the higher cap,
|
||||
// so the validator must match.
|
||||
// - Everything else is altcoin (1x equity by default).
|
||||
maxLeverage := altcoinLeverage
|
||||
posRatio := altcoinPosRatio
|
||||
maxPositionValue := accountEquity * posRatio
|
||||
if d.Symbol == "BTCUSDT" || d.Symbol == "ETHUSDT" {
|
||||
isMajor := d.Symbol == "BTCUSDT" || d.Symbol == "ETHUSDT" || market.IsXyzDexAsset(d.Symbol)
|
||||
if isMajor {
|
||||
maxLeverage = btcEthLeverage
|
||||
posRatio = btcEthPosRatio
|
||||
maxPositionValue = accountEquity * posRatio
|
||||
@@ -69,9 +78,12 @@ func validateDecision(d *Decision, accountEquity float64, btcEthLeverage, altcoi
|
||||
|
||||
tolerance := maxPositionValue * 0.01
|
||||
if d.PositionSizeUSD > maxPositionValue+tolerance {
|
||||
if d.Symbol == "BTCUSDT" || d.Symbol == "ETHUSDT" {
|
||||
switch {
|
||||
case d.Symbol == "BTCUSDT" || d.Symbol == "ETHUSDT":
|
||||
return fmt.Errorf("BTC/ETH single coin position value cannot exceed %.0f USDT (%.1fx account equity), actual: %.0f", maxPositionValue, posRatio, d.PositionSizeUSD)
|
||||
} else {
|
||||
case market.IsXyzDexAsset(d.Symbol):
|
||||
return fmt.Errorf("%s position value cannot exceed %.0f USDT (%.1fx account equity), actual: %.0f", d.Symbol, maxPositionValue, posRatio, d.PositionSizeUSD)
|
||||
default:
|
||||
return fmt.Errorf("altcoin single coin position value cannot exceed %.0f USDT (%.1fx account equity), actual: %.0f", maxPositionValue, posRatio, d.PositionSizeUSD)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user