Commit Graph

508 Commits

Author SHA1 Message Date
ZhouYongyou
94b2b9c296 fix: 統一 handleTraderList 返回完整 AI model ID(保持與 handleGetTraderConfig 一致)
問題:
- handleTraderList 仍在截斷 AI model ID (admin_deepseek → deepseek)
- 與 handleGetTraderConfig 返回的完整 ID 不一致
- 導致前端 isModelInUse 檢查失效

修復:
- 移除 handleTraderList 中的截斷邏輯
- 返回完整 AIModelID (admin_deepseek)
- 與其他 API 端點保持一致

測試:
- GET /api/traders → ai_model: admin_deepseek ✓
- GET /api/traders/:id → ai_model: admin_deepseek ✓
- 模型使用檢查邏輯正確 ✓
2025-11-04 17:35:34 +08:00
ZhouYongyou
8d796357b2 fix: 修復初始余額顯示錯誤(使用當前淨值而非配置值)
問題:
- 圖表顯示「初始余額 693.15 USDT」(實際應該是 600)
- 原因:使用 validHistory[0].total_equity(當前淨值)
- 導致初始余額隨著盈虧變化,數學邏輯錯誤

修復:
- 優先從 account.initial_balance 讀取真實配置值
- 備選方案:從歷史數據反推(淨值 - 盈虧)
- 默認值使用 1000(與創建交易員時的默認配置一致)

測試:
- 初始余額:600 USDT(固定)
- 當前淨值:693.15 USDT
- 盈虧:+93.15 USDT (+15.52%) ✓
2025-11-04 17:35:26 +08:00
ZhouYongyou
a59f4951e8 fix: 修復首次運行時數據庫初始化失敗問題
問題:
- 用戶首次運行報錯:unable to open database file: is a directory
- 原因:Docker volume 掛載時,如果 config.db 不存在,會創建目錄而非文件
- 影響:新用戶無法正常啟動系統

修復:
- 在 start.sh 啟動前檢查 config.db 是否存在
- 如不存在則創建空文件(touch config.db)
- 確保 Docker 掛載為文件而非目錄

測試:
- 首次運行:./start.sh start → 正常初始化 ✓
- 現有用戶:無影響,向後兼容 ✓
2025-11-04 17:35:26 +08:00
ZhouYongyou
7c87fa27e6 fix: 添加 HTTP/2 stream error 到可重試錯誤列表
問題:
- 用戶遇到錯誤:stream error: stream ID 1; INTERNAL_ERROR
- 這是 HTTP/2 連接被服務端關閉的錯誤
- 當前重試機制不包含此類錯誤,導致直接失敗

修復:
- 添加 "stream error" 到可重試列表
- 添加 "INTERNAL_ERROR" 到可重試列表
- 遇到此類錯誤時會自動重試(最多 3 次)

影響:
- 提高 API 調用穩定性
- 自動處理服務端臨時故障
- 減少因網絡波動導致的失敗
2025-11-04 17:35:26 +08:00
ZhouYongyou
8bff23e807 fix: 过滤幽灵持仓 - 跳过 quantity=0 的持仓防止 AI 误判
问题:
- 止损/止盈触发后,交易所返回 positionAmt=0 的持仓记录
- 这些幽灵持仓被传递给 AI,导致 AI 误以为仍持有该币种
- AI 可能基于错误信息做出决策(如尝试调整已不存在的止损)

修复:
- buildTradingContext() 中添加 quantity==0 检查
- 跳过已平仓的持仓,确保只传递真实持仓给 AI
- 触发清理逻辑:撤销孤儿订单、清理内部状态

影响范围:
- trader/auto_trader.go:487-490

测试:
- 编译成功
- 容器重建并启动正常
2025-11-04 17:35:19 +08:00
ZhouYongyou
6d53e9260f feat(decision): make OI threshold configurable + add relaxed prompt template
## Changes

### 1. decision/engine.go - Configurable OI Threshold
- Extract hardcoded 15M OI threshold to configurable constant
- Add clear documentation for risk profiles:
  - 15M (Conservative) - BTC/ETH/SOL only
  - 10M (Balanced) - Add major alt-coins
  - 8M (Relaxed) - Include mid-cap coins (BNB/LINK/AVAX)
  - 5M (Aggressive) - Most alt-coins allowed
- Default: 15M (保守,維持原行為)

### 2. prompts/adaptive_relaxed.txt - New Trading Template
Conservative optimization for increased trading frequency while maintaining high win-rate:

