Skip to content

Merge dev to main#1039

Merged
tinkle-community merged 21 commits into
mainfrom
dev
Nov 16, 2025
Merged

Merge dev to main#1039
tinkle-community merged 21 commits into
mainfrom
dev

Conversation

@tangmengqiu

Copy link
Copy Markdown
Collaborator

Pull Request | PR 提交

📋 选择专用模板 | Choose Specialized Template

我们现在提供了针对不同类型PR的专用模板,帮助你更快速地填写PR信息:
We now offer specialized templates for different types of PRs to help you fill out the information faster:

如何使用?| How to use?

  • 创建PR时,在URL中添加 ?template=backend.md 或其他模板名称
  • When creating a PR, add ?template=backend.md or other template name to the URL
  • 或者直接复制粘贴对应模板的内容
  • Or simply copy and paste the content from the corresponding template

💡 提示 Tip: 推荐 PR 标题格式 type(scope): description
例如: feat(trader): add new strategy | fix(api): resolve auth issue


📝 Description | 描述

English:中文:


🎯 Type of Change | 变更类型

  • 🐛 Bug fix | 修复 Bug
  • ✨ New feature | 新功能
  • 💥 Breaking change | 破坏性变更
  • 📝 Documentation update | 文档更新
  • 🎨 Code style update | 代码样式更新
  • ♻️ Refactoring | 重构
  • ⚡ Performance improvement | 性能优化
  • ✅ Test update | 测试更新
  • 🔧 Build/config change | 构建/配置变更
  • 🔒 Security fix | 安全修复

🔗 Related Issues | 相关 Issue

  • Closes # | 关闭 #
  • Related to # | 相关 #

📋 Changes Made | 具体变更

English:中文:


🧪 Testing | 测试

  • Tested locally | 本地测试通过
  • Tests pass | 测试通过
  • Verified no existing functionality broke | 确认没有破坏现有功能

✅ Checklist | 检查清单

Code Quality | 代码质量

  • Code follows project style | 代码遵循项目风格
  • Self-review completed | 已完成代码自查
  • Comments added for complex logic | 已添加必要注释

Documentation | 文档

  • Updated relevant documentation | 已更新相关文档

Git

  • Commits follow conventional format | 提交遵循 Conventional Commits 格式
  • Rebased on latest dev branch | 已 rebase 到最新 dev 分支
  • No merge conflicts | 无合并冲突

📚 Additional Notes | 补充说明

English:中文:


By submitting this PR, I confirm | 提交此 PR,我确认:

  • I have read the Contributing Guidelines | 已阅读贡献指南
  • I agree to the Code of Conduct | 同意行为准则
  • My contribution is licensed under AGPL-3.0 | 贡献遵循 AGPL-3.0 许可证

🌟 Thank you for your contribution! | 感谢你的贡献!

tinkle and others added 20 commits November 15, 2025 22:17
* refactor(frontend): extract RegistrationDisabled as reusable component

- Create RegistrationDisabled component with i18n support
- Add registrationClosed and registrationClosedMessage translations
- Replace inline JSX in App.tsx with new component
- Improve code maintainability and reusability
- Add hover effect to back button for better UX

* fix(frontend): add registration toggle to LoginModal component

- Add useSystemConfig hook to LoginModal
- Conditionally render registration button based on registration_enabled config
- Ensures consistency with HeaderBar and LoginPage registration controls
- Completes registration toggle feature implementation across all entry points

* feat(frontend): add registration toggle UI support

- Add registration disabled page in App.tsx when registration is closed
- Hide registration link in LoginPage when registration is disabled
- Add registration_enabled field to SystemConfig interface
- Frontend conditionally shows/hides registration UI based on backend config

* feat: add registration toggle feature

Add system-level registration enable/disable control:
- Add registration_enabled config to system_config table (default: true)
- Add registration check in handleRegister API endpoint
- Expose registration_enabled status in /api/config endpoint
- Frontend can use this config to conditionally show/hide registration UI

This allows administrators to control user registration without code changes.

* fix(frontend): add registration toggle to HeaderBar and RegisterPage

- Add useSystemConfig hook and registrationEnabled check to HeaderBar
- Conditionally show/hide signup buttons in both desktop and mobile views
- Add registration check to RegisterPage to show RegistrationDisabled component
- This completes the registration toggle feature across all UI components

* test(frontend): add comprehensive unit tests for registration toggle feature

- Add RegistrationDisabled component tests (rendering, navigation, styling)
- Add registrationToggle logic tests (config handling, edge cases, multi-location consistency)
- Configure Vitest with jsdom environment for React component testing
- All 80 tests passing (9 new tests for RegistrationDisabled + 21 for toggle logic)
* feat(dashboard): display system prompt template and extract color constant

* style(api): format server.go with go fmt
Co-authored-by: zbhan <zbhan@freewheel.tv>
* fix(trader): get peakPnlPct using posKey

* fix(docs): keep readme at the same page

---------

Co-authored-by: zbhan <zbhan@freewheel.tv>
* fix(api): market/combined_streams: Get Proxy form Environment

issues:
❌ 批量订阅流失败: 组合流WebSocket连接失败: dial tcp xxxxxx:443: i/o timeout

Make environment variables effective for
dialer.Dial("wss://fstream.binance.com/stream", nil):

export HTTPS_PROXY=http://ip:port
export HTTP_PROXY=http://ip:port

Signed-off-by: MarsDoge <mars@dogexorg.com>

* docs(WebSocket): add proxy usage guidance for combined streams (#475)

Signed-off-by: MarsDoge <mars@dogexorg.com>

---------

Signed-off-by: MarsDoge <mars@dogexorg.com>
…ons (#989)

## Problem
When creating/editing/deleting traders, AI models, or exchanges, the UI
takes 3-4 seconds to show results, causing users to think the system is frozen.

## Root Cause
Although mutateTraders() was called after operations, it was not awaited,
causing the function to continue immediately without waiting for data refresh.
The UI relied on the refreshInterval: 5000 automatic refresh, resulting in
up to 5 seconds of delay.

## Solution
Added await before all mutateTraders() calls to ensure data is refreshed
before closing modals or showing success messages.

Changes:
- handleCreateTrader: Added await before mutateTraders()
- handleSaveEditTrader: Added await before mutateTraders()
- handleDeleteTrader: Added await before mutateTraders()
- handleToggleTrader: Added await before mutateTraders()

Impact:
- From 3-4s delay to immediate display (< 500ms)
- Significantly improved UX
- Consistent with AI model and exchange config behavior

Testing:
- Frontend build successful
- No TypeScript errors
- Ready for manual UI testing

Co-authored-by: the-dev-z <the-dev-z@users.noreply.github.com>
)

* 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>
修复了token过期后页面一直遇到401错误、无法自动跳转登录页的问题

主要改动:
1. httpClient.ts
   - 去掉延迟跳转的setTimeout,改为立即跳转
   - 返回pending promise阻止SWR捕获401错误
   - 保存from401标记到sessionStorage,由登录页显示提示

2. LoginPage.tsx
   - 检测from401标记,显示"登录已过期"提示(永久显示)
   - 在登录成功时手动关闭过期提示toast
   - 支持管理员登录、普通登录、OTP验证三种场景

3. TraderConfigModal.tsx
   - 修复3处直接使用fetch()的问题,改为httpClient.get()
   - 确保所有API请求都经过统一的401拦截器

4. translations.ts
   - 添加sessionExpired的中英文翻译

修复效果:
- token过期时立即跳转登录页(无延迟)
- 登录页持续显示过期提示,直到用户登录成功或手动关闭
- 不会再看到401错误页面或重复的错误提示

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

Co-authored-by: Claude <noreply@anthropic.com>
## Problem
When multiple users create traders with the same exchange + AI model
combination within the same second, they generate identical traderIDs,
causing data conflicts.

Old code (Line 496):
```go
traderID := fmt.Sprintf("%s_%s_%d", req.ExchangeID, req.AIModelID, time.Now().Unix())
```

## Solution
Use UUID to guarantee 100% uniqueness while preserving prefix for debugging:
```go
traderID := fmt.Sprintf("%s_%s_%s", req.ExchangeID, req.AIModelID, uuid.New().String())
```

Example output: `binance_gpt-4_a1b2c3d4-e5f6-7890-abcd-ef1234567890`

## Changes
- `api/server.go:495-497`: Use UUID for traderID generation
- `api/traderid_test.go`: New test file with 3 comprehensive tests

## Tests
✅ All tests passed (0.189s)
✅ TestTraderIDUniqueness - 100 unique IDs generated
✅ TestTraderIDFormat - 3 exchange/model combinations validated
✅ TestTraderIDNoCollision - 1000 iterations without collision

Fixes #893

Co-authored-by: the-dev-z <the-dev-z@users.noreply.github.com>
* Add files via upload

* Revise Git workflow guidelines and branch strategies

* Update git workflow

* Chores
…1023)

