-
Notifications
You must be signed in to change notification settings - Fork 2.2k
fix: 动态调整最小开仓金额以支持小账户 #907
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
Beta Merge dev、Bug fix
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>
- 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>
Beta bugfix
Fix(workflow): add title and size validation comments
fix(readme): update readme and pr reviewer
…ssing-fields fix(database): GetTraderConfig missing critical fields causes edit to fail
Fix:fix the main branch history issue from November 3rd.
Merge pull request NoFxAiOS#395 from NoFxAiOS/beta fix:fix the main branch history issue from November 3rd.
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>
- 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>
feat: Add Binance setup guide with tutorial modal
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>
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.
新增功能: - update_stop_loss: 调整止损价格(追踪止损) - update_take_profit: 调整止盈价格(技术位优化) - partial_close: 部分平仓(分批止盈) 实现细节: - Decision struct 新增字段:NewStopLoss, NewTakeProfit, ClosePercentage - 新增执行函数:executeUpdateStopLossWithRecord, executeUpdateTakeProfitWithRecord, executePartialCloseWithRecord - 修复持仓字段获取 bug(使用 "side" 并转大写) - 更新 adaptive.txt 文档,包含详细使用示例和策略建议 - 优先级排序:平仓 > 调整止盈止损 > 开仓 命名统一: - 与社区 PR NoFxAiOS#197 保持一致,使用 update_* 而非 adjust_* - 独有功能:partial_close(部分平仓) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
問題根因: - 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 分支,等待測試確認
問題: - 調整止損/止盈時,直接調用 SetStopLoss/SetTakeProfit 會創建新訂單 - 但舊的止損/止盈單仍然存在,導致多個訂單共存 - 可能造成意外觸發或訂單衝突 解決方案(參考 PR NoFxAiOS#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 NoFxAiOS#197 的實現思路
问题:部分平仓时,历史记录显示的是全仓位盈利,而非实际平仓部分的盈利 根本原因: - 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>
- OpenOrder 結構不暴露 trigger 字段 - 改為取消該幣種的所有掛單(安全做法)
…rliquid) (NoFxAiOS#921) * fix(ui): remove duplicate Aster exchange form rendering 修復 Aster 交易所配置表單重複渲染問題。 Issue: - Aster 表單代碼在 AITradersPage.tsx 中出現兩次(lines 2334 和 2559) - 導致用戶界面顯示 6 個輸入欄位(應該是 3 個) - 用戶體驗混亂 Fix: - 刪除重複的 Aster 表單代碼塊(lines 2559-2710,共 153 行) - 保留第一個表單塊(lines 2334-2419) - 修復 prettier 格式問題 Result: - Aster 配置現在正確顯示 3 個欄位:user, signer, private key - Lint 檢查通過 - Hyperliquid Agent Wallet 翻譯已存在無需修改 Technical: - 刪除了完全重複的 JSX 條件渲染塊 - 移除空白行以符合 prettier 規範 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix(ui): remove legacy Hyperliquid single private key field 修復 Hyperliquid 配置頁面顯示舊版私鑰欄位的問題。 Issue: - Hyperliquid 配置同時顯示舊版和新版欄位 - 舊版:單一「私钥」欄位(不安全,已廢棄) - 新版:「代理私钥」+「主钱包地址」(Agent Wallet 安全模式) - 用戶看到重複的欄位配置,造成混淆 Root Cause: - AITradersPage.tsx 存在兩個 Hyperliquid 條件渲染塊 - Lines 2302-2332: 舊版單私鑰模式(應刪除) - Lines 2424-2557: 新版 Agent Wallet 模式(正確) Fix: - 刪除舊版 Hyperliquid 單私鑰欄位代碼塊(lines 2302-2332,共 32 行) - 保留新版 Agent Wallet 配置(代理私鑰 + 主錢包地址) - 移除 `t('privateKey')` 和 `t('hyperliquidPrivateKeyDesc')` 舊版翻譯引用 Result: - Hyperliquid 配置現在只顯示正確的 Agent Wallet 欄位 - 安全提示 banner 正確顯示 - 用戶體驗改善,不再混淆 Technical Details: - 新版使用 `apiKey` 儲存 Agent Private Key - 新版使用 `hyperliquidWalletAddr` 儲存 Main Wallet Address - 符合 Hyperliquid Agent Wallet 最佳安全實踐 Related: - 之前已修復 Aster 重複渲染問題(commit 5462eba) - Hyperliquid 翻譯 key 已存在於 translations.ts (lines 206-216, 1017-1027) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix(i18n): add missing Hyperliquid Agent Wallet translation keys 補充 Hyperliquid 代理錢包配置的翻譯文本,修復前端顯示 key 名稱的問題。 Changes: - 新增 8 個英文翻譯 key (Agent Wallet 配置說明) - 新增 8 個中文翻譯 key (代理錢包配置說明) - 修正 Hyperliquid 配置頁面顯示問題(從顯示 key 名稱改為顯示翻譯文本) Technical Details: - hyperliquidAgentWalletTitle: Banner 標題 - hyperliquidAgentWalletDesc: 安全說明文字 - hyperliquidAgentPrivateKey: 代理私鑰欄位標籤 - hyperliquidMainWalletAddress: 主錢包地址欄位標籤 - 相應的 placeholder 和 description 文本 Related Issue: 用戶反饋前端顯示 key 名稱而非翻譯文本 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: the-dev-z <the-dev-z@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
… request (NoFxAiOS#922) * fix(web): restore missing system_prompt_template in handleSaveEditTrader 修復編輯交易員時策略模板無法保存的問題。 Issue: - 用戶編輯交易員時,選擇的策略模板(system_prompt_template)沒有被保存 - 重新打開編輯窗口,總是顯示默認值 - 用戶困惑為什麼策略模板無法持久化 Root Cause: - PR NoFxAiOS#872 在 UI 重構時遺漏了 system_prompt_template 字段 - handleSaveEditTrader 的 request 對象缺少 system_prompt_template - 導致更新請求不包含策略模板信息 Fix: - 在 handleSaveEditTrader 的 request 對象中添加 system_prompt_template 字段 - 位置:override_base_prompt 之後,is_cross_margin 之前 - 與後端 API 和 TraderConfigModal 保持一致 Result: - 編輯交易員時,策略模板正確保存 - 重新打開編輯窗口,顯示正確的已保存值 - 用戶可以成功切換和保存不同的策略模板 Technical Details: - web/src/types.ts TraderConfigData 接口已有 system_prompt_template ✓ - Backend handleUpdateTrader 接收並保存 SystemPromptTemplate ✓ - Frontend TraderConfigModal 表單提交包含 system_prompt_template ✓ - Frontend handleSaveEditTrader request 缺失此字段 ✗ → ✓ (已修復) Related: - PR NoFxAiOS#872: UI 重構時遺漏 - commit c1f080f: 原始添加 system_prompt_template 支持 - commit e58fc3c: 修復 types.ts 缺失字段 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix(types): add missing system_prompt_template field to TraderConfigData 補充完整修復:確保 TypeScript 類型定義與 API 使用一致。 Issue: - AITradersPage.tsx 提交時包含 system_prompt_template 字段 - 但 TraderConfigData 接口缺少此字段定義 - TypeScript 類型不匹配 Fix: - 在 TraderConfigData 接口添加 system_prompt_template: string - 位置:override_base_prompt 之後,is_cross_margin 之前 - 與 CreateTraderRequest 保持一致 Result: - TypeScript 類型完整 - 編輯交易員時正確加載和保存策略模板 - 無類型錯誤 Technical: - web/src/types.ts Line 200 - 與後端 SystemPromptTemplate 字段對應 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: the-dev-z <the-dev-z@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
…NoFxAiOS#918) ## Problem User-facing messages were too generic and uninformative: 1. **Dashboard empty state**: - Title: "No Traders Configured" (cold, technical) - Description: Generic message with no action guidance - Button: "Go to Traders Page" (unclear what happens next) 2. **Login error messages**: - "Login failed" (too vague - why did it fail?) - "Registration failed" (no guidance on what to do) - "OTP verification failed" (users don't know how to fix) **Impact**: Users felt confused and frustrated, no clear next steps. ## Solution ### 1. Improve Dashboard Empty State **File**: `web/src/i18n/translations.ts` **Before**: ```typescript dashboardEmptyTitle: 'No Traders Configured' dashboardEmptyDescription: "You haven't created any AI traders yet..." goToTradersPage: 'Go to Traders Page' ``` **After**: ```typescript dashboardEmptyTitle: "Let's Get Started!" // ✅ Welcoming, encouraging dashboardEmptyDescription: 'Create your first AI trader to automate your trading strategy. Connect an exchange, choose an AI model, and start trading in minutes!' // ✅ Clear steps goToTradersPage: 'Create Your First Trader' // ✅ Clear action ``` **Changes**: - ✅ More welcoming tone ("Let's Get Started!") - ✅ Specific action steps (connect → choose → trade) - ✅ Time expectation ("in minutes") - ✅ Clear call-to-action button --- ### 2. Improve Error Messages **File**: `web/src/i18n/translations.ts` **Before**: ```typescript loginFailed: 'Login failed' // ❌ No guidance registrationFailed: 'Registration failed' // ❌ No guidance verificationFailed: 'OTP verification failed' // ❌ No guidance ``` **After**: ```typescript loginFailed: 'Login failed. Please check your email and password.' // ✅ Clear hint registrationFailed: 'Registration failed. Please try again.' // ✅ Clear action verificationFailed: 'OTP verification failed. Please check the code and try again.' // ✅ Clear steps ``` **Changes**: - ✅ Specific error hints (check email/password) - ✅ Clear remediation steps (try again, check code) - ✅ User-friendly tone --- ### 3. Chinese Translations All improvements mirrored in Chinese: **Dashboard**: - Title: "开始使用吧!" (Let's get started!) - Description: Clear 3-step guidance - Button: "创建您的第一个交易员" (Create your first trader) **Errors**: - "登录失败,请检查您的邮箱和密码。" - "注册失败,请重试。" - "OTP 验证失败,请检查验证码后重试。" --- ## Impact ### User Experience Improvements | Message Type | Before | After | Benefit | |--------------|--------|-------|---------| | **Empty dashboard** | Cold, technical | Welcoming, actionable | ✅ Reduces confusion | | **Login errors** | Vague | Specific hints | ✅ Faster problem resolution | | **Registration errors** | No guidance | Clear next steps | ✅ Lower support burden | | **OTP errors** | Confusing | Actionable | ✅ Higher success rate | ### Tone Shift **Before**: Technical, system-centric - "No Traders Configured" - "Login failed" **After**: User-centric, helpful - "Let's Get Started!" - "Login failed. Please check your email and password." --- ## Testing **Manual Testing**: - [x] Empty dashboard displays new messages correctly - [x] Login error shows improved message - [x] Registration error shows improved message - [x] OTP error shows improved message - [x] Chinese translations display correctly - [x] Button text updated appropriately **Language Coverage**: - [x] English ✅ - [x] Chinese ✅ --- ## Files Changed **1 frontend file**: - `web/src/i18n/translations.ts` (+12 lines, -6 lines) **Lines affected**: - English: Lines 149-152, 461-464 - Chinese: Lines 950-953, 1227-1229 --- **By submitting this PR, I confirm:** - [x] I have read the Contributing Guidelines - [x] I agree to the Code of Conduct - [x] My contribution is licensed under AGPL-3.0 --- 🌟 **Thank you for reviewing!** This PR improves user experience with clearer, more helpful messages. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: the-dev-z <the-dev-z@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
* feat: add web crypto environment check * fix: auto check env * refactor: WebCryptoEnvironmentCheck swtich to map
* feat(market): add data staleness detection ## 問題背景 解決 PR NoFxAiOS#703 Part 2: 數據陳舊性檢測 - 修復 DOGEUSDT 式問題:連續價格不變表示數據源異常 - 防止系統處理僵化/過期的市場數據 ## 技術方案 ### 數據陳舊性檢測 (market/data.go) - **函數**: `isStaleData(klines []Kline, symbol string) bool` - **檢測邏輯**: - 連續 5 個 3 分鐘週期價格完全不變(15 分鐘無波動) - 價格波動容忍度:0.01%(避免誤報) - 成交量檢查:價格凍結 + 成交量為 0 → 確認陳舊 - **處理策略**: - 數據陳舊確認:跳過該幣種,返回錯誤 - 極低波動市場:記錄警告但允許通過(價格穩定但有成交量) ### 調用時機 - 在 `Get()` 函數中,獲取 3m K線後立即檢測 - 早期返回:避免後續無意義的計算和 API 調用 ## 實現細節 - **檢測閾值**: 5 個連續週期 - **容忍度**: 0.01% 價格波動 - **日誌**: 英文國際化版本 - **並發安全**: 函數無狀態,安全 ## 影響範圍 - ✅ 修改 market/data.go: 新增 isStaleData() + 調用邏輯 - ✅ 新增 log 包導入 - ✅ 50 行新增代碼 ## 測試建議 1. 模擬 DOGEUSDT 場景:連續價格不變 + 成交量為 0 2. 驗證日誌輸出:`stale data confirmed: price freeze + zero volume` 3. 正常市場:極低波動但有成交量,應允許通過並記錄警告 ## 相關 Issue/PR - 拆分自 **PR NoFxAiOS#703** (Part 2/3) - 基於最新 upstream/dev (3112250) - 依賴: 無 - 前置: Part 1 (OI 時間序列) - 已提交 PR NoFxAiOS#798 - 後續: Part 3 (手續費率傳遞) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * test(market): add comprehensive unit tests for isStaleData function - Test normal fluctuating data (expects non-stale) - Test price freeze with zero volume (expects stale) - Test price freeze with volume (low volatility market) - Test insufficient data edge case (<5 klines) - Test boundary conditions (exactly 5 klines) - Test tolerance threshold (0.01% price change) - Test mixed scenario (normal → freeze transition) - Test empty klines edge case All 8 test cases passed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Shui <88711385+hzb1115@users.noreply.github.com>
…#934) Add `user && token` guard to all authenticated SWR calls to prevent requests with `Authorization: Bearer null` when users refresh the page before AuthContext finishes loading the token from localStorage. ## Problem When users refresh the page: 1. React components mount immediately 2. SWR hooks fire API requests 3. AuthContext is still loading token from localStorage 4. Requests sent with `Authorization: Bearer null` 5. Backend returns 401 errors This causes: - Unnecessary 401 errors in backend logs - Error messages in browser console - Poor user experience on page refresh ## Solution Add auth check to SWR key conditions using pattern: ```typescript user && token && condition ? key : null ``` When `user` or `token` is null, SWR key becomes `null`, preventing the request. Once AuthContext loads, SWR automatically revalidates and fetches data. ## Changes **TraderDashboard.tsx** (5 auth guards added): - status: `user && token && selectedTraderId ? 'status-...' : null` - account: `user && token && selectedTraderId ? 'account-...' : null` - positions: `user && token && selectedTraderId ? 'positions-...' : null` - decisions: `user && token && selectedTraderId ? 'decisions/...' : null` - stats: `user && token && selectedTraderId ? 'statistics-...' : null` **EquityChart.tsx** (2 auth guards added + useAuth import): - Import `useAuth` from '../contexts/AuthContext' - Add `const { user, token } = useAuth()` - history: `user && token && traderId ? 'equity-history-...' : null` - account: `user && token && traderId ? 'account-...' : null` **apiGuard.test.ts** (new file, 370 lines): - Comprehensive unit tests covering all auth guard scenarios - Tests for null user, null token, valid auth states - Tests for all 7 SWR calls (5 in TraderDashboard + 2 in EquityChart) ## Testing - ✅ TypeScript compilation passed - ✅ Vite build passed (2.81s) - ✅ All modifications are additive (no logic changes) - ✅ SWR auto-revalidation ensures data loads after auth completes ## Benefits 1. **No more 401 errors on refresh**: Auth guards prevent premature requests 2. **Cleaner logs**: Backend no longer receives invalid Bearer null requests 3. **Better UX**: No error flashes in console on page load 4. **Consistent pattern**: All authenticated endpoints use same guard logic ## Context This PR supersedes closed PR NoFxAiOS#881, which had conflicts due to PR NoFxAiOS#872 (frontend refactor with React Router). This implementation is based on the latest upstream/dev with the new architecture. Related: PR NoFxAiOS#881 (closed), PR NoFxAiOS#872 (Frontend Refactor) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: the-dev-z <the-dev-z@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
…oFxAiOS#935) - Add comprehensive Hyperliquid Agent Wallet setup guide with referral link - Update all 5 language versions (EN, ZH, JA, RU, UK) - Remove "Alternative" prefix from Hyperliquid and Aster DEX section titles - Remove direct wallet method, only recommend secure Agent Wallet approach - Include step-by-step registration, funding, and agent wallet creation - Add security warnings and best practices for all languages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: tinkle <tinkle@tinkle.community> Co-authored-by: Claude <noreply@anthropic.com>
根據 @xqliu 的 code review 建議進行重構: **Changes:** 1. 將硬編碼的幣種判斷 (symbol == "BTCUSDT" || symbol == "ETHUSDT") 改為 map 配置 (symbolSizeRules) 2. 添加 altcoinSizeRules 專門處理山寨幣規則 3. 添加 TestCalculateMinPositionSize_MapConfiguration 測試 - 測試 BTC/ETH 配置邏輯 - 測試未配置幣種的默認行為 (SOL, BNB, MATIC, AVAX, DOT, LINK) 4. 運行 go fmt 修復格式問題 **Benefits:** - ✅ 易於擴展:添加新幣種規則只需在 map 中加一行 - ✅ 易於維護:幣種分類集中管理 - ✅ 易於測試:可以輕鬆 mock 或替換配置 - ✅ 類型安全:避免字符串比較錯誤 **Test Results:** - ✅ All decision tests passed (包括新增的 8 個 map 配置測試) - ✅ go fmt ./... 完成 - ✅ go vet ./... 通過 Addresses code review feedback from PR NoFxAiOS#907: - NoFxAiOS#907 (comment) Co-authored-by: xqliu
🤖 Advisory Check ResultsThese are advisory checks to help improve code quality. They won't block your PR from being merged. 📋 PR InformationTitle Format: ✅ Good - Follows Conventional Commits 🔧 Backend ChecksGo Formatting: ✅ Good Fix locally: go fmt ./... # Format code
go vet ./... # Check for issues
go test ./... # Run tests⚛️ Frontend ChecksBuild & Type Check: ✅ Success Fix locally: cd web
npm run build # Test build (includes type checking)📖 ResourcesQuestions? Feel free to ask in the comments! 🙏 These checks are advisory and won't block your PR from being merged. This comment is automatically generated from pr-checks-run.yml. |
✅ Code Review 反饋已修復感謝 @xqliu 的專業建議!已完成所有要求的修改: 📝 修改內容1️⃣ 重構 if-else 為 map 配置 (decision/engine.go:740)Before: isBTCETH := symbol == "BTCUSDT" || symbol == "ETHUSDT"
if !isBTCETH {
return absoluteMinimum
}
// ... 硬編碼邏輯After: // 幣種規則映射表(易於擴展,添加新幣種只需在此添加一行)
var symbolSizeRules = map[string][]positionSizeConfig{
"BTCUSDT": btcEthSizeRules,
"ETHUSDT": btcEthSizeRules,
// 未來可添加更多幣種的特殊規則,例如:
// "BNBUSDT": bnbSizeRules,
// "SOLUSDT": solSizeRules,
}
func calculateMinPositionSize(symbol string, accountEquity float64) float64 {
// 從配置映射表中獲取幣種規則
rules, exists := symbolSizeRules[symbol]
if !exists {
rules = altcoinSizeRules // 默認使用山寨幣規則
}
// ... 統一的動態計算邏輯
}2️⃣ 添加單元測試覆蓋所有分支新增
3️⃣ 運行 go fmt 修復格式問題✅ go fmt ./... # 格式化完成
✅ go vet ./... # 無警告
✅ go test ./decision -v # 所有測試通過🎯 改進效果可擴展性:
可維護性:
可測試性:
📊 測試結果所有 decision 包測試通過:✅ 26/26 tests passed Commit: 8d6ef99 |
… with config 完成 @xqliu 的第二處 code review 建議(line 337): **Changes:** 將 buildSystemPrompt 中的硬編碼閾值改為使用配置規則: **Before (硬編碼):** ```go if accountEquity < 20.0 { // ❌ 硬編碼 sb.WriteString(" | BTC/ETH≥12 USDT (⚠️ 小账户模式,降低门槛)") } else if accountEquity < 100.0 { // ❌ 硬編碼 minBTCETH := calculateMinPositionSize("BTCUSDT", accountEquity) sb.WriteString(fmt.Sprintf(" | BTC/ETH≥%.0f USDT (根据账户规模动态调整)", minBTCETH)) } else { sb.WriteString(" | BTC/ETH≥60 USDT") // ❌ 硬編碼 } ``` **After (使用配置):** ```go minBTCETH := calculateMinPositionSize("BTCUSDT", accountEquity) // 使用配置規則的閾值(btcEthSizeRules[1].MinEquity, btcEthSizeRules[2].MinEquity) if accountEquity < btcEthSizeRules[1].MinEquity { // ✅ 從配置讀取 btcEthHint = fmt.Sprintf(" | BTC/ETH≥%.0f USDT (⚠️ 小账户模式,降低门槛)", minBTCETH) } else if accountEquity < btcEthSizeRules[2].MinEquity { // ✅ 從配置讀取 btcEthHint = fmt.Sprintf(" | BTC/ETH≥%.0f USDT (根据账户规模动态调整)", minBTCETH) } else { btcEthHint = fmt.Sprintf(" | BTC/ETH≥%.0f USDT", minBTCETH) // ✅ 動態計算 } ``` **Benefits:** - ✅ **Single Source of Truth**: 閾值統一從 `btcEthSizeRules` 配置讀取 - ✅ **一致性**: buildSystemPrompt 和 calculateMinPositionSize 使用相同配置 - ✅ **易於維護**: 修改閾值只需改一處配置 - ✅ **避免不一致**: 消除硬編碼數字不匹配的風險 **Test Results:** ```bash ✅ go test ./decision -v # 所有測試通過 (26 cases) ✅ go fmt ./... # 格式化完成 ``` **現在兩處都已使用 map 配置:** 1. ✅ Line 337 (buildSystemPrompt) - 本次修復 2. ✅ Line 739 (calculateMinPositionSize) - 上次已修復 Addresses code review feedback from PR NoFxAiOS#907 (完整修復): - Line 337: "Can we have a map for this instead of Ashoc if else?" ✅ - Line 739: "Also a map would be better here." ✅ Co-authored-by: xqliu
xqliu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍👍👍
🔧 補充修改:完整修復兩處硬編碼剛才發現我遺漏了一處!現已補充修復 line 337 的硬編碼閾值。 ✅ 現在兩處都已使用 map 配置1️⃣ Line 739 (
|
🤖 Advisory Check ResultsThese are advisory checks to help improve code quality. They won't block your PR from being merged. 📋 PR InformationTitle Format: ✅ Good - Follows Conventional Commits 🔧 Backend ChecksGo Formatting: ✅ Good Fix locally: go fmt ./... # Format code
go vet ./... # Check for issues
go test ./... # Run tests⚛️ Frontend ChecksBuild & Type Check: ✅ Success Fix locally: cd web
npm run build # Test build (includes type checking)📖 ResourcesQuestions? Feel free to ask in the comments! 🙏 These checks are advisory and won't block your PR from being merged. This comment is automatically generated from pr-checks-run.yml. |
* feat(docs): add Hyperliquid Agent Wallet tutorial for all languages - Add comprehensive Hyperliquid Agent Wallet setup guide with referral link - Update all 5 language versions (EN, ZH, JA, RU, UK) - Remove "Alternative" prefix from Hyperliquid and Aster DEX section titles - Remove direct wallet method, only recommend secure Agent Wallet approach - Include step-by-step registration, funding, and agent wallet creation - Add security warnings and best practices for all languages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat(docs): add Hyperliquid and Aster DEX to Table of Contents in all languages - Add navigation links for Hyperliquid and Aster DEX registration in all 5 README versions - Ensure all three exchanges (Binance, Hyperliquid, Aster) have equal visibility in TOC - Add complete TOC structure to Japanese README (was missing before) - Maintain consistency across English, Chinese, Japanese, Russian, and Ukrainian versions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: tinkle <tinkle@tinkle.community> Co-authored-by: Claude <noreply@anthropic.com>
根據 @xqliu 的 code review 建議進行重構: **Changes:** 1. 將硬編碼的幣種判斷 (symbol == "BTCUSDT" || symbol == "ETHUSDT") 改為 map 配置 (symbolSizeRules) 2. 添加 altcoinSizeRules 專門處理山寨幣規則 3. 添加 TestCalculateMinPositionSize_MapConfiguration 測試 - 測試 BTC/ETH 配置邏輯 - 測試未配置幣種的默認行為 (SOL, BNB, MATIC, AVAX, DOT, LINK) 4. 運行 go fmt 修復格式問題 **Benefits:** - ✅ 易於擴展:添加新幣種規則只需在 map 中加一行 - ✅ 易於維護:幣種分類集中管理 - ✅ 易於測試:可以輕鬆 mock 或替換配置 - ✅ 類型安全:避免字符串比較錯誤 **Test Results:** - ✅ All decision tests passed (包括新增的 8 個 map 配置測試) - ✅ go fmt ./... 完成 - ✅ go vet ./... 通過 Addresses code review feedback from PR NoFxAiOS#907: - NoFxAiOS#907 (comment) Co-authored-by: xqliu
… with config 完成 @xqliu 的第二處 code review 建議(line 337): **Changes:** 將 buildSystemPrompt 中的硬編碼閾值改為使用配置規則: **Before (硬編碼):** ```go if accountEquity < 20.0 { // ❌ 硬編碼 sb.WriteString(" | BTC/ETH≥12 USDT (⚠️ 小账户模式,降低门槛)") } else if accountEquity < 100.0 { // ❌ 硬編碼 minBTCETH := calculateMinPositionSize("BTCUSDT", accountEquity) sb.WriteString(fmt.Sprintf(" | BTC/ETH≥%.0f USDT (根据账户规模动态调整)", minBTCETH)) } else { sb.WriteString(" | BTC/ETH≥60 USDT") // ❌ 硬編碼 } ``` **After (使用配置):** ```go minBTCETH := calculateMinPositionSize("BTCUSDT", accountEquity) // 使用配置規則的閾值(btcEthSizeRules[1].MinEquity, btcEthSizeRules[2].MinEquity) if accountEquity < btcEthSizeRules[1].MinEquity { // ✅ 從配置讀取 btcEthHint = fmt.Sprintf(" | BTC/ETH≥%.0f USDT (⚠️ 小账户模式,降低门槛)", minBTCETH) } else if accountEquity < btcEthSizeRules[2].MinEquity { // ✅ 從配置讀取 btcEthHint = fmt.Sprintf(" | BTC/ETH≥%.0f USDT (根据账户规模动态调整)", minBTCETH) } else { btcEthHint = fmt.Sprintf(" | BTC/ETH≥%.0f USDT", minBTCETH) // ✅ 動態計算 } ``` **Benefits:** - ✅ **Single Source of Truth**: 閾值統一從 `btcEthSizeRules` 配置讀取 - ✅ **一致性**: buildSystemPrompt 和 calculateMinPositionSize 使用相同配置 - ✅ **易於維護**: 修改閾值只需改一處配置 - ✅ **避免不一致**: 消除硬編碼數字不匹配的風險 **Test Results:** ```bash ✅ go test ./decision -v # 所有測試通過 (26 cases) ✅ go fmt ./... # 格式化完成 ``` **現在兩處都已使用 map 配置:** 1. ✅ Line 337 (buildSystemPrompt) - 本次修復 2. ✅ Line 739 (calculateMinPositionSize) - 上次已修復 Addresses code review feedback from PR NoFxAiOS#907 (完整修復): - Line 337: "Can we have a map for this instead of Ashoc if else?" ✅ - Line 739: "Also a map would be better here." ✅ Co-authored-by: xqliu
…AiOS#937) ## Problem PR NoFxAiOS#917 fixed the validation logic but missed fixing the button disabled state: **Issue:** - Button enabled/disabled check uses raw input length (includes "0x") - Validation logic uses normalized length (excludes "0x") - **Result:** Button can be enabled with insufficient hex characters **Example scenario:** 1. User inputs: `0x` + 30 hex chars = 32 total chars 2. Button check: `32 < 32` → false → ✅ Button enabled 3. User clicks button 4. Validation: normalized to 30 hex chars → `30 < 32` → ❌ Error 5. Error message: "需要至少 32 個字符" (confusing!) ## Root Cause **Lines 230 & 301**: Button disabled conditions don't normalize input ```typescript // ❌ Before: Checks raw length including "0x" disabled={part1.length < expectedPart1Length || processing} disabled={part2.length < expectedPart2Length} ``` ## Solution Normalize input before checking length in disabled conditions: ```typescript // ✅ After: Normalize before checking disabled={ (part1.startsWith('0x') ? part1.slice(2) : part1).length < expectedPart1Length || processing } disabled={ (part2.startsWith('0x') ? part2.slice(2) : part2).length < expectedPart2Length } ``` ## Testing | Input | Total Length | Normalized Length | Button (Before) | Button (After) | Click Result | |-------|--------------|-------------------|-----------------|----------------|--------------| | `0x` + 30 hex | 32 | 30 | ✅ Enabled (bug) | ❌ Disabled | N/A | | `0x` + 32 hex | 34 | 32 | ✅ Enabled | ✅ Enabled | ✅ Valid | | 32 hex | 32 | 32 | ✅ Enabled | ✅ Enabled | ✅ Valid | ## Impact - ✅ Button state now consistent with validation logic - ✅ Users won't see confusing "need 32 chars" errors when button is enabled - ✅ Better UX - button only enabled when input is truly valid **Related:** Follow-up to PR NoFxAiOS#917 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: the-dev-z <the-dev-z@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
## Problem Small accounts (<20 USDT) cannot trade BTC/ETH due to fixed minimum amount (60 USDT) exceeding account size. **User Report:** - Net worth: 6.97 USDT - AI suggested: 30 USDT position - Validation failed: "Minimum 60 USDT required" - Creates "chicken-and-egg" problem: account too small for mainstream coins ## Solution Implement dynamic minimum amount calculation strategy: - Small accounts (<20U): BTC/ETH minimum 12 USDT (same as altcoins) - Medium accounts (20-100U): Linear interpolation 12-60 USDT (smooth transition) - Large accounts (≥100U): Standard 60 USDT (maintain original strategy) - Altcoins: Fixed 12 USDT (unchanged) ## Changes ### 1. New Function: `calculateMinPositionSize()` - Dynamically calculates minimum position size based on account equity and symbol - Example: 6.97U account → BTC/ETH minimum 12U, 60U account → 36U - Uses configuration-driven approach with `positionSizeConfig` struct ### 2. Configuration System - `btcEthSizeRules`: BTC/ETH tiered rules by account size - `altcoinSizeRules`: Altcoin rules (always absolute minimum) - `symbolSizeRules`: Map for symbol-specific rules (easy to extend) ### 3. Updated Validation Logic (`validateDecision`) - Replaced fixed constants with dynamic calculation - Special error messages for small accounts - Maintains safety margins for all account sizes ### 4. Updated AI Prompt (`buildSystemPrompt`) - Dynamic prompts based on account size - Small accounts: "BTC/ETH≥12 USDT (⚠️ Small account mode)" - Medium accounts: "BTC/ETH≥XX USDT (Dynamically adjusted)" - Large accounts: "BTC/ETH≥60 USDT" ## Testing **Comprehensive unit tests added (286 lines):** - ✅ All branches covered (altcoins, BTC/ETH 3 size tiers) - ✅ Boundary tests (0U, 19.99U, 20U, 99.99U, 100U) - ✅ Linear interpolation verification (monotonicity, accuracy) - ✅ Edge cases (zero equity, negative equity, unknown symbols) - ✅ Performance benchmarks - Total: 16 test cases, all passing **Test Results:** ``` $ go test ./decision/... -v -run TestCalculateMinPositionSize === RUN TestCalculateMinPositionSize --- PASS: TestCalculateMinPositionSize (0.00s) === RUN TestCalculateMinPositionSize_EdgeCases --- PASS: TestCalculateMinPositionSize_EdgeCases (0.00s) === RUN TestCalculateMinPositionSize_LinearInterpolation --- PASS: TestCalculateMinPositionSize_LinearInterpolation (0.00s) === RUN TestCalculateMinPositionSize_MapConfiguration --- PASS: TestCalculateMinPositionSize_MapConfiguration (0.00s) PASS ok nofx/decision 0.314s ``` ## Benefits - ✅ **Lowers barrier**: Small accounts can now trade BTC/ETH - ✅ **Smooth transition**: Linear interpolation avoids hard cutoffs - ✅ **Configurable**: Easy to adjust thresholds via configuration - ✅ **Extensible**: Simple to add new symbols or size tiers - ✅ **Well-tested**: Comprehensive test coverage for all branches - ✅ **Backward compatible**: Large accounts maintain original behavior ## Impact - Only affects position opening validation logic - Does not affect existing positions - Improves UX for small accounts - Maintains safety margins for large accounts ## Files Changed ``` decision/engine.go | 113 +++++++++++--- decision/engine_position_size_test.go | 286 ++++++++++++++++++++++++++++++ 2 files changed, 381 insertions(+), 18 deletions(-) ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
ed48fed to
393d0ad
Compare
🤖 Advisory Check ResultsThese are advisory checks to help improve code quality. They won't block your PR from being merged. 📋 PR InformationTitle Format: ✅ Good - Follows Conventional Commits 🔧 Backend ChecksGo Formatting: ✅ Good Fix locally: go fmt ./... # Format code
go vet ./... # Check for issues
go test ./... # Run tests⚛️ Frontend ChecksBuild & Type Check: ✅ Success Fix locally: cd web
npm run build # Test build (includes type checking)📖 ResourcesQuestions? Feel free to ask in the comments! 🙏 These checks are advisory and won't block your PR from being merged. This comment is automatically generated from pr-checks-run.yml. |
43aad91 to
5517269
Compare
02cb78a to
7bd5ca0
Compare
📝 Description | 描述
中文:
用户报告小账户(净值 6.97 USDT)无法交易 BTC/ETH,因为固定最小开仓金额(60 USDT)超过账户规模,造成"鸡生蛋问题"。本 PR 实施动态最小金额计算策略,根据账户规模自适应调整最小开仓金额,降低小账户交易门槛的同时保持大账户的安全边际。
🎯 Type of Change | 变更类型
🔗 Related Issues | 相关 Issue
📋 Changes Made | 具体变更
中文:
1. 新增动态计算函数
calculateMinPositionSize()根据账户净值和币种动态计算最小开仓金额:
示例:
2. 更新验证逻辑 (
validateDecision)minPositionSizeBTCETH = 60.0)为动态计算3. 更新 System Prompt (
buildSystemPrompt)根据账户规模动态提示 AI 最小开仓金额:
🧪 Testing | 测试
Test Environment | 测试环境
Manual Testing | 手动测试
Test Results | 测试结果
$ go test ./decision/... -v === RUN TestPromptManager_LoadTemplates --- PASS: TestPromptManager_LoadTemplates (0.00s) === RUN TestLeverageFallback --- PASS: TestLeverageFallback (0.00s) === RUN TestPromptReloadEndToEnd --- PASS: TestPromptReloadEndToEnd (0.00s) PASS ok nofx/decision 0.294s $ go fmt ./decision/... decision/prompt_manager_test.go测试覆盖:
🔒 Security Considerations | 安全考虑
安全影响分析:
⚡ Performance Impact | 性能影响
性能分析:
calculateMinPositionSize()为纯计算函数,时间复杂度 O(1)✅ Checklist | 检查清单
Code Quality | 代码质量
go build)go fmt| 已运行go fmtDocumentation | 文档
Git
fix: 动态调整最小开仓金额...)devbranch | 已 rebase 到最新dev分支📚 Additional Notes | 补充说明
中文:
风险控制:
LOT_SIZE和MIN_NOTIONAL是否支持后续追踪:
🎯 设计决策
为什么选择 20U 和 100U 作为阈值?
为什么不直接全部改为 12U?
By submitting this PR, I confirm | 提交此 PR,我确认:
🤖 Generated with Claude Code
Co-Authored-By: Claude noreply@anthropic.com