**Key Adjustments:**
- Confidence threshold: 85 → 80 (allow more opportunities)
- Cooldown period: 9min → 6min (faster reaction)
- Multi-timeframe trend: 3 periods → 2 periods (relaxed requirement)
- Entry checklist: 5/8 → 4/8 (easier to pass)
- RSI range: 30-40/65-70 → <45/>60 (wider acceptance)
- Risk-reward ratio: 1:3 → 1:2.5 (more flexible)

**Expected Impact:**
- Trading frequency: 5/day → 8-15/day (+60-200%)
- Win-rate: 40% → 50-55% (improved)
- Alt-coins: More opportunities unlocked
- Risk controls: Preserved (Sharpe-based, loss-pause)

## Usage
Users can now choose trading style via Web UI:
- `adaptive` - Strictest (original)
- `adaptive_relaxed` - Balanced (this PR)
- `nof1` - Most aggressive

## Rationale
The original adaptive.txt uses 5-layer filtering (confidence/cooldown/trend/checklist/RSI)
that filters out ~95% of opportunities. This template provides a middle-ground option
for users who want higher frequency without sacrificing core risk management.

Related: #trading-frequency #alt-coin-support
2025-11-04 17:22:14 +08:00
ZhouYongyou
b7210029d1 fix(market): resolve price staleness issue in GetCurrentKlines
## Problem
GetCurrentKlines had two critical bugs causing price data to become stale:
1. Incorrect return logic: returned error even when data fetch succeeded
2. Race condition: returned slice reference instead of deep copy, causing concurrent data corruption

## Impact
- BTC price stuck at 106xxx while actual market price was 107xxx+
- LLM calculated take-profit based on stale prices → orders failed validation
- Statistics showed incorrect P&L (0.00%) due to corrupted historical data
- Alt-coins filtered out due to failed market data fetch

## Solution
1. Fixed return logic: only return error when actual failure occurs
2. Return deep copy instead of reference to prevent race conditions
3. Downgrade subscription errors to warnings (non-blocking)

## Test Results
 Price updates in real-time
 Take-profit orders execute successfully
 P&L calculations accurate
 Alt-coins now tradeable

Related: Price feed mechanism, concurrent data access
2025-11-04 17:21:47 +08:00
ZhouYongyou
44e80df22c refactor(prompts): add comprehensive partial_close guidance to adaptive.txt
Add detailed guidance chapter for dynamic TP/SL management and partial close operations.

## Changes

- New chapter: "动态止盈止损与部分平仓指引" (Dynamic TP/SL & Partial Close Guidance)
- Inserted between "可用动作" (Actions) and "决策流程" (Decision Flow) sections
- 4 key guidance points covering:
  1. Partial close best practices (use clear percentages like 25%/50%/75%)
  2. Reassessing remaining position after partial exit
  3. Proper use cases for update_stop_loss / update_take_profit
  4. Multi-stage exit strategy requirements

## Benefits

-  Provides concrete operational guidelines for AI decision-making
-  Clarifies when and how to use partial_close effectively
-  Emphasizes remaining position management (prevents "orphan" positions)
-  Aligns with existing backend support for partial_close action

## Background

While adaptive.txt already lists partial_close as an available action,
it lacked detailed operational guidance. This enhancement fills that gap
by providing specific percentages, use cases, and multi-stage exit examples.

Backend (decision/engine.go) already validates partial_close with
close_percentage field, so this is purely a prompt enhancement with
no code changes required.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 17:20:57 +08:00
ZhouYongyou
e88f756c7e 更新 logger:支持新增的三個動作類型
更新內容:
1. DecisionAction 註釋:添加 update_stop_loss, update_take_profit, partial_close
2. GetStatistics:partial_close 計入 TotalClosePositions
3. AnalyzePerformance 預填充邏輯:處理 partial_close(不刪除持倉記錄)
4. AnalyzePerformance 分析邏輯:
   - partial_close 正確判斷持倉方向
   - 記錄部分平倉的盈虧統計
   - 保留持倉記錄(因為還有剩餘倉位)

說明:partial_close 會記錄盈虧,但不刪除 openPositions,
      因為還有剩餘倉位可能繼續交易