* refactor(web): restructure AITradersPage into modular architecture

Refactored the massive 2652-line AITradersPage.tsx into a clean, modular architecture following React best practices.

**Changes:**
- Decomposed 2652-line component into 12 focused modules
- Introduced Zustand stores for config and modal state management
- Extracted all business logic into useTraderActions custom hook (633 lines)
- Created reusable section components (PageHeader, TradersGrid, etc.)
- Separated complex modal logic into dedicated components
- Added TraderConfig type, eliminated all any types
- Fixed critical bugs in configuredExchanges logic and getState() usage

**File Structure:**
- Main page reduced from 2652 → 234 lines (91% reduction)
- components/traders/: 7 UI components + 5 section components
- stores/: tradersConfigStore, tradersModalStore
- hooks/: useTraderActions (all business logic)

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

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: ignore PR_DESCRIPTION.md

* fix(web): restore trader dashboard navigation functionality

Fixed missing navigation logic in refactored AITradersPage. The "查看" (View) button now correctly navigates to the trader dashboard.

**Root Cause:**
During refactoring, the `useNavigate` hook and default navigation logic were inadvertently omitted from the main page component.

**Changes:**
- Added `useNavigate` import from react-router-dom
- Implemented `handleTraderSelect` function with fallback navigation
- Restored original behavior: use `onTraderSelect` prop if provided, otherwise navigate to `/dashboard?trader=${traderId}`

**Testing:**
- ✅ Click "查看" button navigates to trader dashboard
- ✅ Query parameter correctly passed to dashboard

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

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(web): correct type definitions for trader configuration

Fixed TypeScript build errors by using the correct `TraderConfigData` type instead of the incorrect `TraderConfig` type.

**Root Cause:**
During refactoring, a new `TraderConfig` type was incorrectly created that extended `CreateTraderRequest` (with fields like `name`, `ai_model_id`). However, the `TraderConfigModal` component and API responses actually use `TraderConfigData` (with fields like `trader_name`, `ai_model`).

**Changes:**
- Replaced all `TraderConfig` references with `TraderConfigData`:
  - stores/tradersModalStore.ts
  - hooks/useTraderActions.ts
  - lib/api.ts
- Removed incorrect `TraderConfig` type definition from types.ts
- Added null check for `editingTrader.trader_id` to satisfy TypeScript

**Build Status:**
- ✅ TypeScript compilation: PASS
- ✅ Vite production build: PASS

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

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
问题: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
…ke_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>
## Problem

PR #906 changed healthcheck commands from `wget` to `curl`, but Alpine Linux
(our base image) does not include `curl` by default, causing all containers
to fail healthchecks with:

```
exec: "curl": executable file not found in $PATH
```

This creates a configuration mismatch:
- docker/Dockerfile.backend uses `wget` (✅ works)
- docker-compose.yml uses `curl` (❌ fails)

## Root Cause Analysis

Alpine Linux philosophy is minimalism:
- ✅ `wget` is pre-installed (part of busybox)
- ❌ `curl` requires `apk add curl` (~3MB extra)

The original PR #906 made two commits:
1. First commit (3af8760): `curl` → `wget` (✅ correct fix)
2. Second commit (333b2ef): `wget` → `curl` (❌ introduced bug)

The second commit was based on incorrect assumption that "curl is more
widely available than wget in Docker images". This is false for Alpine.

## Solution

Revert healthcheck commands back to `wget` to match:
1. Alpine's pre-installed tools
2. Dockerfile.backend healthcheck (line 68)
3. Docker and Kubernetes best practices

## Testing

✅ Verified `wget` exists in Alpine containers:
```bash
docker run --rm alpine:latest which wget
# Output: /usr/bin/wget
```

✅ Added new CI workflow to prevent regression:
- `.github/workflows/pr-docker-compose-healthcheck.yml`
- Validates healthcheck compatibility with Alpine
- Ensures containers reach healthy status

## Impact

- **Before**: Containers show (unhealthy), potential auto-restart loops
- **After**: Containers show (healthy), monitoring systems happy
- **Scope**: Only affects docker-compose deployments
- **Breaking**: None - this is a bug fix

## References

- PR #906: Original (incorrect) fix
- Alpine Linux: https://alpinelinux.org/about/
- Dockerfile.backend L68: Existing `wget` healthcheck

🤖 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>
Co-authored-by: Shui <88711385+hzb1115@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

⚠️ PR Title Format Suggestion

Your PR title doesn't follow the Conventional Commits format, but this won't block your PR from being merged.

Current title: Merge dev to main

Recommended format: type(scope): description

Valid types:

feat, fix, docs, style, refactor, perf, test, chore, ci, security, build

Common scopes (optional):

exchange, trader, ai, api, ui, frontend, backend, security, deps, workflow, github, actions, config, docker, build, release

Examples:

  • feat(trader): add new trading strategy
  • fix(api): resolve authentication issue
  • docs: update README
  • chore(deps): update dependencies
  • ci(workflow): improve GitHub Actions

Note: This is a suggestion to improve consistency. Your PR can still be reviewed and merged.


This is an automated comment. You can update the PR title anytime.

@github-actions

Copy link
Copy Markdown

🚨 This PR is large (>6814 lines changed). Please consider breaking it into smaller, focused PRs for easier review.

@github-actions

github-actions Bot commented Nov 16, 2025

Copy link
Copy Markdown

🔴 Go Test Coverage Report

Total Coverage: 32.1% (needs improvement)

Coverage

📊 Detailed Coverage Report (click to expand)

Coverage by Package

