-
Notifications
You must be signed in to change notification settings - Fork 2.2k
fix(web): prevent unauthorized API calls with null token (clean rebuild of #669) #880
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
Closed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Introduces 15m and 1h timeframes to Data struct and related calculations for more robust multi-timeframe analysis. Updates system prompt to reflect new data sources and analysis methods, and extends Format output to include mid-term series. Enhances signal quality and trend confirmation by leveraging multiple timeframes.
Added logic to automatically cancel all orders for a symbol when its position disappears, ensuring orphan stop-loss/take-profit orders are cleaned up. This improves order management and prevents unintended trades after a position is closed.
**核心功能**: - 新增买卖压力数据解析(TakerBuyVolume, BuySellRatio) - 重写系统提示词为震荡交易策略 - 添加连续放量检测功能(2-3根K线) **技术细节**: - market/data.go: 解析币安 K线 item[9] 为主动买入量 - decision/engine.go: 震荡区间识别 + 区间边界入场逻辑 - IntradayData: 新增 Volumes 和 BuySellRatios 数组
根据 ADAPTIVE_STRATEGY_DESIGN.md 方案 A(简单版)实现: 新增功能: 1. 市场状态判断(3个指标交叉验证): - 多时间框架一致性(15m/1h/4h MACD 方向) - 价格波动率(最近 10 根 K线波动幅度) - 买卖压力极端值(BuySellRatio 连续性) 2. 双策略系统: - 策略 A(震荡交易):止盈 1-2%,止损 0.8-1%,盈亏比 1:1.5-1:2 - 策略 B(趋势跟随):止盈 5-10%,止损 1.5-2%,盈亏比 1:3-1:5 3. 策略选择指导:AI 必须在思维链中明确说明市场状态判断和策略选择 改进效果: - 让 AI 根据市场状态动态调整止盈止损 - 震荡市场快进快出,趋势市场让利润奔跑 - 预期提升胜率和盈亏比,降低最大回撤 实施方式:纯提示词改进(无代码变更),耗时 30 分钟 🤖 Generated with Claude Code
解决问题: - 固定百分比止盈经常在技术位前回撤 - 浮盈没有保护机制,从 +1.5% 回撤到止损 核心改进: 1. 技术位优先止盈: - 震荡策略:技术位 < 2% → 止盈设在技术位前 0.1% - 趋势策略:技术位 < 5% → 止盈设在技术位前 0.2% - 技术位识别:EMA20、最近高低点、整数关口 2. 追踪止损机制: - 震荡:浮盈 0.8% → 止损移到成本价,浮盈 1.2% → 止损移到 +0.5% - 趋势:浮盈 2% → 止损移到成本价,浮盈 5% → 止损移到 +2.5% - 价格接近技术位 → 主动平仓避免回撤 3. 分批止盈预留: - 趋势策略:技术位在 5-10% → 分两批止盈 - 为阶段2分批止盈做准备 预期效果: - 减少"快到止盈就回撤"的情况 - 锁定浮盈,避免全部回撤 - 提高实际盈亏比 实施方式:纯提示词改进,基于已有数据(EMA20、K线高低点) 🤖 Generated with Claude Code
问题: - 旧算法只计算价格变化百分比,未考虑杠杆倍数 - 例:10倍杠杆,价格涨1% → 显示+1%(错误),实际应该是+10% - 导致 AI 收到错误的盈亏数据,影响决策 修复: - 使用实际盈亏除以保证金计算百分比 - 公式:pnlPct = (unrealizedPnl / marginUsed) * 100 - 优点: ✓ 考虑杠杆倍数 ✓ 使用 API 提供的实际盈亏(含手续费、资金费率) ✓ 更准确反映真实盈亏百分比 示例对比: - 入场:100,000,当前:101,000(+1%),10倍杠杆 - 旧算法:显示 +1%(错误) - 新算法:显示 +10%(正确) 感谢用户反馈 @1711z 🤖 Generated with Claude Code
问题: - Go 语言不识别中文双引号 "" - 导致编译失败:syntax error: unexpected name 修复: - 将所有中文双引号 "" 替换为英文单引号 '' - 影响行:287, 365-369 错误示例: - 错误:"趋势市场" - 正确:'趋势市场' 🤖 Generated with Claude Code
- 问题:config.json.example 与 main.go 的 ConfigFile 结构不一致 - 影响:新用户复制 example 时会缺少必要的配置字段 - 修复:添加 coin_pool_api_url 和 oi_top_api_url(空字符串) 相关提交:517d0ca (admin_mode config)
新增 prompts/adaptive.txt 模板,包含: ## 核心特性 - 市場狀態判斷(震盪/趨勢,多指標交叉驗證) - 雙策略系統: * 策略 A: 震盪交易(高勝率低盈虧比) * 策略 B: 趨勢跟隨(中等勝率高盈虧比) - 技術位優先止盈機制(EMA20、前高前低、整數關口) - 動態追踪止損(鎖定利潤,避免回撤) - 夏普比率自我進化(交易質量 > 交易頻率) ## 使用方式 用戶可在 Web UI 選擇此模板,或繼續使用 default/nof1 ## 技術實現 - 259 行完整策略指導 - 與現有模板系統兼容 - engine.go 保留硬編碼作為 fallback 相關文檔:TEMPLATE_MIGRATION_PLAN.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
## 問題
- 之前邏輯:加載模板 → 無條件追加硬編碼策略
- 結果:選擇 adaptive 模板時,會收到重複的策略內容
* adaptive.txt: 259 行
* 硬編碼: 184 行
* 總計:443 行重複指導 ❌
## 解決方案
使用 templateLoaded 標記追蹤模板加載狀態:
- ✅ 模板成功 → 使用模板,跳過硬編碼
- ❌ 模板失敗 → 使用硬編碼作為 fallback
## 變更內容
1. 添加 templateLoaded bool 變量
2. 硬編碼策略包裹在 `if !templateLoaded {}` 中(277-463 行)
3. 硬約束和輸出格式始終追加(不受影響)
4. 添加日誌追蹤模板使用情況
## 測試驗證
- ✅ Go 編譯成功
- ✅ Docker build 成功
- ✅ 向後兼容(模板失敗時回退到硬編碼)
## 架構改進
```
加載流程:
1. 嘗試加載指定模板(如 adaptive)
2. 失敗 → 嘗試 default
3. 仍失敗 → 使用硬編碼
4. 追加硬約束(動態生成)
5. 追加輸出格式(動態生成)
```
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
## 問題
用戶反饋:「怎麼 engine.go 還寫入了這些?... 有必要嗎?」
**根本原因**:
- prompts/ 目錄下已有 default.txt (114行) 和 adaptive.txt (259行)
- engine.go 卻硬編碼了 183 行 adaptive 策略作為 fallback
- 這導致:
1. 重複維護兩份相同的策略內容
2. templateLoaded 標記多餘(模板系統本身已有 fallback)
3. 如果 default.txt 都加載失敗,說明文件系統有嚴重問題,不應繼續交易
## 解決方案
### 1. 移除冗餘硬編碼
- 刪除 183 行硬編碼 adaptive 策略(271-453 行)
- 移除 templateLoaded 標記及其邏輯
### 2. 簡化模板加載邏輯
```go
// 之前(複雜)
templateLoaded := false
if 模板加載成功 {
templateLoaded = true
}
if !templateLoaded {
追加 183 行硬編碼策略 // ❌ 冗餘
}
// 現在(簡潔)
if 用戶模板加載失敗 {
嘗試 default.txt // ✅ 已經是 fallback
}
if default.txt 也失敗 {
返回空字符串,上層應停止交易 // ✅ 安全
}
```
### 3. 新增動態止盈止損設計文檔
創建 `DYNAMIC_TP_SL_PROPOSAL.md`,記錄:
- 用戶反饋:「建议加个 adjust tp sl 或者给 close 加个 quantity」
- 問題分析:策略提到追蹤止損,但 AI 無法執行
- 解決方案:添加 `adjust_stop_loss`, `adjust_take_profit`, `partial_close` actions
- 實施步驟:修改 Decision 結構、執行邏輯、模板說明
## 測試驗證
- ✅ Go 編譯成功
- ✅ Docker build 成功
- ✅ 模板系統邏輯清晰(用戶模板 → default → 報錯)
- ✅ 代碼減少 183 行(更易維護)
## 檔案變更
- `decision/engine.go`: -183 行硬編碼策略
- `DYNAMIC_TP_SL_PROPOSAL.md`: +300 行設計文檔
## 後續工作
- [ ] 實現 adjust_stop_loss action
- [ ] 實現 partial_close action
- [ ] 更新模板文件說明新 actions
---
感謝 @user 指出這個設計缺陷!🙏
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
DYNAMIC_TP_SL_PROPOSAL.md 是動態止盈止損功能的設計文檔, 但功能尚未實現,保留在代碼庫中可能造成困擾(誤以為已完成)。 當需要實現該功能時,可以從 git 歷史中恢復(commit bac5744)。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
## 問題
之前修改將模板加載失敗時改為返回空字符串,但:
- 上層函數沒有檢測空字符串的邏輯
- 空字符串會直接傳給 AI API,導致錯誤
- 極端情況下系統無法運行
## 解決方案
恢復原始邏輯,保留內置簡化版本作為最後防線:
```
用戶模板失敗 → default 失敗 → 使用內置簡化版本
"你是专业的加密货币交易AI。请根据市场数据做出交易决策。"
```
## 差異對比
### 之前(不安全)
```go
if default 加載失敗 {
return "" // ❌ 上層未檢測,會傳空字符串給 AI
}
```
### 現在(安全)
```go
if default 加載失敗 {
sb.WriteString("你是专业的加密货币交易AI。请根据市场数据做出交易决策。\n\n")
// ✅ 有最後防線,極端情況下仍能運行
}
```
## 測試驗證
- ✅ Go 編譯成功
- ✅ Docker build 成功
- ✅ 邏輯恢復到原始穩定版本
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
问题: - 编辑交易员并修改系统提示词模板时,保存失败 - 错误提示:AI模型配置不存在或未启用 根本原因: 1. 后端 API 返回的 ai_model 被截断(admin_deepseek → deepseek) 2. 前端验证时找不到对应的模型 ID(enabledModels 存的是完整 ID) 3. API 缺少 system_prompt_template 字段 修复内容: - api/server.go: 移除 AI model ID 截断逻辑,返回完整 ID - api/server.go: 在 handleGetTraderConfig 中添加 system_prompt_template 字段 - web/src/types.ts: TraderConfigData 接口添加 system_prompt_template 字段 - web/src/components/AITradersPage.tsx: 添加 fallback 机制和详细日志 测试: - 编辑交易员 → 修改系统提示词模板 → 保存成功 - Console 输出验证日志,不再报错
改動說明: - 新增「數據框架說明」章節:詳細說明 4 個時間框架的覆蓋時間和用途 * 3分鐘序列(30分鐘):實時價格、放量檢測、買賣壓力 * 15分鐘序列(2.5小時):震盪區間識別 * 1小時序列(10小時):中期趨勢確認 * 4小時序列(40小時):大趨勢判斷 - 新增「關鍵數據解讀」章節: * BuySellRatio 含義和參考範圍(0.6-0.7 強買壓,0.3-0.4 強賣壓) * 成交量分析:放量檢測標準(1.5-2 倍平均) * RSI 參考範圍:根據市場波動性調整(震盪市 30-40/60-70) - 新增「入場信號參考示例」章節: * 震盪策略入場信號(區間下沿做多、上沿做空) * 趨勢策略入場信號(趨勢突破參考) - 補充「避免低質量信號」: * 新增:震盪市在區間中部交易(應等待區間邊界) * 新增:缺乏買賣壓力確認(BuySellRatio 中性時謹慎) 設計哲學: - 採用「解釋 + 參考示例」方式,而非硬編碼固定規則 - 所有參考數值都明確標註「你可以根據市場狀態自主調整」 - 強調根據市場波動性、趨勢強度自主判斷 - 激發 AI 的判斷能力,而非限制其靈活性 - 通過夏普比率反饋實現自我進化 改動統計: - 原文件:259 行 - 新文件:366 行(+107 行) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
問題:AI 生成 update_stop_loss 決策但被拒絕為無效動作 原因:adaptive.txt 描述了動態止損功能,但 dev 分支代碼未實現 刪除內容: - 震盪策略:追蹤止損(持倉中動態調整)段落 - 趨勢策略:分批止盈、追蹤止損段落 - 策略選擇:追蹤止損計劃 - 持倉動態調整範例 結果:提示詞與代碼功能完全匹配,避免 AI 生成無效決策 相關 issue:生產環境報錯 '无效的action:update_stop_loss' 後續計劃:在 feature/partial-close-dynamic-tpsl 測試完成後再合併動態功能
問題: - 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 ✓ - 模型使用檢查邏輯正確 ✓
問題: - 圖表顯示「初始余額 693.15 USDT」(實際應該是 600) - 原因:使用 validHistory[0].total_equity(當前淨值) - 導致初始余額隨著盈虧變化,數學邏輯錯誤 修復: - 優先從 account.initial_balance 讀取真實配置值 - 備選方案:從歷史數據反推(淨值 - 盈虧) - 默認值使用 1000(與創建交易員時的默認配置一致) 測試: - 初始余額:600 USDT(固定) - 當前淨值:693.15 USDT - 盈虧:+93.15 USDT (+15.52%) ✓
問題: - 用戶首次運行報錯:unable to open database file: is a directory - 原因:Docker volume 掛載時,如果 config.db 不存在,會創建目錄而非文件 - 影響:新用戶無法正常啟動系統 修復: - 在 start.sh 啟動前檢查 config.db 是否存在 - 如不存在則創建空文件(touch config.db) - 確保 Docker 掛載為文件而非目錄 測試: - 首次運行:./start.sh start → 正常初始化 ✓ - 現有用戶:無影響,向後兼容 ✓
問題: - 用戶遇到錯誤:stream error: stream ID 1; INTERNAL_ERROR - 這是 HTTP/2 連接被服務端關閉的錯誤 - 當前重試機制不包含此類錯誤,導致直接失敗 修復: - 添加 "stream error" 到可重試列表 - 添加 "INTERNAL_ERROR" 到可重試列表 - 遇到此類錯誤時會自動重試(最多 3 次) 影響: - 提高 API 調用穩定性 - 自動處理服務端臨時故障 - 減少因網絡波動導致的失敗
问题: - 止损/止盈触发后,交易所返回 positionAmt=0 的持仓记录 - 这些幽灵持仓被传递给 AI,导致 AI 误以为仍持有该币种 - AI 可能基于错误信息做出决策(如尝试调整已不存在的止损) 修复: - buildTradingContext() 中添加 quantity==0 检查 - 跳过已平仓的持仓,确保只传递真实持仓给 AI - 触发清理逻辑:撤销孤儿订单、清理内部状态 影响范围: - trader/auto_trader.go:487-490 测试: - 编译成功 - 容器重建并启动正常
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. ## Problem When users refresh the page, SWR fires requests before AuthContext loads the token from localStorage, causing "Bearer null" errors. ## Solution Add auth check to SWR key conditions: - ✅ App.tsx (6 calls): traders, status, account, positions, decisions, stats - ✅ EquityChart.tsx (2 calls): history, account - ✅ Add comprehensive unit tests for API guard logic ## Testing - ✅ TypeScript compilation: \`npx tsc --noEmit\` - ✅ 370 lines of unit tests covering all edge cases Fixes NoFxAiOS#634 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
29 tasks
Collaborator
Author
|
Closing - created from wrong base. Will recreate from upstream/dev to avoid including unrelated commits. |
31 tasks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Prevents unauthorized API calls with
Authorization: Bearer nullby adding authentication guards to all SWR calls. This is a clean rebuild of #669 from the latestdevbranch.Problem
When users refresh the page or directly access trader pages, SWR fires API requests before AuthContext finishes loading the token from localStorage, causing errors:
Solution
Add
user && token &&to all authenticated SWR key conditions:Files Changed (3 files, 376 insertions)
web/src/App.tsx(6 SWR calls): traders, status, account, positions, decisions, statsweb/src/components/EquityChart.tsx(2 SWR calls): history, accountweb/src/lib/apiGuard.test.ts(370 lines): Comprehensive unit testsTesting
npx tsc --noEmitWhy Rebuild?
Old PR #669 had 165 commits with 9 file conflicts due to being based on an outdated branch. This clean rebuild:
dev(no conflicts)Related
🤖 Generated with Claude Code
Co-Authored-By: Claude [email protected]