2025-11-04 17:19:58 +08:00
ZhouYongyou
a486859c1c fix: remove unnecessary prompts/adaptive.txt changes
- This PR should only contain backend core functionality
- prompts/adaptive.txt v2.0 is already in upstream
- Prompt enhancements will be in separate PR (Batch 3)
2025-11-04 16:58:28 +08:00
ZhouYongyou
11d2a06d5e fix: 修復 Hyperliquid CancelStopOrders 編譯錯誤
- OpenOrder 結構不暴露 trigger 字段
- 改為取消該幣種的所有掛單(安全做法)
2025-11-04 16:45:20 +08:00
ZhouYongyou
dc56ecccdb fix: 修复部分平仓盈利计算错误
问题:部分平仓时,历史记录显示的是全仓位盈利,而非实际平仓部分的盈利

根本原因:
- AnalyzePerformance 使用开仓总数量计算部分平仓的盈利
- 应该使用 action.Quantity(实际平仓数量)而非 openPos["quantity"](总数量)

修复:
- 添加 actualQuantity 变量区分完整平仓和部分平仓
- partial_close 使用 action.Quantity
- 所有相关计算(PnL、PositionValue、MarginUsed)都使用 actualQuantity

影响范围:logger/decision_logger.go:428-465

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 16:40:28 +08:00
ZhouYongyou
519c107781 修復關鍵缺陷:添加 CancelStopOrders 方法避免多個止損單共存
問題:
- 調整止損/止盈時,直接調用 SetStopLoss/SetTakeProfit 會創建新訂單
- 但舊的止損/止盈單仍然存在,導致多個訂單共存
- 可能造成意外觸發或訂單衝突