nofx/api/crypto_handler.go:17:		NewCryptoHandler			0.0%
nofx/api/crypto_handler.go:26:		HandleGetPublicKey			0.0%
nofx/api/crypto_handler.go:38:		HandleDecryptSensitiveData		0.0%
nofx/api/crypto_handler.go:65:		isValidPrivateKey			0.0%
nofx/api/server.go:37:			NewServer				0.0%
nofx/api/server.go:64:			corsMiddleware				0.0%
nofx/api/server.go:80:			setupRoutes				0.0%
nofx/api/server.go:162:			handleHealth				0.0%
nofx/api/server.go:170:			handleGetSystemConfig			0.0%
nofx/api/server.go:216:			handleGetServerIP			0.0%
nofx/api/server.go:249:			getPublicIPFromAPI			0.0%
nofx/api/server.go:287:			getPublicIPFromInterface		0.0%
nofx/api/server.go:332:			isPrivateIP				0.0%
nofx/api/server.go:354:			getTraderFromQuery			0.0%
nofx/api/server.go:465:			handleCreateTrader			0.0%
nofx/api/server.go:690:			handleUpdateTrader			0.0%
nofx/api/server.go:808:			handleDeleteTrader			0.0%
nofx/api/server.go:833:			handleStartTrader			0.0%
nofx/api/server.go:882:			handleStopTrader			0.0%
nofx/api/server.go:920:			handleUpdateTraderPrompt		0.0%
nofx/api/server.go:953:			handleGetModelConfigs			0.0%
nofx/api/server.go:981:			handleUpdateModelConfigs		0.0%
nofx/api/server.go:1048:		handleGetExchangeConfigs		0.0%
nofx/api/server.go:1078:		handleUpdateExchangeConfigs		0.0%
nofx/api/server.go:1145:		handleGetUserSignalSource		0.0%
nofx/api/server.go:1164:		handleSaveUserSignalSource		0.0%
nofx/api/server.go:1187:		handleTraderList			0.0%
nofx/api/server.go:1223:		handleGetTraderConfig			0.0%
nofx/api/server.go:1273:		handleStatus				0.0%
nofx/api/server.go:1291:		handleAccount				0.0%
nofx/api/server.go:1324:		handlePositions				0.0%
nofx/api/server.go:1349:		handleDecisions				0.0%
nofx/api/server.go:1375:		handleLatestDecisions			0.0%
nofx/api/server.go:1414:		handleStatistics			0.0%
nofx/api/server.go:1439:		handleCompetition			0.0%
nofx/api/server.go:1460:		handleEquityHistory			0.0%
nofx/api/server.go:1550:		handlePerformance			0.0%
nofx/api/server.go:1577:		authMiddleware				0.0%
nofx/api/server.go:1619:		handleLogout				0.0%
nofx/api/server.go:1647:		handleRegister				0.0%
nofx/api/server.go:1763:		handleCompleteRegistration		0.0%
nofx/api/server.go:1816:		handleLogin				0.0%
nofx/api/server.go:1860:		handleVerifyOTP				0.0%
nofx/api/server.go:1900:		handleResetPassword			0.0%
nofx/api/server.go:1944:		initUserDefaultConfigs			0.0%
nofx/api/server.go:1952:		handleGetSupportedModels		0.0%
nofx/api/server.go:1965:		handleGetSupportedExchanges		0.0%
nofx/api/server.go:1993:		Start					0.0%
nofx/api/server.go:2031:		Shutdown				0.0%
nofx/api/server.go:2044:		handleGetPromptTemplates		0.0%
nofx/api/server.go:2062:		handleGetPromptTemplate			0.0%
nofx/api/server.go:2078:		handlePublicTraderList			0.0%
nofx/api/server.go:2125:		handlePublicCompetition			0.0%
nofx/api/server.go:2138:		handleTopTraders			0.0%
nofx/api/server.go:2151:		handleEquityHistoryBatch		0.0%
nofx/api/server.go:2206:		getEquityHistoryForTraders		0.0%
nofx/api/server.go:2256:		handleGetPublicTraderConfig		0.0%
nofx/api/server.go:2287:		reloadPromptTemplatesWithLog		0.0%
nofx/api/utils.go:7:			MaskSensitiveString			100.0%
nofx/api/utils.go:19:			SanitizeModelConfigForLog		100.0%
nofx/api/utils.go:38:			SanitizeExchangeConfigForLog		82.4%
nofx/api/utils.go:83:			MaskEmail				100.0%
nofx/auth/auth.go:32:			SetJWTSecret				0.0%
nofx/auth/auth.go:37:			BlacklistToken				0.0%
nofx/auth/auth.go:58:			IsTokenBlacklisted			0.0%
nofx/auth/auth.go:79:			HashPassword				0.0%
nofx/auth/auth.go:85:			CheckPassword				0.0%
nofx/auth/auth.go:91:			GenerateOTPSecret			0.0%
nofx/auth/auth.go:110:			VerifyOTP				0.0%
nofx/auth/auth.go:115:			GenerateJWT				0.0%
nofx/auth/auth.go:132:			ValidateJWT				0.0%
nofx/auth/auth.go:152:			GetOTPQRCodeURL				0.0%
nofx/bootstrap/bootstrap.go:42:		Register				0.0%
nofx/bootstrap/bootstrap.go:60:		Run					0.0%
nofx/bootstrap/bootstrap.go:65:		RunWithPolicy				0.0%
nofx/bootstrap/bootstrap.go:148:	GetRegistered				0.0%
nofx/bootstrap/bootstrap.go:158:	Clear					0.0%
nofx/bootstrap/bootstrap.go:165:	Count					0.0%
nofx/bootstrap/context.go:19:		NewContext				0.0%
nofx/bootstrap/context.go:28:		Set					0.0%
nofx/bootstrap/context.go:35:		Get					0.0%
nofx/bootstrap/context.go:43:		MustGet					0.0%
nofx/bootstrap/hook_builder.go:18:	EnabledIf				0.0%
nofx/bootstrap/hook_builder.go:24:	OnError					0.0%
nofx/bootstrap/init_hook.go:10:		RegisterInitHook			0.0%
nofx/bootstrap/init_hook.go:15:		RunInitHooks				0.0%
nofx/config/config.go:48:		LoadConfig				0.0%
nofx/config/database.go:62:		NewDatabase				56.2%
nofx/config/database.go:100:		createTables				81.8%
nofx/config/database.go:277:		initDefaultData				81.2%
nofx/config/database.go:344:		migrateExchangesTable			70.8%
nofx/config/database.go:505:		GenerateOTPSecret			0.0%
nofx/config/database.go:515:		CreateUser				100.0%
nofx/config/database.go:524:		EnsureAdminUser				0.0%
nofx/config/database.go:550:		GetUserByEmail				0.0%
nofx/config/database.go:566:		GetUserByID				0.0%
nofx/config/database.go:582:		GetAllUsers				0.0%
nofx/config/database.go:601:		UpdateUserOTPVerified			0.0%
nofx/config/database.go:607:		UpdateUserPassword			0.0%
nofx/config/database.go:617:		GetAIModels				0.0%
nofx/config/database.go:651:		UpdateAIModel				0.0%
nofx/config/database.go:735:		GetExchanges				86.7%
nofx/config/database.go:778:		UpdateExchange				89.6%
nofx/config/database.go:879:		CreateAIModel				0.0%
nofx/config/database.go:888:		CreateExchange				0.0%
nofx/config/database.go:902:		CreateTrader				0.0%
nofx/config/database.go:911:		GetTraders				0.0%
nofx/config/database.go:949:		UpdateTraderStatus			0.0%
nofx/config/database.go:955:		UpdateTrader				0.0%
nofx/config/database.go:971:		UpdateTraderCustomPrompt		0.0%
nofx/config/database.go:978:		UpdateTraderInitialBalance		0.0%
nofx/config/database.go:984:		DeleteTrader				0.0%
nofx/config/database.go:990:		GetTraderConfig				0.0%
nofx/config/database.go:1053:		GetSystemConfig				0.0%
nofx/config/database.go:1060:		SetSystemConfig				0.0%
nofx/config/database.go:1068:		CreateUserSignalSource			0.0%
nofx/config/database.go:1077:		GetUserSignalSource			0.0%
nofx/config/database.go:1093:		UpdateUserSignalSource			0.0%
nofx/config/database.go:1102:		GetCustomCoins				0.0%
nofx/config/database.go:1131:		Close					100.0%
nofx/config/database.go:1136:		LoadBetaCodesFromFile			0.0%
nofx/config/database.go:1188:		ValidateBetaCode			0.0%
nofx/config/database.go:1201:		UseBetaCode				0.0%
nofx/config/database.go:1223:		GetBetaCodeStats			0.0%
nofx/config/database.go:1238:		SetCryptoService			100.0%
nofx/config/database.go:1243:		encryptSensitiveData			57.1%
nofx/config/database.go:1258:		decryptSensitiveData			77.8%
nofx/crypto/crypto.go:51:		NewCryptoService			0.0%
nofx/crypto/crypto.go:83:		GenerateRSAKeyPair			0.0%
nofx/crypto/crypto.go:129:		ParseRSAPrivateKeyFromPEM		0.0%
nofx/crypto/crypto.go:153:		loadDataKeyFromEnv			0.0%
nofx/crypto/crypto.go:169:		decodePossibleKey			0.0%
nofx/crypto/crypto.go:187:		normalizeAESKey				0.0%
nofx/crypto/crypto.go:201:		HasDataKey				0.0%
nofx/crypto/crypto.go:205:		GetPublicKeyPEM				0.0%
nofx/crypto/crypto.go:219:		EncryptForStorage			0.0%
nofx/crypto/crypto.go:253:		DecryptFromStorage			0.0%
nofx/crypto/crypto.go:303:		IsEncryptedStorageValue			0.0%
nofx/crypto/crypto.go:307:		composeAAD				0.0%
nofx/crypto/crypto.go:314:		isEncryptedStorageValue			0.0%
nofx/crypto/crypto.go:318:		DecryptPayload				0.0%
nofx/crypto/crypto.go:388:		DecryptSensitiveData			0.0%
nofx/crypto/encryption.go:35:		GetEncryptionManager			100.0%
nofx/crypto/encryption.go:44:		newEncryptionManager			71.4%
nofx/crypto/encryption.go:71:		loadOrGenerateRSAKeyPair		72.7%
nofx/crypto/encryption.go:120:		loadRSAKeyPair				0.0%
nofx/crypto/encryption.go:150:		GetPublicKeyPEM				100.0%
nofx/crypto/encryption.go:160:		DecryptWithPrivateKey			0.0%
nofx/crypto/encryption.go:225:		loadOrGenerateMasterKey			43.3%
nofx/crypto/encryption.go:275:		EncryptForDatabase			76.9%
nofx/crypto/encryption.go:299:		DecryptFromDatabase			85.7%
nofx/crypto/encryption.go:340:		RotateMasterKey				0.0%
nofx/crypto/secure_storage.go:17:	NewSecureStorage			0.0%
nofx/crypto/secure_storage.go:39:	SaveEncryptedExchangeConfig		0.0%
nofx/crypto/secure_storage.go:78:	LoadDecryptedExchangeConfig		0.0%
nofx/crypto/secure_storage.go:124:	SaveEncryptedAIModelConfig		0.0%
nofx/crypto/secure_storage.go:146:	LoadDecryptedAIModelConfig		0.0%
nofx/crypto/secure_storage.go:173:	initAuditLog				0.0%
nofx/crypto/secure_storage.go:192:	logAudit				0.0%
nofx/crypto/secure_storage.go:204:	GetAuditLogs				0.0%
nofx/crypto/secure_storage.go:244:	MigrateToEncrypted			0.0%
nofx/decision/engine.go:124:		GetFullDecision				0.0%
nofx/decision/engine.go:129:		GetFullDecisionWithCustomPrompt		0.0%
nofx/decision/engine.go:169:		fetchMarketDataForContext		0.0%
nofx/decision/engine.go:246:		calculateMaxCandidates			0.0%
nofx/decision/engine.go:275:		buildSystemPromptWithCustom		92.3%
nofx/decision/engine.go:302:		buildSystemPrompt			100.0%
nofx/decision/engine.go:365:		buildUserPrompt				0.0%
nofx/decision/engine.go:469:		parseFullDecisionResponse		0.0%
nofx/decision/engine.go:497:		extractCoTTrace				0.0%
nofx/decision/engine.go:522:		extractDecisions			0.0%
nofx/decision/engine.go:602:		fixMissingQuotes			0.0%
nofx/decision/engine.go:631:		validateJSONFormat			0.0%
nofx/decision/engine.go:664:		min					0.0%
nofx/decision/engine.go:672:		removeInvisibleRunes			0.0%
nofx/decision/engine.go:677:		compactArrayOpen			0.0%
nofx/decision/engine.go:682:		validateDecisions			0.0%
nofx/decision/engine.go:692:		findMatchingBracket			0.0%
nofx/decision/engine.go:714:		validateDecision			82.0%
nofx/decision/prompt_manager.go:32:	init					75.0%
nofx/decision/prompt_manager.go:42:	NewPromptManager			100.0%
nofx/decision/prompt_manager.go:49:	LoadTemplates				85.0%
nofx/decision/prompt_manager.go:95:	GetTemplate				100.0%
nofx/decision/prompt_manager.go:108:	GetAllTemplateNames			100.0%
nofx/decision/prompt_manager.go:121:	GetAllTemplates				0.0%
nofx/decision/prompt_manager.go:134:	ReloadTemplates				100.0%
nofx/decision/prompt_manager.go:145:	GetPromptTemplate			100.0%
nofx/decision/prompt_manager.go:150:	GetAllPromptTemplateNames		0.0%
nofx/decision/prompt_manager.go:155:	GetAllPromptTemplates			0.0%
nofx/decision/prompt_manager.go:160:	ReloadPromptTemplates			100.0%
nofx/hook/hooks.go:14:			HookExec				0.0%
nofx/hook/hooks.go:31:			RegisterHook				0.0%
nofx/hook/http_client_hook.go:13:	Error					0.0%
nofx/hook/http_client_hook.go:20:	GetResult				0.0%
nofx/hook/ip_hook.go:10:		Error					0.0%
nofx/hook/ip_hook.go:14:		GetResult				0.0%
nofx/hook/trader_hook.go:15:		Error					0.0%
nofx/hook/trader_hook.go:22:		GetResult				0.0%
nofx/hook/trader_hook.go:32:		Error					0.0%
nofx/hook/trader_hook.go:39:		GetResult				0.0%
nofx/logger/config.go:22:		SetDefaults				0.0%
nofx/logger/config.go:31:		GetLogrusLevels				0.0%
nofx/logger/decision_logger.go:90:	NewDecisionLogger			0.0%
nofx/logger/decision_logger.go:112:	LogDecision				0.0%
nofx/logger/decision_logger.go:140:	GetLatestRecords			0.0%
nofx/logger/decision_logger.go:179:	GetRecordByDate				0.0%
nofx/logger/decision_logger.go:207:	CleanOldRecords				0.0%
nofx/logger/decision_logger.go:239:	GetStatistics				0.0%
nofx/logger/decision_logger.go:344:	AnalyzePerformance			0.0%
nofx/logger/decision_logger.go:691:	calculateSharpeRatio			0.0%
nofx/logger/logger.go:24:		Init					0.0%
nofx/logger/logger.go:66:		setupTelegramHook			0.0%
nofx/logger/logger.go:80:		InitWithSimpleConfig			0.0%
nofx/logger/logger.go:85:		InitWithTelegram			0.0%
nofx/logger/logger.go:97:		InitFromLogConfig			0.0%
nofx/logger/logger.go:127:		InitFromParams				0.0%
nofx/logger/logger.go:142:		Shutdown				0.0%
nofx/logger/logger.go:154:		WithFields				0.0%
nofx/logger/logger.go:159:		WithField				0.0%
nofx/logger/logger.go:164:		Debug					0.0%
nofx/logger/logger.go:168:		Info					0.0%
nofx/logger/logger.go:172:		Warn					0.0%
nofx/logger/logger.go:176:		Debugf					0.0%
nofx/logger/logger.go:180:		Infof					0.0%
nofx/logger/logger.go:184:		Warnf					0.0%
nofx/logger/logger.go:188:		Error					0.0%
nofx/logger/logger.go:192:		Errorf					0.0%
nofx/logger/logger.go:196:		Fatal					0.0%
nofx/logger/logger.go:200:		Fatalf					0.0%
nofx/logger/logger.go:204:		Panic					0.0%
nofx/logger/logger.go:208:		Panicf					0.0%
nofx/logger/telegram_hook.go:19:	NewTelegramHook				0.0%
nofx/logger/telegram_hook.go:44:	Levels					0.0%
nofx/logger/telegram_hook.go:52:	Fire					0.0%
nofx/logger/telegram_hook.go:67:	formatMessage				0.0%
nofx/logger/telegram_hook.go:109:	getLevelEmoji				0.0%
nofx/logger/telegram_hook.go:129:	escapeMarkdown				0.0%
nofx/logger/telegram_hook.go:154:	Stop					0.0%
nofx/logger/telegram_sender.go:24:	NewTelegramSender			0.0%
nofx/logger/telegram_sender.go:49:	Start					0.0%
nofx/logger/telegram_sender.go:55:	SendAsync				0.0%
nofx/logger/telegram_sender.go:66:	listenAndSend				0.0%
nofx/logger/telegram_sender.go:85:	sendWithRetry				0.0%
nofx/logger/telegram_sender.go:106:	send					0.0%
nofx/logger/telegram_sender.go:115:	Stop					0.0%
nofx/main.go:42:			loadConfigFile				0.0%
nofx/main.go:65:			syncConfigToDatabase			0.0%
nofx/main.go:119:			loadBetaCodesToDatabase			0.0%
nofx/main.go:153:			main					0.0%
nofx/manager/trader_manager.go:32:	NewTraderManager			100.0%
nofx/manager/trader_manager.go:42:	LoadTradersFromDatabase			0.0%
nofx/manager/trader_manager.go:185:	addTraderFromDB				0.0%
nofx/manager/trader_manager.go:289:	AddTraderFromDB				0.0%
nofx/manager/trader_manager.go:393:	GetTrader				83.3%
nofx/manager/trader_manager.go:405:	GetAllTraders				0.0%
nofx/manager/trader_manager.go:417:	GetTraderIDs				0.0%
nofx/manager/trader_manager.go:429:	StartAll				0.0%
nofx/manager/trader_manager.go:445:	StopAll					0.0%
nofx/manager/trader_manager.go:456:	GetComparisonData			0.0%
nofx/manager/trader_manager.go:493:	GetCompetitionData			0.0%
nofx/manager/trader_manager.go:557:	getConcurrentTraderData			0.0%
nofx/manager/trader_manager.go:656:	GetTopTradersData			0.0%
nofx/manager/trader_manager.go:685:	isUserTrader				0.0%
nofx/manager/trader_manager.go:699:	containsUserPrefix			0.0%
nofx/manager/trader_manager.go:715:	LoadUserTraders				0.0%
nofx/manager/trader_manager.go:859:	LoadTraderByID				0.0%
nofx/manager/trader_manager.go:1001:	loadSingleTrader			0.0%
nofx/manager/trader_manager.go:1095:	RemoveTrader				100.0%
nofx/market/api_client.go:22:		NewAPIClient				0.0%
nofx/market/api_client.go:38:		GetExchangeInfo				0.0%
nofx/market/api_client.go:59:		GetKlines				0.0%
nofx/market/api_client.go:103:		parseKline				0.0%
nofx/market/api_client.go:126:		GetCurrentPrice				0.0%
nofx/market/combined_streams.go:23:	NewCombinedStreamsClient		0.0%
nofx/market/combined_streams.go:32:	Connect					0.0%
nofx/market/combined_streams.go:54:	BatchSubscribeKlines			0.0%
nofx/market/combined_streams.go:80:	splitIntoBatches			0.0%
nofx/market/combined_streams.go:95:	subscribeStreams			0.0%
nofx/market/combined_streams.go:113:	readMessages				0.0%
nofx/market/combined_streams.go:140:	handleCombinedMessage			0.0%
nofx/market/combined_streams.go:164:	AddSubscriber				0.0%
nofx/market/combined_streams.go:172:	handleReconnect				0.0%
nofx/market/combined_streams.go:186:	Close					0.0%
nofx/market/data.go:28:			Get					0.0%
nofx/market/data.go:116:		calculateEMA				90.0%
nofx/market/data.go:138:		calculateMACD				80.0%
nofx/market/data.go:152:		calculateRSI				95.7%
nofx/market/data.go:196:		calculateATR				100.0%
nofx/market/data.go:230:		calculateIntradaySeries			100.0%
nofx/market/data.go:280:		calculateLongerTermData			0.0%
nofx/market/data.go:326:		getOpenInterestData			0.0%
nofx/market/data.go:360:		getFundingRate				0.0%
nofx/market/data.go:412:		Format					0.0%
nofx/market/data.go:489:		formatPriceWithDynamicPrecision		0.0%
nofx/market/data.go:519:		formatFloatSlice			0.0%
nofx/market/data.go:528:		Normalize				0.0%
nofx/market/data.go:537:		parseFloat				0.0%
nofx/market/data.go:554:		isStaleData				100.0%
nofx/market/monitor.go:37:		NewWSMonitor				0.0%
nofx/market/monitor.go:47:		Initialize				0.0%
nofx/market/monitor.go:78:		initializeHistoricalData		0.0%
nofx/market/monitor.go:119:		Start					0.0%
nofx/market/monitor.go:142:		subscribeSymbol				0.0%
nofx/market/monitor.go:151:		subscribeAll				0.0%
nofx/market/monitor.go:170:		handleKlineData				0.0%
nofx/market/monitor.go:181:		getKlineDataMap				0.0%
nofx/market/monitor.go:192:		processKlineUpdate			0.0%
nofx/market/monitor.go:235:		GetCurrentKlines			0.0%
nofx/market/monitor.go:270:		Close					0.0%
nofx/market/websocket_client.go:71:	NewWSClient				0.0%
nofx/market/websocket_client.go:79:	Connect					0.0%
nofx/market/websocket_client.go:101:	SubscribeKline				0.0%
nofx/market/websocket_client.go:106:	SubscribeTicker				0.0%
nofx/market/websocket_client.go:111:	SubscribeMiniTicker			0.0%
nofx/market/websocket_client.go:116:	subscribe				0.0%
nofx/market/websocket_client.go:139:	readMessages				0.0%
nofx/market/websocket_client.go:166:	handleMessage				0.0%
nofx/market/websocket_client.go:186:	handleReconnect				0.0%
nofx/market/websocket_client.go:200:	AddSubscriber				0.0%
nofx/market/websocket_client.go:208:	RemoveSubscriber			0.0%
nofx/market/websocket_client.go:214:	Close					0.0%
nofx/mcp/client.go:58:			New					0.0%
nofx/mcp/client.go:80:			NewClient				100.0%
nofx/mcp/client.go:116:			SetAPIKey				0.0%
nofx/mcp/client.go:132:			SetTimeout				100.0%
nofx/mcp/client.go:137:			CallWithMessages			100.0%
nofx/mcp/client.go:177:			setAuthHeader				100.0%
nofx/mcp/client.go:181:			buildMCPRequestBody			100.0%
nofx/mcp/client.go:209:			marshalRequestBody			75.0%
nofx/mcp/client.go:217:			parseMCPResponse			83.3%
nofx/mcp/client.go:237:			buildUrl				100.0%
nofx/mcp/client.go:244:			buildRequest				83.3%
nofx/mcp/client.go:260:			call					88.5%
nofx/mcp/client.go:314:			String					100.0%
nofx/mcp/client.go:320:			isRetryableError			100.0%
nofx/mcp/client.go:350:			CallWithRequest				54.5%
nofx/mcp/client.go:396:			callWithRequest				75.0%
nofx/mcp/client.go:448:			buildRequestBodyFromRequest		76.0%
nofx/mcp/config.go:37:			DefaultConfig				100.0%
nofx/mcp/config.go:54:			getEnvInt				50.0%
nofx/mcp/config.go:64:			getEnvString				0.0%
nofx/mcp/deepseek_client.go:20:		NewDeepSeekClient			100.0%
nofx/mcp/deepseek_client.go:36:		NewDeepSeekClientWithOptions		100.0%
nofx/mcp/deepseek_client.go:61:		SetAPIKey				100.0%
nofx/mcp/deepseek_client.go:81:		setAuthHeader				100.0%
nofx/mcp/logger.go:17:			Debugf					0.0%
nofx/mcp/logger.go:21:			Infof					0.0%
nofx/mcp/logger.go:25:			Warnf					0.0%
nofx/mcp/logger.go:29:			Errorf					0.0%
nofx/mcp/logger.go:36:			Debugf					0.0%
nofx/mcp/logger.go:37:			Infof					0.0%
nofx/mcp/logger.go:38:			Warnf					0.0%
nofx/mcp/logger.go:39:			Errorf					0.0%
nofx/mcp/logger.go:42:			NewNoopLogger				0.0%
nofx/mcp/options.go:19:			WithLogger				100.0%
nofx/mcp/options.go:30:			WithHTTPClient				100.0%
nofx/mcp/options.go:44:			WithTimeout				100.0%
nofx/mcp/options.go:55:			WithMaxRetries				100.0%
nofx/mcp/options.go:65:			WithRetryWaitBase			100.0%
nofx/mcp/options.go:79:			WithMaxTokens				100.0%
nofx/mcp/options.go:89:			WithTemperature				100.0%
nofx/mcp/options.go:100:		WithAPIKey				100.0%
nofx/mcp/options.go:107:		WithBaseURL				100.0%
nofx/mcp/options.go:114:		WithModel				100.0%
nofx/mcp/options.go:121:		WithProvider				100.0%
nofx/mcp/options.go:128:		WithUseFullURL				100.0%
nofx/mcp/options.go:142:		WithDeepSeekConfig			100.0%
nofx/mcp/options.go:155:		WithQwenConfig				100.0%
nofx/mcp/qwen_client.go:20:		NewQwenClient				100.0%
nofx/mcp/qwen_client.go:36:		NewQwenClientWithOptions		100.0%
nofx/mcp/qwen_client.go:61:		SetAPIKey				100.0%
nofx/mcp/qwen_client.go:81:		setAuthHeader				100.0%
nofx/mcp/request.go:43:			NewMessage				0.0%
nofx/mcp/request.go:51:			NewSystemMessage			100.0%
nofx/mcp/request.go:59:			NewUserMessage				100.0%
nofx/mcp/request.go:67:			NewAssistantMessage			100.0%
nofx/mcp/request_builder.go:30:		NewRequestBuilder			100.0%
nofx/mcp/request_builder.go:42:		WithModel				0.0%
nofx/mcp/request_builder.go:48:		WithStream				0.0%
nofx/mcp/request_builder.go:58:		WithSystemPrompt			100.0%
nofx/mcp/request_builder.go:66:		WithUserPrompt				100.0%
nofx/mcp/request_builder.go:74:		AddSystemMessage			100.0%
nofx/mcp/request_builder.go:79:		AddUserMessage				100.0%
nofx/mcp/request_builder.go:84:		AddAssistantMessage			100.0%
nofx/mcp/request_builder.go:92:		AddMessage				0.0%
nofx/mcp/request_builder.go:100:	AddMessages				0.0%
nofx/mcp/request_builder.go:106:	AddConversationHistory			100.0%
nofx/mcp/request_builder.go:112:	ClearMessages				0.0%
nofx/mcp/request_builder.go:123:	WithTemperature				42.9%
nofx/mcp/request_builder.go:138:	WithMaxTokens				100.0%
nofx/mcp/request_builder.go:147:	WithTopP				100.0%
nofx/mcp/request_builder.go:156:	WithFrequencyPenalty			100.0%
nofx/mcp/request_builder.go:165:	WithPresencePenalty			100.0%
nofx/mcp/request_builder.go:174:	WithStopSequences			100.0%
nofx/mcp/request_builder.go:180:	AddStopSequence				0.0%
nofx/mcp/request_builder.go:192:	AddTool					100.0%
nofx/mcp/request_builder.go:198:	AddFunction				100.0%
nofx/mcp/request_builder.go:215:	WithToolChoice				100.0%
nofx/mcp/request_builder.go:225:	Build					100.0%
nofx/mcp/request_builder.go:263:	MustBuild				75.0%
nofx/mcp/request_builder.go:276:	ForChat					100.0%
nofx/mcp/request_builder.go:288:	ForCodeGeneration			100.0%
nofx/mcp/request_builder.go:302:	ForCreativeWriting			100.0%
nofx/pool/coin_pool.go:72:		SetCoinPoolAPI				0.0%
nofx/pool/coin_pool.go:77:		SetOITopAPI				0.0%
nofx/pool/coin_pool.go:82:		SetUseDefaultCoins			0.0%
nofx/pool/coin_pool.go:87:		SetDefaultCoins				0.0%
nofx/pool/coin_pool.go:95:		GetCoinPool				0.0%
nofx/pool/coin_pool.go:148:		fetchCoinPool				0.0%
nofx/pool/coin_pool.go:195:		saveCoinPoolCache			0.0%
nofx/pool/coin_pool.go:222:		loadCoinPoolCache			0.0%
nofx/pool/coin_pool.go:254:		GetAvailableCoins			0.0%
nofx/pool/coin_pool.go:277:		GetTopRatedCoins			0.0%
nofx/pool/coin_pool.go:320:		normalizeSymbol				0.0%
nofx/pool/coin_pool.go:336:		trimSpaces				0.0%
nofx/pool/coin_pool.go:346:		toUpper					0.0%
nofx/pool/coin_pool.go:358:		endsWith				0.0%
nofx/pool/coin_pool.go:366:		convertSymbolsToCoins			0.0%
nofx/pool/coin_pool.go:422:		GetOITopPositions			0.0%
nofx/pool/coin_pool.go:469:		fetchOITop				0.0%
nofx/pool/coin_pool.go:511:		saveOITopCache				0.0%
nofx/pool/coin_pool.go:537:		loadOITopCache				0.0%
nofx/pool/coin_pool.go:567:		GetOITopSymbols				0.0%
nofx/pool/coin_pool.go:591:		GetMergedCoinPool			0.0%
nofx/scripts/migrate_encryption.go:14:	main					0.0%
nofx/scripts/migrate_encryption.go:69:	migrateExchanges			0.0%
nofx/scripts/migrate_encryption.go:151:	migrateAIModels				0.0%
nofx/trader/aster_trader.go:54:		NewAsterTrader				87.5%
nofx/trader/aster_trader.go:85:		genNonce				100.0%
nofx/trader/aster_trader.go:90:		getPrecision				89.3%
nofx/trader/aster_trader.go:154:	roundToTickSize				80.0%
nofx/trader/aster_trader.go:167:	formatPrice				57.1%
nofx/trader/aster_trader.go:184:	formatQuantity				57.1%
nofx/trader/aster_trader.go:201:	formatFloatWithPrecision		100.0%
nofx/trader/aster_trader.go:213:	normalizeAndStringify			71.4%
nofx/trader/aster_trader.go:226:	normalize				52.0%
nofx/trader/aster_trader.go:270:	sign					86.2%
nofx/trader/aster_trader.go:331:	request					55.0%
nofx/trader/aster_trader.go:374:	doRequest				80.0%
nofx/trader/aster_trader.go:435:	GetBalance				86.4%
nofx/trader/aster_trader.go:523:	GetPositions				76.9%
nofx/trader/aster_trader.go:577:	OpenLong				71.4%
nofx/trader/aster_trader.go:644:	OpenShort				71.4%
nofx/trader/aster_trader.go:711:	CloseLong				71.1%
nofx/trader/aster_trader.go:793:	CloseShort				71.1%
nofx/trader/aster_trader.go:876:	SetMarginMode				40.0%
nofx/trader/aster_trader.go:923:	SetLeverage				100.0%
nofx/trader/aster_trader.go:934:	GetMarketPrice				78.6%
nofx/trader/aster_trader.go:961:	SetStopLoss				82.4%
nofx/trader/aster_trader.go:1002:	SetTakeProfit				82.4%
nofx/trader/aster_trader.go:1043:	CancelStopLossOrders			40.0%
nofx/trader/aster_trader.go:1102:	CancelTakeProfitOrders			40.0%
nofx/trader/aster_trader.go:1161:	CancelAllOrders				100.0%
nofx/trader/aster_trader.go:1171:	CancelStopOrders			43.5%
nofx/trader/aster_trader.go:1226:	FormatQuantity				75.0%
nofx/trader/auto_trader.go:113:		NewAutoTrader				0.0%
nofx/trader/auto_trader.go:242:		Run					0.0%
nofx/trader/auto_trader.go:281:		Stop					0.0%
nofx/trader/auto_trader.go:292:		runCycle				0.0%
nofx/trader/auto_trader.go:482:		buildTradingContext			49.2%
nofx/trader/auto_trader.go:638:		executeDecisionWithRecord		50.0%
nofx/trader/auto_trader.go:663:		executeOpenLongWithRecord		84.2%
nofx/trader/auto_trader.go:743:		executeOpenShortWithRecord		84.2%
nofx/trader/auto_trader.go:823:		executeCloseLongWithRecord		83.3%
nofx/trader/auto_trader.go:849:		executeCloseShortWithRecord		83.3%
nofx/trader/auto_trader.go:875:		executeUpdateStopLossWithRecord		76.1%
nofx/trader/auto_trader.go:959:		executeUpdateTakeProfitWithRecord	76.1%
nofx/trader/auto_trader.go:1043:	executePartialCloseWithRecord		64.2%
nofx/trader/auto_trader.go:1170:	GetID					100.0%
nofx/trader/auto_trader.go:1175:	GetName					100.0%
nofx/trader/auto_trader.go:1180:	GetAIModel				0.0%
nofx/trader/auto_trader.go:1185:	GetExchange				0.0%
nofx/trader/auto_trader.go:1190:	SetCustomPrompt				100.0%
nofx/trader/auto_trader.go:1195:	SetOverrideBasePrompt			0.0%
nofx/trader/auto_trader.go:1200:	SetSystemPromptTemplate			100.0%
nofx/trader/auto_trader.go:1205:	GetSystemPromptTemplate			100.0%
nofx/trader/auto_trader.go:1210:	GetDecisionLogger			0.0%
nofx/trader/auto_trader.go:1215:	GetStatus				75.0%
nofx/trader/auto_trader.go:1239:	GetAccountInfo				66.7%
nofx/trader/auto_trader.go:1329:	GetPositions				90.5%
nofx/trader/auto_trader.go:1378:	calculatePnLPercentage			100.0%
nofx/trader/auto_trader.go:1387:	sortDecisionsByPriority			87.5%
nofx/trader/auto_trader.go:1425:	getCandidateCoins			95.7%
nofx/trader/auto_trader.go:1483:	normalizeSymbol				100.0%
nofx/trader/auto_trader.go:1496:	startDrawdownMonitor			0.0%
nofx/trader/auto_trader.go:1519:	checkPositionDrawdown			100.0%
nofx/trader/auto_trader.go:1595:	emergencyClosePosition			90.9%
nofx/trader/auto_trader.go:1617:	GetPeakPnLCache				100.0%
nofx/trader/auto_trader.go:1630:	UpdatePeakPnL				100.0%
nofx/trader/auto_trader.go:1647:	ClearPeakPnLCache			100.0%
nofx/trader/binance_futures.go:22:	getBrOrderID				88.9%
nofx/trader/binance_futures.go:65:	NewFuturesTrader			88.9%
nofx/trader/binance_futures.go:90:	setDualSidePosition			44.4%
nofx/trader/binance_futures.go:112:	syncBinanceServerTime			50.0%
nofx/trader/binance_futures.go:126:	GetBalance				72.7%
nofx/trader/binance_futures.go:165:	GetPositions				78.8%
nofx/trader/binance_futures.go:219:	SetMarginMode				42.3%
nofx/trader/binance_futures.go:270:	SetLeverage				81.0%
nofx/trader/binance_futures.go:316:	OpenLong				72.7%
nofx/trader/binance_futures.go:371:	OpenShort				72.7%
nofx/trader/binance_futures.go:426:	CloseLong				75.0%
nofx/trader/binance_futures.go:481:	CloseShort				75.0%
nofx/trader/binance_futures.go:536:	CancelStopLossOrders			39.1%
nofx/trader/binance_futures.go:586:	CancelTakeProfitOrders			39.1%
nofx/trader/binance_futures.go:636:	CancelAllOrders				80.0%
nofx/trader/binance_futures.go:650:	CancelStopOrders			41.2%
nofx/trader/binance_futures.go:697:	GetMarketPrice				77.8%
nofx/trader/binance_futures.go:716:	CalculatePositionSize			100.0%
nofx/trader/binance_futures.go:724:	SetStopLoss				86.7%
nofx/trader/binance_futures.go:762:	SetTakeProfit				86.7%
nofx/trader/binance_futures.go:800:	GetMinNotional				100.0%
nofx/trader/binance_futures.go:806:	CheckMinNotional			75.0%
nofx/trader/binance_futures.go:826:	GetSymbolPrecision			76.9%
nofx/trader/binance_futures.go:851:	calculatePrecision			88.9%
nofx/trader/binance_futures.go:874:	trimTrailingZeros			57.1%
nofx/trader/binance_futures.go:894:	FormatQuantity				80.0%
nofx/trader/binance_futures.go:906:	contains				0.0%
nofx/trader/binance_futures.go:910:	stringContains				75.0%
nofx/trader/hyperliquid_trader.go:28:	NewHyperliquidTrader			22.2%
nofx/trader/hyperliquid_trader.go:133:	GetBalance				81.7%
nofx/trader/hyperliquid_trader.go:246:	GetPositions				88.2%
nofx/trader/hyperliquid_trader.go:312:	SetMarginMode				100.0%
nofx/trader/hyperliquid_trader.go:324:	SetLeverage				83.3%
nofx/trader/hyperliquid_trader.go:340:	refreshMetaIfNeeded			0.0%
nofx/trader/hyperliquid_trader.go:375:	OpenLong				81.8%
nofx/trader/hyperliquid_trader.go:433:	OpenShort				81.8%
nofx/trader/hyperliquid_trader.go:491:	CloseLong				80.0%
nofx/trader/hyperliquid_trader.go:563:	CloseShort				80.0%
nofx/trader/hyperliquid_trader.go:637:	CancelStopLossOrders			100.0%
nofx/trader/hyperliquid_trader.go:645:	CancelTakeProfitOrders			100.0%
nofx/trader/hyperliquid_trader.go:653:	CancelAllOrders				54.5%
nofx/trader/hyperliquid_trader.go:677:	CancelStopOrders			50.0%
nofx/trader/hyperliquid_trader.go:711:	GetMarketPrice				80.0%
nofx/trader/hyperliquid_trader.go:733:	SetStopLoss				90.0%
nofx/trader/hyperliquid_trader.go:770:	SetTakeProfit				90.0%
nofx/trader/hyperliquid_trader.go:807:	FormatQuantity				100.0%
nofx/trader/hyperliquid_trader.go:817:	getSzDecimals				100.0%
nofx/trader/hyperliquid_trader.go:839:	roundToSzDecimals			100.0%
nofx/trader/hyperliquid_trader.go:854:	roundPriceToSigfigs			94.4%
nofx/trader/hyperliquid_trader.go:892:	convertSymbolToHyperliquid		100.0%
nofx/trader/hyperliquid_trader.go:901:	absFloat				100.0%
nofx/trader/trader_test_suite.go:24:	NewTraderTestSuite			100.0%
nofx/trader/trader_test_suite.go:33:	Cleanup					100.0%
nofx/trader/trader_test_suite.go:41:	RunAllTests				100.0%
nofx/trader/trader_test_suite.go:70:	TestGetBalance				91.7%
nofx/trader/trader_test_suite.go:103:	TestGetPositions			92.9%
nofx/trader/trader_test_suite.go:140:	TestGetMarketPrice			100.0%
nofx/trader/trader_test_suite.go:179:	TestSetLeverage				85.7%
nofx/trader/trader_test_suite.go:213:	TestSetMarginMode			85.7%
nofx/trader/trader_test_suite.go:247:	TestFormatQuantity			90.9%
nofx/trader/trader_test_suite.go:291:	TestCancelAllOrders			85.7%
nofx/trader/trader_test_suite.go:321:	TestOpenLong				92.3%
nofx/trader/trader_test_suite.go:370:	TestOpenShort				92.3%
nofx/trader/trader_test_suite.go:419:	TestCloseLong				100.0%
nofx/trader/trader_test_suite.go:462:	TestCloseShort				100.0%
nofx/trader/trader_test_suite.go:509:	TestSetStopLoss				85.7%
nofx/trader/trader_test_suite.go:549:	TestSetTakeProfit			85.7%
nofx/trader/trader_test_suite.go:589:	TestCancelStopOrders			85.7%
nofx/trader/trader_test_suite.go:615:	TestCancelStopLossOrders		85.7%
nofx/trader/trader_test_suite.go:641:	TestCancelTakeProfitOrders		85.7%
total:					(statements)				32.1%

