# v0.48 个人资产与只读交易所连接

入口：`/assets`，也可从首页或接口管理页的“我的资产”进入。

## 支持范围

| 接入方式 | 当前覆盖 | 尚未覆盖 |
| --- | --- | --- |
| Binance 全球站 | 当前用户所连账户的现货余额，可用与冻结数量 | Binance.US、资金/理财/质押/合约、其他子账户自动枚举 |
| OKX | Spot mode（acctLv=1）的交易账户币种余额 | 资金/理财/合约、多币种保证金/组合保证金模式 |
| 手工 / CSV | 用户声明的完整持仓快照，可选参考价格 | 完整成交和充提账本、成本、历史收益、税务核算 |

查询余额不等于获取整个交易所的全部资产。页面汇总仅覆盖已添加账户与支持的账户范围。账户登录是 TrendLab 登录，交易所连接使用另一组专用凭证。

## 交易所 API 填写位置

1. 登录 TrendLab，进入“我的资产”。
2. 在“添加个人账户”选择 Binance 或 OKX、填写名称。OKX 还需选择账户注册区域。
3. 填写交易所 API Key、Secret Key；OKX 另填 Passphrase。仅创建 Read / 读取权限的密钥，关闭交易、划转与提现权限。
4. 点击“保存账户”：服务器仅加密保存凭证，不访问交易所，不创建自动调度。
5. 点击该账户的“验证权限并同步”：查询时间与密钥权限，通过后才读取余额。再读取公开参考价格，保存完整快照。

同步由用户点击触发。每次尝试间隔至少60秒；网络请求总超时30秒，工作租约60秒。失败显示受控错误码，保留旧快照，不能把失败解释为零余额。交易所正常返回空余额时会保存明确的空快照。暂停或断开时会清除租约，阻断在途请求返回后的写入。

密钥权限不合格时不会继续查询余额。Binance 通过 `/sapi/v1/account/apiRestrictions` 验证；OKX 通过 `/api/v5/account/config` 的 `perm` 和 `acctLv` 验证。未识别的权限和不支持的账户模式会被拒绝。

当前固定访问以下域名，不接受用户自定义代理或地址，不跟随HTTP重定向：

- Binance 全球站：`https://api.binance.com`
- OKX 全球站：`https://openapi.okx.com`
- OKX 美国/澳大利亚注册账户：`https://us.okx.com`
- OKX 欧洲经济区注册账户：`https://eea.okx.com`

账户地域、网络可达性、IP白名单和交易所账户限制仍须在实际部署验收。当前托管环境不保证固定出口IP；需要固定IP时，应先在具有固定出口的独立部署环境测试。此版本不提供绕过地域限制或IP白名单的功能。

## 凭证与个人数据

个人资产API仅接受已登录的浏览器身份。`/api/console/wealth*` 不接受团队选择头，不通过工作区API密钥或MCP开放。账户、快照和审计的 owner 固定为当前登录用户；团队所有者、管理员和平台运营角色不因此获得其他用户的个人资产读取能力。独立客户部署仍遵循原OIDC会话与停用规则。

部署需新增专用32字节Base64环境密钥 `ASSET_KEY_ENCRYPTION_KEY`。交易所凭证使用AES-256-GCM加密，附加认证数据绑定用户、账户ID、交易所与区域。此密钥与信号/Webhook主密钥分开管理。环境密钥只放在部署平台的秘密配置中，不写入代码、浏览器、日志或部署清单。

输入框使用密码字段，不写入浏览器存储，提交后清空。普通查询和资产导出不返回原API Key、Secret、Passphrase或密文，仅显示密钥哈希指纹。数据库备份含密文，应继续使用现有客户端加密备份流程。

“轮换密钥”替换密文并要求重新验证。轮换后的新密钥须属于原交易所账户。“断开并移出汇总”清除服务器保存的凭证，保留历史快照，停止计入组合。需要再次连接时使用同一账户卡片的“重新连接”。多个API Key对应同一交易所账号时阻断重复同步。跨用户账号标识不暴露，交易所UID只以作用域哈希保存。

## 手工与CSV导入

创建“手工 / CSV”账户后，选择“查看持仓”，填写快照时间。可逐行输入币种、数量、参考价格，也可上传UTF-8 CSV。

统一表头：

```csv
asset,quantity,unit_price_usdt
```