解決方案(參考 PR #197):
1. 在 Trader 接口添加 CancelStopOrders 方法
2. 為三個交易所實現:
   - binance_futures.go: 過濾 STOP_MARKET/TAKE_PROFIT_MARKET 類型
   - aster_trader.go: 同樣邏輯
   - hyperliquid_trader.go: 過濾 trigger 訂單(有 triggerPx)
3. 在 executeUpdateStopLossWithRecord 和 executeUpdateTakeProfitWithRecord 中:
   - 先調用 CancelStopOrders 取消舊單
   - 然後設置新止損/止盈
   - 取消失敗不中斷執行(記錄警告)

優勢:
-  避免多個止損單同時存在
-  保留我們的價格驗證邏輯
-  保留執行價格記錄
-  詳細錯誤信息
-  取消失敗時繼續執行(更健壯)

測試建議:
- 開倉後調整止損,檢查舊止損單是否被取消
- 連續調整兩次,確認只有最新止損單存在

致謝:參考 PR #197 的實現思路
2025-11-04 16:40:23 +08:00
ZhouYongyou
91d6de2f2e 修復關鍵 BUG:validActions 缺少新動作導致驗證失敗
問題根因:
- auto_trader.go 已實現 update_stop_loss/update_take_profit/partial_close 處理
- adaptive.txt 已描述這些功能
- 但 validateDecision 的 validActions map 缺少這三個動作
- 導致 AI 生成的決策在驗證階段被拒絕:「无效的action:update_stop_loss」

修復內容:
1. validActions 添加三個新動作
2. 為每個新動作添加參數驗證:
   - update_stop_loss: 驗證 NewStopLoss > 0
   - update_take_profit: 驗證 NewTakeProfit > 0
   - partial_close: 驗證 ClosePercentage 在 0-100 之間
3. 修正註釋:adjust_* → update_*

測試狀態:feature 分支,等待測試確認
2025-11-04 16:40:18 +08:00
ZhouYongyou
622c860cd9 feat: 添加部分平仓和动态止盈止损功能
新增功能:
- update_stop_loss: 调整止损价格(追踪止损)
- update_take_profit: 调整止盈价格(技术位优化)
- partial_close: 部分平仓(分批止盈)

实现细节:
- Decision struct 新增字段:NewStopLoss, NewTakeProfit, ClosePercentage
- 新增执行函数:executeUpdateStopLossWithRecord, executeUpdateTakeProfitWithRecord, executePartialCloseWithRecord
- 修复持仓字段获取 bug(使用 "side" 并转大写)
- 更新 adaptive.txt 文档,包含详细使用示例和策略建议
- 优先级排序:平仓 > 调整止盈止损 > 开仓

命名统一:
- 与社区 PR #197 保持一致,使用 update_* 而非 adjust_*
- 独有功能:partial_close(部分平仓)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 16:40:12 +08:00
ZhouYongyou
856a9c407e fix(api): correct variable name from traderRecord to trader
Fixed compilation error caused by variable name mismatch:
- Line 404: defined as 'trader'
- Line 425: was using 'traderRecord' (undefined)

This aligns with upstream dev branch naming convention.
2025-11-04 16:28:43 +08:00
ZhouYongyou
2b9c4d2d6b fix(api): query actual exchange balance when creating trader
Problem:
- Users could input arbitrary initial balance when creating traders
- This didn't reflect the actual available balance in exchange account
- Could lead to incorrect position sizing and risk calculations

Solution:
- Before creating trader, query exchange API for actual balance
- Use GetBalance() from respective trader implementation:
  * Binance: NewFuturesTrader + GetBalance()
  * Hyperliquid: NewHyperliquidTrader + GetBalance()
  * Aster: NewAsterTrader + GetBalance()
- Extract 'available_balance' or 'balance' from response
- Override user input with actual balance
- Fallback to user input if query fails

Changes:
- Added 'nofx/trader' import
- Query GetExchanges() to find matching exchange config
- Create temporary trader instance based on exchange type
- Call GetBalance() to fetch actual available balance
- Use actualBalance instead of req.InitialBalance
- Comprehensive error handling with fallback logic

Benefits:
-  Ensures accurate initial balance matches exchange account
-  Prevents user errors in balance input
-  Improves position sizing accuracy
-  Maintains data integrity between system and exchange

Example logs:
✓ 查询到交易所实际余额: 150.00 USDT (用户输入: 100.00 USDT)
⚠️ 查询交易所余额失败,使用用户输入的初始资金: connection timeout

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 16:28:38 +08:00
tinkle-community
5649cb7496 Merge pull request #404 from 0xEmberZz/feature/binance-guide
feat: Add Binance setup guide with tutorial modal
2025-11-04 15:35:19 +08:00
Ember
0756c6d6f2 feat: Add Binance setup guide with tutorial modal
- Add Binance configuration tutorial image (guide.png)
- Implement "View Guide" button in exchange configuration modal
- Add tutorial display modal with image viewer
- Add i18n support for guide-related text (EN/ZH)
- Button only appears when configuring Binance exchange

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 14:50:38 +08:00
tangmengqiu
f4351627bb fix print 2025-11-04 00:29:37 -05:00
tangmengqiu
ecda116a89 fix go vet check 2025-11-04 00:24:34 -05:00
tangmengqiu
2fec4ca347 fix pk prefix handle 2025-11-04 00:03:56 -05:00
tangmengqiu
3ca9669cfc fix 2025-11-03 23:43:06 -05:00
tangmengqiu
eea26d755d feat(hyperliquid): Auto-generate wallet address from private key
Enable automatic wallet address generation from private key for Hyperliquid
exchange, simplifying user onboarding and reducing configuration errors.

Backend Changes (trader/hyperliquid_trader.go):
- Import crypto/ecdsa package for ECDSA public key operations
- Enable wallet address auto-generation when walletAddr is empty
- Use crypto.PubkeyToAddress() to derive address from private key
- Add logging for both auto-generated and manually provided addresses

Frontend Changes (web/src/components/AITradersPage.tsx):
- Remove wallet address required validation (only private key required)
- Update button disabled state to only check private key
- Add "Optional" label to wallet address field
- Add dynamic placeholder with bilingual hint
- Show context-aware helper text based on input state
- Remove HTML required attribute from input field

Translation Updates (web/src/i18n/translations.ts):
- Add 'optional' translation (EN: "Optional", ZH: "可选")
- Add 'hyperliquidWalletAddressAutoGenerate' translation
  EN: "Leave blank to automatically generate wallet address from private key"
  ZH: "留空将自动从私钥生成钱包地址"

Benefits:
 Simplified UX - Users only need to provide private key
 Error prevention - Auto-generated address always matches private key
 Backward compatible - Manual address input still supported
 Better UX - Clear visual indicators for optional fields

Technical Details:
- Uses Ethereum standard ECDSA public key to address conversion
- Implementation was already present but commented out (lines 37-43)
- No database schema changes required (hyperliquid_wallet_addr already nullable)
- Fallback behavior: manual input > auto-generation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 23:15:38 -05:00
SkywalkerJi
cc728b5fb4 fix the main branch history issue from November 3rd.
Merge pull request #395 from NoFxAiOS/beta
fix:fix the main branch history issue from November 3rd.
2025-11-04 13:00:05 +09:00
tinkle-community
ff4cd0e3ca Merge pull request #389 from NoFxAiOS/beta
Fix:fix the main branch history issue from November 3rd.
2025-11-04 11:22:10 +08:00
Shui
b6b956de8e Merge pull request #354 from zhouyongyou/fix/trader-config-missing-fields
fix(database): GetTraderConfig missing critical fields causes edit to fail
2025-11-03 21:57:48 -05:00
Shui
0791d6733d Merge pull request #373 from hzb1115/dev
fix(readme): update readme and pr reviewer
2025-11-03 21:07:31 -05:00
zbhan
4dcaee0477 Fix owner 2025-11-03 21:06:25 -05:00
zbhan
703aa8effa fix owner 2025-11-03 20:56:16 -05:00
zbhan
d17035dde3 fix(readme): update readme and pr reviewer 2025-11-03 20:50:56 -05:00
Luna Martinez
7ec49b0ebe Merge pull request #362 from hzb1115/dev
Fix(workflow): add title and size validation comments
2025-11-03 13:20:02 -05:00
Luna Martinez
b2df15be3f Merge branch 'NoFxAiOS:dev' into dev 2025-11-03 13:16:11 -05:00
Icyoung
045535c8cc Merge pull request #361 from Icyoung/beta
Beta bugfix
2025-11-04 02:14:54 +08:00
zbhan
09b54b8c3b Fix PR check 2025-11-03 13:12:47 -05:00
icy
793a064a27 Add NOFX watermarks to charts and fix empty state internationalization
- Add NOFX watermark to ComparisonChart (competition page)
- Add NOFX watermark to EquityChart (dashboard page)
- Fix empty state handling and internationalization in CompetitionPage

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 02:08:38 +08:00
icy
d8f325dc36 Fix ComparisonChart data display issue
The chart was not showing data because the API response format changed.
Fixed the calculation of PnL percentage by computing it from total_pnl
and balance values (initial_balance = balance - total_pnl).

Now the AI competition chart should properly display performance comparison data.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 01:54:21 +08:00
Icyoung
88d46b1dde Merge pull request #359 from Icyoung/beta
Beta Merge dev、Bug fix
2025-11-04 01:50:34 +08:00
icy
6eecd8b33a Merge branch 'dev' into beta 2025-11-04 01:45:21 +08:00
icy
4869c2bd28 Merge branch 'dev' of https://github.com/tinkle-community/nofx into dev 2025-11-04 01:45:15 +08:00
icy
5507ae7b13 Remove all test dependencies and configurations
- Removed test script from package.json
- Removed testing dependencies (@testing-library/react, vitest, jsdom)
- Deleted test directory and vitest.config.ts
- Updated package-lock.json to reflect changes
- Build still works perfectly without test dependencies

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 01:44:40 +08:00
icy
e25f04c642 Remove unused test files
Removed App.test.tsx and AITradersPage.test.tsx that were causing TypeScript build issues and are not currently in use.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 01:43:02 +08:00
Luna Martinez
4166776fdf Merge pull request #323 from zhouyongyou/fix/go-vet-warnings
fix: resolve go vet warnings for non-constant format strings
2025-11-03 12:42:46 -05:00
icy
8ca6f68867 Fix TypeScript build error
Removed unused 'Zap' import from App.tsx that was causing build failure.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 01:42:25 +08:00
Luna Martinez
9f03266fed Merge pull request #329 from zhouyongyou/chore/peer-dependency-markers
chore(web): add peer dependency markers to package-lock.json
2025-11-03 12:39:24 -05:00
icy
364c6081af Resolve merge conflicts with dev branch
Resolved conflicts in:
- api/server.go: Preserved beta_mode config and user permission checks
- manager/trader_manager.go: Kept optimized concurrent competition data with caching

Maintained all performance optimizations while merging new features from dev.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 01:36:54 +08:00
icy
71637268fd Merge branch 'dev' of https://github.com/tinkle-community/nofx into dev
# Conflicts:
#	api/server.go
2025-11-04 01:34:14 +08:00
icy
3af2dd41fb Fix: Add proper top padding to prevent HeaderBar overlap on all main app pages
Match main app layout with proven working /competition route layout:
- Use px-6 py-6 pt-24 padding (same as /competition route)
- Ensures HeaderBar doesn't overlap content on /traders and /dashboard pages
- Provides consistent 6rem (96px) top clearance for fixed positioned HeaderBar
- Removes responsive padding variants that differed from competition page

This fixes header overlap issues across all main application routes.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 01:29:39 +08:00
hzb1115
1b654cf9d2 style(backend): go fmt code 2025-11-03 17:22:11 +00:00
Luna Martinez
04f3a20af9 Merge pull request #356 from xqliu/revert-pr-229-ut-infrastructure
Revert PR #229: Remove UT infrastructure
2025-11-03 12:13:16 -05:00