Coverage Guidelines

  • 🟢 >= 80%: Excellent
  • 🟡 >= 60%: Good
  • 🟠 >= 40%: Fair
  • 🔴 < 40%: Needs improvement

This is an automated coverage report. The coverage requirement is advisory and does not block PR merging.

@github-actions

Copy link
Copy Markdown

🐳 Docker Build Check Results

AMD64 builds: ✅ success
ARM64 build (native runner): ✅ success

🎉 All Docker builds passed!

✨ Using GitHub native ARM64 runners - 3x faster than emulation!

After merge, full multi-arch builds will run in ~10-12 minutes.

Checked: Backend (amd64 + arm64 native), Frontend (amd64) | Powered by GitHub ARM64 Runners

@github-actions

Copy link
Copy Markdown

🤖 Advisory Check Results

These are advisory checks to help improve code quality. They won't block your PR from being merged.

📋 PR Information

Title Format: ⚠️ Suggestion - Consider using type(scope): description

Recommended format

Valid types: feat, fix, docs, style, refactor, perf, test, chore, ci, security, build

Examples:

  • feat(trader): add new trading strategy
  • fix(api): resolve authentication issue
  • docs: update README

PR Size: 🔴 Large (6814 lines: +5465 -1349)

💡 Suggestion: This is a large PR. Consider breaking it into smaller, focused PRs for easier review.