模板是空白表头；请填写自己的真实持仓。最多200个币种、64 KiB文件。数量和价格使用普通非负十进制文本，最多15位整数、18位小数；不接受科学计数、公式、重复币种或负数。价格留空表示未知，不自动假定为零。当前不自动识别各交易所的原生CSV表头。

先点击“预览导入”，核对后“确认保存完整快照”。新快照时间须严格递增，旧快照保留；重试同一快照ID不会重复保存。保存时完整替换当前持仓视图，不能将分批明细误当完整快照。不要把同一账户同时通过手工和API加入汇总；平台无法推断用户手工填写账户与真实交易所账户是否相同。

## 估值含义

余额查询完成时间作为API快照的 asOf；OKX 的 uTime 是最后余额变化时间，不能用来判定安静账户的查询是否过期。公开价格记录其取回时间或交易所报价时间。USDT以USDT计价单位1计算；其他币种仅使用实际取得的直接USDT报价，不假定其他稳定币价格为1，不跨来源拼接或插值。

缺失报价的资产仍保留数量，市值明确标为“未计入”。行情查询失败不丢弃成功取得的余额。余额超过15分钟标为过期；已知市值仍展示保存的参考值。不同账户时间、用户手工参考价、过期和缺价可能并存，因此不将此汇总称作完整实时净值。数量保留精确字符串，市值是浮点参考估算。

此版不计算平均成本、已实现损益、累计收益或资金加权收益，未将持仓映射到策略目标，也不生成订单、划转或提现。后续需单独接入成交、手续费、充提与划转流水并对账。

## 数据、恢复与接口

每用户最多10个账户、2000个历史快照。达到上限时阻断新增历史，不静默删除。每账户可导出全部快照与SHA-256完整性校验，导出不含凭证。历史保留/删除策略待后续建设。

接口均位于 `/api/console/`，写入要求同源JSON请求、当前登录和个人所有者权限：

| 方法 / 路径 | 用途 |
| --- | --- |
| GET wealth | 读取个人账户与最近快照 |
| POST wealth/accounts | 创建手工账户或保存加密API连接 |
| POST wealth/control | 暂停、恢复或断开 |
| POST wealth/rotate | 轮换或重新连接凭证 |
| POST wealth/import | 预览确认后的完整手工/CSV持仓快照 |
| POST wealth/sync | 核验只读权限并同步一次 |
| POST wealth/export | 导出单账户全部历史快照 |

参数不接受 owner、任意接口URL、执行开关或客户端权限证据。所有写入使用修订号，网络返回后的提交再次检查登录会话、个人权限、租约及连接状态。

新增 `asset_accounts`、`asset_snapshots`，共62业务表、29迁移、42便携恢复工具文件。前一版本41个文件冻结在 `public/integration/v047/`。个人资产的工作区备份须在个人工作区下载；团队备份不包含任何成员个人资产。

离线恢复验证账户归属、币种精度、快照哈希和估值摘要。恢复后清除交易所凭证、断开连接并清除租约，保留原始持仓历史，必须主动重新连接和核验。部署回退必须保留新结构与 `personal-assets-v1`；不能直接回退到v0.47。

## 验证边界

代码、构建后HTTP与恢复测试使用明确的隔离交易所响应，不接触真实个人账户。生产可达性、真实只读密钥、固定出口IP、真实余额对账、真实客户登录和浏览器点击仍需实际验收。未完成真实账户验收之前不能把隔离测试视为已成功同步个人资产。

官方协议参考（核对日期2026-10-17）：

- https://developers.binance.com/en/docs/catalog/core-trading-wallet/api/rest-api/account
- https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/rest-api/account
- https://www.okx.com/docs-v5/

## v0.48.1 连接诊断补充

在账户卡片点击“检查服务器连通性”，只请求当前托管服务器到交易所的公共时间接口，不使用API Key、Secret或余额。此检查独立共享限流每来源6次/分钟，不创建调度。成功不代表密钥或余额通过验证；失败在公共时间接口则尚未提交认证信息。

新同步错误记录阶段、白名单路径、HTTP状态及数字错误码，刷新后仍可查看。HTTP451显示区域/服务资格限制，HTTP403保持一般访问拒绝；币安-2015只能说明密钥、IP或权限之一被拒绝，不能据此断言Secret错误。上游原文、完整签名URL和凭证不会返回或记录。Binance连接仅支持系统生成的HMAC API Key和Secret Key。

修复不清除或重建现有连接，不变更交易所权限。若公共接口被交易所拒绝，需要先确认账户服务资格与受支持的实际部署网络；更换Secret本身不能证明能解决网络拒绝。
