Commit Graph

64 Commits

Author SHA1 Message Date
tinkle-community b228412821 feat: add trading stats to AI context and one-click deployment data clearing
- Add historical trading statistics to AI decision context with language detection
- Remove win rate from metrics, focus on profit factor, sharpe ratio, win/loss ratio
- Add option to clear trading data tables during one-click deployment
- Add sqlite to Docker runtime for container-based data clearing
2025-12-28 22:09:47 +08:00
tinkle-community e591ed8226 fix: normalize symbol comparison to prevent duplicate data in AI input
Use market.Normalize() for both position and candidate symbols to handle
different formats (ETH vs ETHUSDT), ensuring positions are correctly
excluded from candidate list.
2025-12-26 04:13:34 +08:00
tinkle-community 6a2abfa96d feat: improve AI decision input format and chart UX
Backend changes:
- Add symbol headers to market data sections for clarity
- Add symbol labels to quantitative data output
- Skip position coins in candidate list to avoid duplicate data

Frontend changes:
- Add B/S toggle button to show/hide order markers
- Remove bottom legend (B BUY S SELL)
- Fix chart position reset on data refresh
- Separate marker toggle logic from data loading
2025-12-26 02:43:34 +08:00
tinkle-community 1744e7f38e feat: migrate to CoinAnk API and improve chart UI
- Chart improvements: professional styling, popular symbols quick selection, simplified B/S legend
- Data source migration: use CoinAnk API exclusively for all kline data
- Code cleanup: remove Binance WebSocket cache and related code (websocket_client.go, combined_streams.go, monitor.go)
- Log optimization: reduce hook spam, suppress 404 errors, increase P&L diff threshold
- Lighter integration: add order sync functionality, fix market order precision
- Remove ticker merge logic for simplicity
2025-12-26 00:58:12 +08:00
tinkle-community 0009c9c3dd feat: add BOLL (Bollinger Bands) indicator to Strategy Studio
- Add BOLL to frontend indicator grid with period selection
- Add BOLL calculation (upper/middle/lower bands) in market data
- Add BOLL fields to TimeframeSeriesData struct
- Integrate BOLL into AI decision engine prompts
- Support multi-timeframe BOLL analysis
2025-12-20 16:17:16 +08:00
tinkle-community e4d9ea032d fix: position sizing guidance and Lighter sub-accounts support
- Fix hardcoded 5x position ratio in AI prompt example, now uses configured ratio
- Add position sizing guidance section for AI to calculate proper position size
- Add sub_accounts support for Lighter account API
2025-12-16 00:00:07 +08:00
tinkle-community abaffaddb9 fix: add SSRF protection for user-controlled URLs
- Add security/url_validator.go with ValidateURL, SafeHTTPClient, SafeGet
- Block private IP ranges (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16)
- Block cloud metadata endpoints (169.254.169.254, metadata.google.internal)
- Validate DNS resolution to prevent DNS rebinding attacks
- Check redirect destinations for SSRF
- Fix FetchQuantData, FetchOIRanking, fetchAI500, fetchOITop, fetchSingleExternalSource
2025-12-14 12:01:23 +08:00
tinkle-community 4aa612f397 refactor: rename pool to provider (Data Provider) 2025-12-13 21:43:43 +08:00
tinkle-community c4363f3bc7 fix: use strategy config for position value ratio validation instead of hardcoded 1.5x 2025-12-13 20:47:15 +08:00
tinkle-community cc390706d0 feat: add OI ranking data support and fix trader config update issues
- Add OI ranking data fetching and formatting for AI prompts
- Fix trader update not saving strategy_id, ai_model_id, initial_balance
- Fix AI API key not set for non-qwen/deepseek providers
- Add strategy_id to trader config API response
- Remove old trader from memory before reloading on update
- Clean up unused useTraderActions.ts
2025-12-12 16:08:21 +08:00
tinkle-community ecbedc6525 fix: OKX trading issues and improve position tracking
- Add maxMktSz check for OKX market orders to prevent exceeding limits
- Increase margin safety buffer (0.1% fee + 1% buffer) for all exchanges
- Fix Binance position closure detection with direct trade queries
- Move Recent Completed Trades before Current Positions in AI prompt
- Update README screenshots with table layout for better alignment
2025-12-10 22:01:57 +08:00
tinkle-community 319ccb8ca3 fix: initial balance calculation and UI improvements
- Fix initial balance using available_balance instead of total_equity
- Fix WSMonitor nil pointer by starting market monitor before loading traders
- Add strategy name display on traders list and dashboard pages
- Various position sync and trading improvements
2025-12-10 14:40:08 +08:00
tinkle-community f39fc8af23 fix: save raw AI response for debugging and require calculated numbers
- Add RawResponse field to FullDecision and DecisionRecord
- Save raw AI response to database for debugging parse failures
- Add IMPORTANT note in prompt: all numeric values must be calculated numbers, not formulas
2025-12-08 11:29:31 +08:00
tinkle-community a12c0ae8c9 refactor: standardize code comments 2025-12-08 01:43:22 +08:00
tinkle-community 5d1d0b6842 Feature/custom strategy (#1173)
* feat: add Strategy Studio with multi-timeframe support
- Add Strategy Studio page with three-column layout for strategy management
- Support multi-timeframe K-line data selection (5m, 15m, 1h, 4h, etc.)
- Add GetWithTimeframes() function in market package for fetching multiple timeframes
- Add TimeframeSeriesData struct for storing per-timeframe technical indicators
- Update formatMarketData() to display all selected timeframes in AI prompt
- Add strategy API endpoints for CRUD operations and test run
- Integrate real AI test runs with configured AI models
- Support custom AI500 and OI Top API URLs from strategy config
* docs: add Strategy Studio screenshot to README files
* feat: add quant data integration and fix position click navigation
- Integrate quant data API (netflow, OI, price changes) into Strategy Studio
- Add enable_quant_data toggle in indicator editor
- Fix position symbol click to navigate to chart (sync defaultSymbol prop)
- Fix TradingView chart fullscreen flickering
2025-12-06 07:47:03 +08:00
tinkle-community 5cff32e4f2 Feature/custom strategy (#1172)
* feat: add Strategy Studio with multi-timeframe support
- Add Strategy Studio page with three-column layout for strategy management
- Support multi-timeframe K-line data selection (5m, 15m, 1h, 4h, etc.)
- Add GetWithTimeframes() function in market package for fetching multiple timeframes
- Add TimeframeSeriesData struct for storing per-timeframe technical indicators
- Update formatMarketData() to display all selected timeframes in AI prompt
- Add strategy API endpoints for CRUD operations and test run
- Integrate real AI test runs with configured AI models
- Support custom AI500 and OI Top API URLs from strategy config
* docs: add Strategy Studio screenshot to README files
* fix: correct strategy-studio.png filename case in README
* refactor: remove legacy signal source config and simplify trader creation
- Remove signal source configuration from traders page (now handled by strategy)
- Remove advanced options (legacy config) from TraderConfigModal
- Rename default strategy to "默认山寨策略" with AI500 coin pool URL
- Delete SignalSourceModal and SignalSourceWarning components
- Clean up related stores, hooks, and page components
2025-12-06 07:20:11 +08:00
tinkle-community f4ece051e7 Refactor/trading actions (#1169)
* refactor: 简化交易动作,移除 update_stop_loss/update_take_profit/partial_close
- 移除 Decision 结构体中的 NewStopLoss, NewTakeProfit, ClosePercentage 字段
- 删除 executeUpdateStopLossWithRecord, executeUpdateTakeProfitWithRecord, executePartialCloseWithRecord 函数
- 简化 logger 中的 partial_close 聚合逻辑
- 更新 AI prompt 和验证逻辑,只保留 6 个核心动作
- 清理相关测试代码
保留的交易动作: open_long, open_short, close_long, close_short, hold, wait
* refactor: 移除 AI学习与反思 模块
- 删除前端 AILearning.tsx 组件和相关引用
- 删除后端 /performance API 接口
- 删除 logger 中 AnalyzePerformance、calculateSharpeRatio 等函数
- 删除 PerformanceAnalysis、TradeOutcome、SymbolPerformance 等结构体
- 删除 Context 中的 Performance 字段
- 移除 AI prompt 中夏普比率自我进化相关内容
- 清理 i18n 翻译文件中的相关条目
该模块基于磁盘存储计算,经常出错,做减法移除
* refactor: 将数据库操作统一迁移到 store 包
- 新增 store/ 包,统一管理所有数据库操作
  - store.go: 主 Store 结构,懒加载各子模块
  - user.go, ai_model.go, exchange.go, trader.go 等子模块
  - 支持加密/解密函数注入 (SetCryptoFuncs)
- 更新 main.go 使用 store.New() 替代 config.NewDatabase()
- 更新 api/server.go 使用 *store.Store 替代 *config.Database
- 更新 manager/trader_manager.go:
  - 新增 LoadTradersFromStore, LoadUserTradersFromStore 方法
  - 删除旧版 LoadUserTraders, LoadTraderByID, loadSingleTrader 等方法
  - 移除 nofx/config 依赖
- 删除 config/database.go 和 config/database_test.go
- 更新 api/server_test.go 使用 store.Trader 类型
- 清理 logger/ 包中未使用的 telegram 相关代码
* refactor: unify encryption key management via .env
- Remove redundant EncryptionManager and SecureStorage
- Simplify CryptoService to load keys from environment variables only
  - RSA_PRIVATE_KEY: RSA private key for client-server encryption
  - DATA_ENCRYPTION_KEY: AES-256 key for database encryption
  - JWT_SECRET: JWT signing key for authentication
- Update start.sh to auto-generate missing keys on first run
- Remove secrets/ directory and file-based key storage
- Delete obsolete encryption setup scripts
- Update .env.example with all required keys
* refactor: unify logger usage across mcp package
- Add MCPLogger adapter in logger package to implement mcp.Logger interface
- Update mcp/config.go to use global logger by default
- Remove redundant defaultLogger from mcp/logger.go
- Keep noopLogger for testing purposes
* chore: remove leftover test RSA key file
* chore: remove unused bootstrap package
* refactor: unify logging to use logger package instead of fmt/log
- Replace all fmt.Print/log.Print calls with logger package
- Add auto-initialization in logger package init() for test compatibility
- Update main.go to initialize logger at startup
- Migrate all packages: api, backtest, config, decision, manager, market, store, trader
* refactor: rename database file from config.db to data.db
- Update main.go, start.sh, docker-compose.yml
- Update migration script and documentation
- Update .gitignore and translations
* fix: add RSA_PRIVATE_KEY to docker-compose environment
* fix: add registration_enabled to /api/config response
* fix: Fix navigation between login and register pages
Use window.location.href instead of react-router's navigate() to fix
the issue where URL changes but the page doesn't reload due to App.tsx
using custom route state management.
* fix: Switch SQLite from WAL to DELETE mode for Docker compatibility
WAL mode causes data sync issues with Docker bind mounts on macOS due
to incompatible file locking mechanisms between the container and host.
DELETE mode (traditional journaling) ensures data is written directly
to the main database file.
* refactor: Remove default user from database initialization
The default user was a legacy placeholder that is no longer needed now
that proper user registration is in place.
* feat: Add order tracking system with centralized status sync
- Add trader_orders table for tracking all order lifecycle
- Implement GetOrderStatus interface for all exchanges (Binance, Bybit, Hyperliquid, Aster, Lighter)
- Create OrderSyncManager for centralized order status polling
- Add trading statistics (Sharpe ratio, win rate, profit factor) to AI context
- Include recent completed orders in AI decision input
- Remove per-order goroutine polling in favor of global sync manager
* feat: Add TradingView K-line chart to dashboard
- Create TradingViewChart component with exchange/symbol selectors
- Support Binance, Bybit, OKX, Coinbase, Kraken, KuCoin exchanges
- Add popular symbols quick selection
- Support multiple timeframes (1m to 1W)
- Add fullscreen mode
- Integrate with Dashboard page below equity chart
- Add i18n translations for zh/en
* refactor: Replace separate charts with tabbed ChartTabs component
- Create ChartTabs component with tab switching between equity curve and K-line
- Add embedded mode support for EquityChart and TradingViewChart
- User can now switch between account equity and market chart in same area
* fix: Use ChartTabs in App.tsx and fix embedded mode in EquityChart
- Replace EquityChart with ChartTabs in App.tsx (the actual dashboard renderer)
- Fix EquityChart embedded mode for error and empty data states
- Rename interval state to timeInterval to avoid shadowing window.setInterval
- Add debug logging to ChartTabs component
* feat: Add position tracking system for accurate trade history
- Add trader_positions table to track complete open/close trades
- Add PositionSyncManager to detect manual closes via polling
- Record position on open, update on close with PnL calculation
- Use positions table for trading stats and recent trades (replacing orders table)
- Fix TradingView chart symbol format (add .P suffix for futures)
- Fix DecisionCard wait/hold action color (gray instead of red)
- Auto-append USDT suffix for custom symbol input
* update
---------
2025-12-06 01:04:26 +08:00
SkywalkerJi 010676c591 fix: Fix Deepseek compatibility issues on the official website. (#1166)
* fix: Compatible with the HTTP2 stream transmission bug on DeepSeek's official website endpoint.
* fix: Remove reasoning from JSON
2025-12-04 19:19:48 +08:00
Rick 11b6c6ba3e Dev backtest (#1134) 2025-11-28 21:34:27 +08:00
Lawrence Liu a41f2f5a72 fix(decision): clarify field names for update_stop_loss and update_take_profit actions (#993)
* fix(decision): clarify field names for update_stop_loss and update_take_profit actions
修复 AI 决策中的字段名混淆问题:
**问题**:
AI 在使用 update_stop_loss 时错误地使用了 `stop_loss` 字段,
导致解析失败(backend 期望 `new_stop_loss` 字段)
**根因**:
系统 prompt 的字段说明不够明确,AI 无法知道 update_stop_loss
应该使用 new_stop_loss 字段而非 stop_loss
**修复**:
1. 在字段说明中明确标注:
   - update_stop_loss 时必填: new_stop_loss (不是 stop_loss)
   - update_take_profit 时必填: new_take_profit (不是 take_profit)
2. 在 JSON 示例中增加 update_stop_loss 的具体用法示例
**验证**:
decision_logs 中的错误 "新止损价格必须大于0: 0.00" 应该消失
* test(decision): add validation tests for update actions
添加针对 update_stop_loss、update_take_profit 和 partial_close
动作的字段验证单元测试:
**测试覆盖**:
1. TestUpdateStopLossValidation - 验证 new_stop_loss 字段
   - 正确使用 new_stop_loss 字段(应通过)
   - new_stop_loss 为 0(应报错)
   - new_stop_loss 为负数(应报错)
2. TestUpdateTakeProfitValidation - 验证 new_take_profit 字段
   - 正确使用 new_take_profit 字段(应通过)
   - new_take_profit 为 0(应报错)
   - new_take_profit 为负数(应报错)
3. TestPartialCloseValidation - 验证 close_percentage 字段
   - 正确使用 close_percentage 字段(应通过)
   - close_percentage 为 0(应报错)
   - close_percentage 超过 100(应报错)
**测试结果**:所有测试用例通过 ✓
---------
Co-authored-by: Shui <88711385+hzb1115@users.noreply.github.com>
2025-11-15 22:21:11 -05:00
Lawrence Liu 5365b1b4dc fix(decision): add missing actions to AI prompt (#983)
问题:AI 返回 adjust_stop_loss 导致决策验证失败
根因:prompt 只列出 6 个 action,缺少 3 个有效 action
修复(TDD):
1. 添加测试验证 prompt 包含所有 9 个有效 action
2. 最小修改:在 action 列表中补充 3 个缺失项
   - update_stop_loss
   - update_take_profit
   - partial_close
测试:
- TestBuildSystemPrompt_ContainsAllValidActions 
- TestBuildSystemPrompt_ActionListCompleteness 
Fixes: 无效的action: adjust_stop_loss
2025-11-15 22:21:11 -05:00
Shui b96c86fce4 Improve(interface): replace some struct with interface for testing (#994)
* fix(trader): get peakPnlPct using posKey
* fix(docs): keep readme at the same page
* improve(interface): replace with interface
* refactor mcp
---------
Co-authored-by: zbhan <zbhan@freewheel.tv>
2025-11-15 22:20:06 -05:00
Diego a574717f7b fix(stats): fixed the PNL calculation (#963) 2025-11-15 22:20:06 -05:00
0xYYBB | ZYY | Bobo 1d1b31f1f1 fix(trader): add backend safety checks for partial_close (#713)
* fix(trader): add backend safety checks for partial_close
After PR #415 added partial_close functionality, production users reported two critical issues:
1. **Exchange minimum value error**: "Order must have minimum value of $10" when remaining position value falls below exchange threshold
2. **Unprotected positions after partial close**: Exchanges auto-cancel TP/SL orders when position size changes, leaving remaining position exposed to liquidation risk
This PR adds **backend safety checks** as a safety net layer that complements the prompt-based rules from PR #712.
**Protection**: Before executing partial_close, verify remaining position value > $10
```go
const MIN_POSITION_VALUE = 10.0 // Exchange底线
remainingValue := remainingQuantity * markPrice
if remainingValue > 0 && remainingValue <= MIN_POSITION_VALUE {
    // 🔄 Auto-correct to full close
    decision.Action = "close_long" // or "close_short"
    return at.executeCloseLongWithRecord(decision, actionRecord)
}
```
**Behavior**:
- Position $20 → partial_close 50% → remaining $10 ≤ $10 → Auto full close 
- Position $30 → partial_close 50% → remaining $15 > $10 → Allow partial close 
**Protection**: Restore TP/SL orders for remaining position if AI provides new_stop_loss/new_take_profit
```go
// Exchanges auto-cancel TP/SL when position size changes
if decision.NewStopLoss > 0 {
    at.trader.SetStopLoss(symbol, side, remainingQuantity, decision.NewStopLoss)
}
if decision.NewTakeProfit > 0 {
    at.trader.SetTakeProfit(symbol, side, remainingQuantity, decision.NewTakeProfit)
}
// Warning if AI didn't provide new TP/SL
if decision.NewStopLoss <= 0 && decision.NewTakeProfit <= 0 {
    log.Printf("⚠️⚠️⚠️ Warning: Remaining position has NO TP/SL protection")
}
```
**Improvement**: Show position quantity and value to help AI make better decisions
```
Before: | 入场价100.00 当前价105.00 | 盈亏+5.00% | ...
After:  | 入场价100.00 当前价105.00 | 数量0.5000 | 仓位价值52.50 USDT | 盈亏+5.00% | ...
```
**Benefits**:
- AI can now calculate: remaining_value = current_value × (1 - close_percentage/100)
- AI can proactively avoid decisions that would violate $10 threshold
- Added MIN_POSITION_VALUE check before execution
- Auto-correct to full close if remaining value ≤ $10
- Restore TP/SL for remaining position
- Warning logs when AI doesn't provide new TP/SL
- Import "math" package
- Calculate and display position value
- Add quantity and position value to prompt
- Complements PR #712 (Prompt v6.0.0 safety rules)
- Addresses #301 (Backend layer)
- Based on PR #415 (Core functionality)
| Layer | Location | Purpose |
|-------|----------|---------|
| **Layer 1: AI Prompt** | PR #712 | Prevent bad decisions before they happen |
| **Layer 2: Backend** | This PR | Auto-correct and safety net |
**Together they provide**:
-  AI makes better decisions (sees position value, knows rules)
-  Backend catches edge cases (auto-corrects violations)
-  User-friendly warnings (explains what happened)
- [x] Compiles successfully (`go build ./...`)
- [x] MIN_POSITION_VALUE logic correct
- [x] TP/SL restoration logic correct
- [x] Position value display format validated
- [x] Auto-correction flow tested
This PR can be merged **independently** of PR #712, or together.
Suggested merge order:
1. PR #712 (Prompt v6.0.0) - AI layer improvements
2. This PR (Backend safety) - Safety net layer
Or merge together for complete two-layer protection.
---
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
* fix: add error handling for markPrice type assertion
- Check type assertion success before using markPrice
- Return error if markPrice is invalid or <= 0
- Addresses code review feedback from @xqliu in PR #713
* test(trader): add comprehensive unit tests for partial_close safety checks
- Test minimum position value check (< 10 USDT triggers full close)
- Test boundary condition (exactly 10 USDT also triggers full close)
- Test stop-loss/take-profit recovery after partial close
- Test edge cases (invalid close percentages)
- Test integration scenarios with mock trader
All 14 test cases passed, covering:
1. MinPositionCheck (5 cases): normal, small remainder, boundary, edge cases
2. StopLossTakeProfitRecovery (4 cases): both/SL only/TP only/none
3. EdgeCases (4 cases): zero/over 100/negative/normal percentages
4. Integration (2 cases): LONG with SL/TP, SHORT with auto full close
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
* style: apply go fmt after rebase
Only formatting changes:
- api/server.go: fix indentation
- manager/trader_manager.go: add blank line
- trader/partial_close_test.go: align struct fields
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
* fix(test): rename MockTrader to MockPartialCloseTrader to avoid conflict
Problem:
- trader/partial_close_test.go defined MockTrader
- trader/auto_trader_test.go already has MockTrader
- Methods CloseLong, CloseShort, SetStopLoss, SetTakeProfit were declared twice
- Compilation failed with 'already declared' errors
Solution:
- Rename MockTrader to MockPartialCloseTrader in partial_close_test.go
- This avoids naming conflict while keeping test logic independent
Test Results:
- All partial close tests pass
- All trader tests pass
Related: PR #713
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
---------
Co-authored-by: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com>
Co-authored-by: tinkle-community <tinklefund@gmail.com>
Co-authored-by: the-dev-z <the-dev-z@users.noreply.github.com>
2025-11-11 20:36:16 -05:00
zpng a010cc2190 FIX: 编译错误,strconv imported and not used (#891) 2025-11-10 22:23:46 -05:00
0xYYBB | ZYY | Bobo 6a66913194 fix(decision): 添加槓桿超限 fallback 機制並澄清盈虧計算說明 (#716)
* fix(decision): 添加槓桿超限 fallback 機制並澄清盈虧計算說明
1. AI 決策輸出超限槓桿時(如 20x),驗證直接拒絕導致整個交易週期失敗
2. Prompt 未明確說明盈虧百分比已包含槓桿效應,導致 AI 思維鏈中誤用價格變動%
- **Before**: 超限直接報錯 → 決策失敗
- **After**: 自動降級為配置上限 → 決策繼續執行
- **效果**: SOLUSDT 20x → 自動修正為 5x(配置上限)
- 明確告知 AI:系統提供的「盈虧%」已包含槓桿效應
- 公式: 盈虧% = (未實現盈虧 / 保證金) × 100
- 示例: 5x 槓桿,價格漲 2% = 實際盈利 10%
- 測試山寨幣超限修正(20x → 5x)
- 測試 BTC/ETH 超限修正(20x → 10x)
- 測試正常範圍不修正
- 測試無效槓桿拒絕
```
PASS: TestLeverageFallback/山寨币杠杆超限_自动修正为上限
PASS: TestLeverageFallback/BTC杠杆超限_自动修正为上限
PASS: TestLeverageFallback/杠杆在上限内_不修正
PASS: TestLeverageFallback/杠杆为0_应该报错
```
-  向後兼容:正常槓桿範圍不受影響
-  容錯性增強:AI 輸出超限時系統自動修正
-  決策質量提升:AI 對槓桿收益有正確認知
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
* style: apply go fmt after rebase
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
---------
Co-authored-by: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com>
Co-authored-by: tinkle-community <tinklefund@gmail.com>
2025-11-10 20:47:46 -05:00
darkedge 463a092a64 feat: 添加AI请求耗时记录,优化性能评估 (#587)
# Conflicts:
#	decision/engine.go
2025-11-10 20:18:39 -05:00
WquGuru befc887a89 fix(ci): add test encryption key for CI environment (#826)
* fix(ci): add test encryption key for CI environment
- Add DATA_ENCRYPTION_KEY environment variable to PR test workflow
- Add test RSA public key for encryption tests in CI
- Ensures unit tests pass in CI without production credentials
Co-authored-by: tinkle-community <tinklefund@gmail.com>
* fix(ci): install Go cover tool to eliminate covdata warnings
- Add step to install golang.org/x/tools/cmd/cover in CI workflow
- Use || true to prevent installation failure from breaking CI
- Eliminates "no such tool covdata" warnings during test execution
- Apply go fmt to multiple files for consistency
Co-authored-by: tinkle-community <tinklefund@gmail.com>
* fix(ci): install covdata tool for Go 1.23 coverage
The CI was failing with "go: no such tool 'covdata'" error.
This is because Go 1.23 requires the covdata tool to be installed
for coverage reporting.
Changes:
- Install golang.org/x/tools/cmd/covdata in CI workflow
- Update step name to reflect both coverage tools being installed
Fixes the unit test failures in CI pipeline.
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
* fix(ci): remove unnecessary covdata installation and use builtin go tool cover
The previous attempt to install golang.org/x/tools/cmd/covdata was failing
because the package structure changed in Go 1.23 and tools v0.38.0.
The covdata tool is not needed for this project since we only use simple
coverage reporting with go test -coverprofile. The go tool cover command
is built into the Go toolchain and requires no additional installation.
Changes:
- Remove failed covdata and cover installation attempts
- Add verification step for go tool cover availability
- Simplify CI pipeline by eliminating unnecessary dependencies
Co-authored-by: tinkle-community <tinklefund@gmail.com>
* fix(ci): upgrade Go version to 1.25 to match go.mod declaration
The CI was using Go 1.23 while go.mod declares go 1.25.0, causing
"no such tool covdata" errors during coverage test compilation.
Go 1.25's coverage infrastructure requires toolchain features not
available in Go 1.23.
This change aligns the CI Go version with the project's declared
version requirement, ensuring the full Go 1.25 toolchain (including
the covdata tool) is available for coverage testing.
Co-authored-by: tinkle-community <tinklefund@gmail.com>
---------
Co-authored-by: tinkle-community <tinklefund@gmail.com>
2025-11-09 18:40:03 +08:00
Lawrence Liu fd3fc654cb Fix 历史最高收益率(百分比), 盈亏金额 USDT, 最高收益率 没有传递给 AI 作决策,无法在 prompt 中使用 (#651) 2025-11-09 16:20:52 +08:00
SkywalkerJi 1c4c933b7f refactor(decision): use XML tags to separate reasoning from JSON decisions (#719)
* Separate the AI's thought process from the instruction JSON using XML tags.
* Avoid committing encryption key related materials to Git.
* Removing adaptive series prompts, awaiting subsequent modifications for compatibility.
2025-11-07 22:35:53 +08:00
Linden f1f24ad1fa fix:完善aster账户净值和盈亏计算|Improve the calculation of the net value and profit/loss of the aster account (#695)
Co-authored-by: LindenWang <linden@Lindens-MacBookPro-2.local>
2025-11-07 13:38:39 +08:00
0xYYBB | ZYY | Bobo 4b924f6133 fix(decision): add safe fallback when AI outputs only reasoning without JSON (#561)
## 问题 (Problem)
当 AI 只输出思维链分析没有 JSON 决策时,系统会崩溃并报错:
"无法找到JSON数组起始",导致整个交易周期失败,前端显示红色错误。
## 解决方案 (Solution)
1. 添加安全回退机制 (Safe Fallback)
   - 当检测不到 JSON 数组时,自动生成保底决策
   - Symbol: "ALL", Action: "wait"
   - Reasoning 包含思维链摘要(最多 240 字符)
2. 统一注释为简体中文 + 英文对照
   - 关键修复 (Critical Fix)
   - 安全回退 (Safe Fallback)
   - 退而求其次 (Fallback)
## 效果 (Impact)
- 修复前:系统崩溃,前端显示红色错误 "获取AI决策失败"
- 修复后:系统稳定,自动进入 wait 状态,前端显示绿色成功
- 日志记录:[SafeFallback] 标记方便监控和调试
## 设计考量 (Design Considerations)
- 仅在完全找不到 JSON 时触发(区分于格式错误)
- 有 JSON 但格式错误仍然报错(提示需要改进 prompt)
- 保留完整思维链摘要供后续分析
- 避免隐藏真正的问题(格式错误应该暴露)
## 测试 (Testing)
-  正常 JSON 输出:解析成功
-  纯思维链输出:安全回退到 wait
-  JSON 格式错误:继续报错(预期行为)
-  编译通过
## 监控建议 (Monitoring)
可通过日志统计 fallback 频率:
```bash
grep "[SafeFallback]" logs/nofx.log | wc -l
```
如果频率 > 5% 的交易周期,建议检查并改进 prompt 质量。
Co-authored-by: tinkle-community <tinklefund@gmail.com>
2025-11-06 00:08:23 +08:00
0xYYBB | ZYY | Bobo 701ab9c62f Revert "fix: hard system prompt (#401)" (#522)
This reverts commit 7dd669a907c7c2ff1023bd76821af7d13be1f35a.
2025-11-05 19:05:09 +08:00
Jupiteriana 14b788a0f0 fix: hard system prompt (#401) 2025-11-05 17:45:18 +08:00
Icyoung 71f79a72fe Merge pull request #462 from zhouyongyou/fix/quantity-zero-min-notional
fix(trader+decision): prevent quantity=0 error with minimum notional validation
2025-11-05 16:29:24 +08:00
Icyoung 90b1b03697 Merge pull request #446 from zhouyongyou/fix/json-fullwidth-characters
fix(decision): handle fullwidth JSON characters from AI responses
2025-11-05 15:46:56 +08:00
Icyoung e33f9babfe Merge pull request #386 from zhouyongyou/feat/configurable-oi-threshold
feat(decision): configurable OI threshold + relaxed trading template
2025-11-05 15:46:25 +08:00
ZhouYongyou 7027d7a2e1 refactor(decision): relax minimum position size constraints for flexibility
## Changes
### Prompt Layer (Soft Guidance)
**Before**:
- BTC/ETH ≥100 USDT | 山寨币 ≥15 USDT (硬性要求)
**After**:
- 统一建议 ≥12 USDT (软性建议)
- 更简洁,不区分币种
- 给 AI 更多决策空间
### Validation Layer (Lower Thresholds)
**Before**:
- BTC/ETH: 100 USDT (硬性)
- 山寨币: 15 USDT (硬性)
**After**:
- BTC/ETH: 60 USDT (-40%, 更灵活)
- 山寨币: 12 USDT (-20%, 更合理)
## Rationale
### Why Relax?
1. **Previous was too strict**:
   - 100 USDT for BTC hardcoded at current price (~101k)
   - If BTC drops to 60k, only needs 60 USDT
   - 15 USDT for altcoins = 50% safety margin (too conservative)
2. **Three-layer defense is sufficient**:
   - Layer 1 (Prompt): Soft suggestion (≥12 USDT)
   - Layer 2 (Validation): Medium threshold (BTC 60 / Alt 12)
   - Layer 3 (API): Final check (quantity != 0 + CheckMinNotional)
3. **User feedback**: Original constraints too restrictive
### Safety Preserved
 API layer still prevents:
- quantity = 0 errors (formatted precision check)
- Below min notional (CheckMinNotional)
 Validation still blocks obviously small amounts
 Prompt guides AI toward safe amounts
## Testing
| Symbol | Amount | Old | New | Result |
|--------|--------|-----|-----|--------|
| BTCUSDT | 50 USDT |  Rejected |  Rejected |  Correct (too small) |
| BTCUSDT | 70 USDT |  Rejected |  Pass |  More flexible |
| ADAUSDT | 11 USDT |  Rejected |  Rejected |  Correct (too small) |
| ADAUSDT | 13 USDT |  Rejected |  Pass |  More flexible |
## Impact
-  More flexible for price fluctuations
-  Better user experience for small accounts
-  Still prevents API errors
-  AI has more decision space
2025-11-05 01:18:22 +08:00
ZhouYongyou 1cb5c268c5 fix(trader+decision): prevent quantity=0 error with min notional checks
User encountered API error when opening BTC position:
- Account equity: 9.20 USDT
- AI suggested: ~7.36 USDT position
- Error: `code=-4003, msg=Quantity less than or equal to zero.`
```
quantity = 7.36 / 101808.2 ≈ 0.00007228 BTC
formatted (%.3f) → "0.000"  Rounded down to 0!
```
BTCUSDT precision is 3 decimals (stepSize=0.001), causing small quantities to round to 0.
-  CloseLong() and CloseShort() have CheckMinNotional()
-  OpenLong() and OpenShort() **missing** CheckMinNotional()
- AI could suggest position_size_usd < minimum notional value
- No validation prevented tiny positions that would fail
---
**OpenLong() and OpenShort()** - Added two checks:
```go
//  Check if formatted quantity became 0 (rounding issue)
quantityFloat, _ := strconv.ParseFloat(quantityStr, 64)
if quantityFloat <= 0 {
    return error("Quantity too small, formatted to 0...")
}
//  Check minimum notional value (Binance requires ≥10 USDT)
if err := t.CheckMinNotional(symbol, quantityFloat); err != nil {
    return err
}
```
**Impact**: Prevents API errors by catching invalid quantities before submission.
---
Added minimum position size validation:
```go
const minPositionSizeGeneral = 15.0   // Altcoins
const minPositionSizeBTCETH = 100.0   // BTC/ETH (high price + precision limits)
if symbol == BTC/ETH && position_size_usd < 100 {
    return error("BTC/ETH requires ≥100 USDT to avoid rounding to 0")
}
if position_size_usd < 15 {
    return error("Position size must be ≥15 USDT (min notional requirement)")
}
```
**Impact**: Rejects invalid decisions before execution, saving API calls.
---
Updated hard constraints in AI prompt:
```
6. 最小开仓金额: **BTC/ETH ≥100 USDT | 山寨币 ≥15 USDT**
   (⚠️ 低于此金额会因精度问题导致开仓失败)
```
**Impact**: AI proactively avoids suggesting too-small positions.
---
-  User equity 9.20 USDT → suggested 7.36 USDT BTC position → **FAIL**
-  No validation, error only at API level
-  AI validation rejects position_size_usd < 100 for BTC
-  Binance trader checks quantity != 0 before submission
-  Clear error: "BTC/ETH requires ≥100 USDT..."
| Symbol | position_size_usd | Price | quantity | Formatted | Result |
|--------|-------------------|-------|----------|-----------|--------|
| BTCUSDT | 7.36 | 101808.2 | 0.00007228 | "0.000" |  Rejected (validation) |
| BTCUSDT | 150 | 101808.2 | 0.00147 | "0.001" |  Pass |
| ADAUSDT | 15 | 1.2 | 12.5 | "12.500" |  Pass |
---
**Immediate**:
-  Prevents quantity=0 API errors
-  Clear error messages guide users
-  Saves wasted API calls
**Long-term**:
-  AI learns minimum position sizes
-  Better user experience for small accounts
-  Prevents confusion from cryptic API errors
---
- Diagnostic report: /tmp/quantity_zero_diagnosis.md
- Binance min notional: 10 USDT (hardcoded in GetMinNotional())
2025-11-05 01:18:09 +08:00
ZhouYongyou 2f14ee304b fix(decision): correct Unicode regex escaping in reInvisibleRunes
## Critical Fix
### Problem
-  `regexp.MustCompile(`[\u200B...]`)` (backticks = raw string)
- Raw strings don't parse \uXXXX escape sequences in Go
- Regex was matching literal text "\u200B" instead of Unicode characters
### Solution
-  `regexp.MustCompile("[\u200B...]")` (double quotes = parsed string)
- Double quotes properly parse Unicode escape sequences
- Now correctly matches U+200B (zero-width space), U+200C, U+200D, U+FEFF
## Impact
- Zero-width characters are now properly removed before JSON parsing
- Prevents invisible character corruption in AI responses
- Fixes potential JSON parsing failures
## Related
- Same fix applied to z-dev in commit db7c035
2025-11-05 01:05:13 +08:00
ZhouYongyou 14ba145ea7 perf(decision): precompile regex patterns for performance
## Changes
- Move all regex patterns to global precompiled variables
- Reduces regex compilation overhead from O(n) to O(1)
- Matches z-dev's performance optimization
## Modified Patterns
- reJSONFence: Match ```json code blocks
- reJSONArray: Match JSON arrays
- reArrayHead: Validate array start
- reArrayOpenSpace: Compact array formatting
- reInvisibleRunes: Remove zero-width characters
## Performance Impact
- Regex compilation now happens once at startup
- Eliminates repeated compilation in extractDecisions() (called every decision cycle)
- Expected performance improvement: ~5-10% in JSON parsing
## Safety
 All regex patterns remain unchanged (only moved to global scope)
 Compilation successful
 Maintains same functionality as before
2025-11-05 00:54:51 +08:00
ZhouYongyou 30b22d3762 fix(decision): extract fullwidth chars BEFORE regex matching
🐛 Problem:
- AI returns JSON with fullwidth characters: [{
- Regex \[ cannot match fullwidth [
- extractDecisions() fails with "无法找到JSON数组起始"
🔧 Root Cause:
- fixMissingQuotes() was called AFTER regex matching
- If regex fails to match fullwidth chars, fix function never executes
 Solution:
- Call fixMissingQuotes(s) BEFORE regex matching (line 461)
- Convert fullwidth to halfwidth first: [→[, {→{
- Then regex can successfully match the JSON array
📊 Impact:
- Fixes "无法找到JSON数组起始" error
- Supports AI responses with fullwidth JSON characters
- Backward compatible with halfwidth JSON
This fix is identical to z-dev commit 3676cc0
2025-11-05 00:32:48 +08:00
ZhouYongyou 5afd417a5d feat(decision): sync robust JSON extraction & limit candidates from z-dev
## Synced from z-dev
### 1. Robust JSON Extraction (from aa63298)
- Add regexp import
- Add removeInvisibleRunes() - removes zero-width chars & BOM
- Add compactArrayOpen() - normalizes '[ {' to '[{'
- Rewrite extractDecisions():
  * Priority 1: Extract from ```json code blocks
  * Priority 2: Regex find array
  * Multi-layer defense: 7 layers total
### 2. Enhanced Validation
- validateJSONFormat now uses regex ^\[\s*\{ (allows any whitespace)
- More tolerant than string prefix check
### 3. Limit Candidate Coins (from f1e981b)
- calculateMaxCandidates now enforces proper limits:
  * 0 positions: max 30 candidates
  * 1 position: max 25 candidates
  * 2 positions: max 20 candidates
  * 3+ positions: max 15 candidates
- Prevents Prompt bloat when users configure many coins
## Coverage
Now handles:
-  Pure JSON
-  ```json code blocks
-  Thinking chain混合
-  Fullwidth characters (16種)
-  CJK characters
-  Zero-width characters
-  All whitespace combinations
Estimated coverage: **99.9%**
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
2025-11-05 00:27:47 +08:00
ZhouYongyou 834285bb16 fix(decision): replace fullwidth space (U+3000) in JSON
Critical bug: AI can output fullwidth space ( U+3000) between brackets:
Input:  [ {"symbol":"BTCUSDT"}]
        ↑ ↑ fullwidth space
After previous fix:
        [ {"symbol":"BTCUSDT"}]
         ↑ fullwidth space remained!
Result: validateJSONFormat failed because:
- Checks "[{" (no space) 
- Checks "[ {" (halfwidth space U+0020) 
- AI output "[ {" (fullwidth space U+3000) 
Solution: Replace fullwidth space → halfwidth space
-  (U+3000) → space (U+0020)
This allows existing validation logic to work:
strings.HasPrefix(trimmed, "[ {") now matches 
Why fullwidth space?
- Common in CJK text editing
- AI trained on mixed CJK content
- Invisible to naked eye but breaks JSON parsing
Test case:
Input:  [ {"symbol":"BTCUSDT"}]
Output: [ {"symbol":"BTCUSDT"}]
Validation:  PASS
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
2025-11-04 23:59:20 +08:00
ZhouYongyou 40ba5865a4 fix(decision): add CJK punctuation support in fixMissingQuotes
Critical discovery: AI can output different types of "fullwidth" brackets:
- Fullwidth: []{}(U+FF3B/FF3D/FF5B/FF5D) ← Already handled
- CJK: 【】〔〕(U+3010/3011/3014/3015) ← Was missing!
Root cause of persistent errors:
User reported: "JSON 必须以【{开头"
The 【 character (U+3010) is NOT the same as [ (U+FF3B)!
Added CJK punctuation replacements:
- 【 → [ (U+3010 Left Black Lenticular Bracket)
- 】 → ] (U+3011 Right Black Lenticular Bracket)
- 〔 → [ (U+3014 Left Tortoise Shell Bracket)
- 〕 → ] (U+3015 Right Tortoise Shell Bracket)
- 、 → , (U+3001 Ideographic Comma)
Why this was missed:
AI uses different characters in different contexts. CJK brackets (U+3010-3017)
are distinct from Fullwidth Forms (U+FF00-FFEF) in Unicode.
Test case:
Input:  【{"symbol":"BTCUSDT"】
Output: [{"symbol":"BTCUSDT"}]
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
2025-11-04 23:11:08 +08:00
ZhouYongyou 1ca4b80add feat(decision): add validateJSONFormat to catch common AI errors
Adds comprehensive JSON validation before parsing to catch common AI output errors:
1. Format validation: Ensures JSON starts with [{ (decision array)
2. Range symbol detection: Rejects ~ symbols (e.g., "leverage: 3~5")
3. Thousands separator detection: Rejects commas in numbers (e.g., "98,000")
Execution order (critical for fullwidth character fix):
1. Extract JSON from response
2. fixMissingQuotes - normalize fullwidth → halfwidth 
3. validateJSONFormat - check for common errors 
4. Parse JSON
This validation layer provides early error detection and clearer error messages
for debugging AI response issues.
Added helper function:
- min(a, b int) int - returns smaller of two integers
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
2025-11-04 23:04:22 +08:00
ZhouYongyou 2f0f026fdb fix(decision): handle fullwidth JSON characters from AI responses
Extends fixMissingQuotes() to replace fullwidth brackets, colons, and commas that Claude AI occasionally outputs, preventing JSON parsing failures.
Root cause: AI can output fullwidth characters like [{:, instead of [{ :,
Error: "JSON 必须以 [{ 开头,实际: [ {"symbol": "BTCU"
Fix: Replace all fullwidth JSON syntax characters:
- [] (U+FF3B/FF3D) → []
- {} (U+FF5B/FF5D) → {}
- : (U+FF1A) → :
- , (U+FF0C) → ,
Test case:
Input:  [{\"symbol\":\"BTCUSDT\",\"action\":\"open_short\"}]
Output: [{\"symbol\":\"BTCUSDT\",\"action\":\"open_short\"}]
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
2025-11-04 22:41:35 +08:00
ZhouYongyou b8eea8eaad 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 c2aed38785 修復關鍵 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 8344e6b68f 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(部分平仓)
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
2025-11-04 16:40:12 +08:00