🔧 Backend Checks

Go Formatting: ✅ Good
Go Vet: ✅ Good
Tests: ✅ Passed

Fix locally:

go fmt ./...      # Format code
go vet ./...      # Check for issues
go test ./...     # Run tests

⚛️ Frontend Checks

Build & Type Check: ✅ Success

Fix locally:

cd web
npm run build  # Test build (includes type checking)

📖 Resources

Questions? 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.

* improve(interface): replace with interface

* feat(mcp): 添加构建器模式支持

新增功能:
- RequestBuilder 构建器,支持流式 API
- 多轮对话支持(AddAssistantMessage)
- Function Calling / Tools 支持
- 精细参数控制(temperature, top_p, penalties 等)
- 3个预设场景(Chat, CodeGen, CreativeWriting)
- 完整的测试套件(19个新测试)

修复问题:
- Config 字段未使用(MaxRetries、Temperature 等)
- DeepSeek/Qwen SetAPIKey 的冗余 nil 检查

向后兼容:
- 保留 CallWithMessages API
- 新增 CallWithRequest API

测试:
- 81 个测试全部通过
- 覆盖率 80.6%

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

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: zbhan <zbhan@freewheel.tv>
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

⚠️ PR Title Format Suggestion

Your PR title doesn't follow the Conventional Commits format, but this won't block your PR from being merged.

