Commit Graph

8 Commits

Author SHA1 Message Date
shinchan-zhai
cd6fe62e16 feat(agent): add market hours check for stock trades
- execute_trade: warn user when US market is closed (order queued for next open)
- get_market_price: include market_open/market_status for stock quotes
- Uses Alpaca's /v2/clock endpoint via IsMarketOpen() interface
- Prevents surprise queued orders during off-hours
2026-03-25 01:05:54 +08:00
shinchan-zhai
06824915a4 fix: isStockSymbol misclassifies crypto symbols (BTC/ETH/SOL) as stock tickers
Critical bug: isStockSymbol('BTC') returned true because 'BTC' is 3
uppercase letters and the suffix check only catches 'BTCUSDT'-style pairs.
This caused crypto trade commands to be routed to Alpaca (stock trader)
instead of crypto exchanges.

Fix: add knownCryptoSymbols map with 60+ common crypto base symbols.
Check this map first before the heuristic letter-count check.

Also includes:
- Unit tests for isStockSymbol (crypto vs stock classification)
- Alpaca support in handleSyncBalance/handleClosePosition API handlers
- Cancel orphaned SL/TP orders before manual position close
- Clear peak PnL cache on position close (prevent stale data)
- Lighter FormatQuantity uses actual market precision instead of hardcoded 4
2026-03-25 01:05:54 +08:00
shinchan-zhai
33b725ca14 fix: Alpaca integration bugs — field mapping, market hours, stock symbol handling
- Fix critical bug: Alpaca GetBalance returns wrong field names (total_equity
  vs totalEquity) — auto_trader was getting 0 equity, breaking all decisions
- Fix critical bug: Alpaca GetPositions missing positionAmt/unRealizedProfit
  fields — positions invisible to trading AI
- Fix CancelAllOrders: was nuking ALL orders globally, now filters by symbol
- Implement GetClosedPnL: was returning nil, now returns filled sell orders
- Add IsMarketOpen: checks Alpaca clock endpoint for market hours
- Add market hours check in trading loop: skip cycles when US market closed
  (saves LLM tokens and prevents failed orders)
- Fix parseTradeCommand: 'BUY AAPL 10' no longer becomes 'AAPLUSDT'
- Fix toolGetMarketPrice: route stock symbols to Alpaca, crypto to others
- Add exchange field to toolGetPositions output for multi-exchange clarity
2026-03-25 01:05:54 +08:00
shinchan-zhai
7e77b92fd0 feat: Alpaca US stock trader integration (Tasks 8-11)
- trader/alpaca/: Full Trader interface implementation for Alpaca
  - Paper/Live trading support (market orders, stop/limit)
  - GetBalance, GetPositions, GetMarketPrice via Alpaca API
  - Fractional share support (4 decimal places)
  - Commission-free trading

- Agent trade routing: stock symbols (AAPL, TSLA) → Alpaca
  - isStockSymbol() heuristic to distinguish crypto vs stock
  - execute_trade tool updated for stock buy/sell semantics
  - get_market_price works for both crypto and stocks

- TraderManager + API: Alpaca registered as exchange type
  - Factory case in auto_trader.go
  - Config mapping in trader_manager.go
  - Temp trader creation in handler_trader.go for balance query

- Frontend: PositionsPanel distinguishes stock vs crypto
  - US flag emoji for stock positions
  - Dollar prefix for stock PnL/prices
  - 'Shares' label instead of 'Qty' for stocks

- System prompts updated for stock trading capabilities
2026-03-25 01:05:54 +08:00
shinchan-zhai
c014724896 fix: context propagation in LLM calls, SSE error handling, security hardening
- Propagate request context through MCP client (Request.Ctx field)
  — Client disconnects now cancel in-flight LLM API calls (both streaming and non-streaming)
  — Prevents wasted LLM tokens when user navigates away mid-response
- proxyBinance: use http.NewRequestWithContext for context-aware upstream calls
  — Client disconnects cancel Binance proxy requests
  — Distinguishes client cancellation from upstream failures
- Fix SSE parse bug in AgentChatPage: catch block was swallowing error events
  — throw new Error(data) for 'error' events was caught by the same try/catch
  — Now parse JSON separately, then handle events outside try/catch
- Add io.LimitReader to Hyperliquid coins.go JSON decoder (4MB limit)
- Use safe.ReadAllLimited in batch ticker handler for consistency
- Sanitize URL validation error in handler_ai_model.go (was leaking raw error)
- Cache agent tool definitions (built once, reused per message)
- Sort trade history by exit time for consistent ordering
2026-03-25 01:05:54 +08:00
shinchan-zhai
8a7ac8719a feat: dynamic crypto detection, trade history tool, fix 9 ticker leaks
- Agent gatherContext: expand from 10 hardcoded symbols to 38+ known symbols
  plus dynamic XXXUSDT pattern extraction (caps at 5 to avoid slow context)
- Add get_trade_history tool: LLM can now query closed trades with PnL summary
  (win rate, total PnL, recent N trades across all traders)
- Fix ticker.Stop() leak in ALL 9 exchange order_sync goroutines:
  OKX, Hyperliquid, Aster, Bybit, KuCoin, Gate, Bitget, Lighter, Binance
  — tickers were never stopped when traders were stopped, leaking goroutines
2026-03-25 01:05:54 +08:00
shinchan-zhai
5676ba2e5c feat: dynamic stock search via Sina suggest API
- Add searchStock() using Sina's suggest API (type=11,31,41)
- Supports A-share, HK, and US markets dynamically
- No longer limited to hardcoded knownStocks map
- resolveStockCodeDynamic: tries static map first, then API fallback
- extractStockKeyword: smart keyword extraction from natural language
- New LLM tool 'search_stock': agent can proactively search stocks
- Top 3 search results auto-enriched with real-time quotes
- System prompts updated for both zh/en
2026-03-25 01:05:54 +08:00
shinchan-zhai
0fa8c48b84 feat(agent): LLM tool-calling for auto trade execution
- New agent/tools.go: defines LLM tools (execute_trade, get_positions,
  get_balance, get_market_price)
- thinkAndAct now uses CallWithRequestFull with tool-calling loop
  (max 5 rounds) — LLM autonomously decides when to call tools
- Trade safety: execute_trade creates pending orders requiring user
  confirmation ('确认 trade_xxx' / 'confirm trade_xxx')
- Pending trades expire after 5 minutes
- System prompt updated with tool usage instructions and safety rules
- Both paths work: regex shortcut ('做多 BTC 0.01') and natural
  language ('帮我开一个BTC多单') via LLM tool calling
- Fallback: if tool-calling fails, degrades to plain LLM call
2026-03-25 01:05:54 +08:00