Current title: Merge dev to main

Recommended format: type(scope): description

Valid types:

feat, fix, docs, style, refactor, perf, test, chore, ci, security, build

Common scopes (optional):

exchange, trader, ai, api, ui, frontend, backend, security, deps, workflow, github, actions, config, docker, build, release

Examples:

  • feat(trader): add new trading strategy
  • fix(api): resolve authentication issue
  • docs: update README
  • chore(deps): update dependencies
  • ci(workflow): improve GitHub Actions

Note: This is a suggestion to improve consistency. Your PR can still be reviewed and merged.


This is an automated comment. You can update the PR title anytime.

@github-actions

Copy link
Copy Markdown

🚨 This PR is large (>12978 lines changed). Please consider breaking it into smaller, focused PRs for easier review.

@github-actions

Copy link
Copy Markdown

🤖 Advisory Check Results

These are advisory checks to help improve code quality. They won't block your PR from being merged.

📋 PR Information

Title Format: ⚠️ Suggestion - Consider using type(scope): description

Recommended format

Valid types: feat, fix, docs, style, refactor, perf, test, chore, ci, security, build

Examples:

  • feat(trader): add new trading strategy
  • fix(api): resolve authentication issue
  • docs: update README

PR Size: 🔴 Large (12978 lines: +11548 -1430)

💡 Suggestion: This is a large PR. Consider breaking it into smaller, focused PRs for easier review.

🔧 Backend Checks

Go Formatting: ⚠️ Needs formatting

Files needing formatting
mcp/client.go
mcp/config.go
mcp/deepseek_client.go
mcp/options.go
mcp/qwen_client.go
mcp/request.go
mcp/request_builder.go

Go Vet: ✅ Good
Tests: ✅ Passed

Fix locally:

go fmt ./...      # Format code
go vet ./...      # Check for issues
go test ./...     # Run tests

⚛️ Frontend Checks

Build & Type Check: ✅ Success

Fix locally:

cd web
npm run build  # Test build (includes type checking)

📖 Resources

Questions? 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.

@github-actions

Copy link
Copy Markdown

🐳 Docker Build Check Results

AMD64 builds: ✅ success
ARM64 build (native runner): ✅ success

🎉 All Docker builds passed!

✨ Using GitHub native ARM64 runners - 3x faster than emulation!

After merge, full multi-arch builds will run in ~10-12 minutes.

Checked: Backend (amd64 + arm64 native), Frontend (amd64) | Powered by GitHub ARM64 Runners

@tinkle-community
tinkle-community merged commit c0eb5f4 into main Nov 16, 2025
31 of 38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants