Skip to content

Repository files navigation

OpenMask 后端服务

交易信号管理平台后端服务

项目结构

openmask/
├── cmd/server/main.go # 入口文件
├── go.mod # Go模块配置
├── internal/
│ ├── config/ # 配置模块
│ │ ├── config.go # 配置加载
│ │ └── config_test.go # 配置测试
│ ├── models/ # 数据库模型
│ │ └── models.go # 17个数据表模型
│ ├── repository/ # 数据访问层
│ │ └── repository.go # 数据库操作
│ ├── services/ # 业务逻辑层
│ │ ├── user_service.go # 用户/鉴权服务
│ │ ├── signal_service.go # 信号中心服务
│ │ ├── trade_service.go # 交易回报服务
│ │ ├── stats_service.go # 统计分析服务
│ │ ├── content_service.go # 内容消息服务
│ │ └── *_test.go # 服务层测试
│ ├── handlers/ # API处理器
│ │ └── handlers.go # 所有HTTP接口
│ └── middleware/ # 中间件
│ └── middleware.go # 认证/日志/限流等
└── pkg/
├── utils/ # 工具函数
│ ├── crypto.go # 加密/脱敏
│ ├── response.go # 响应封装
│ └── *_test.go # 工具测试
└── errors/ # 错误处理
├── errors.go # 错误定义
└── errors_test.go # 错误测试

系统架构图

graph TB
subgraph Client ["客户端"]
A[iOS App]
B[Android App]
C[Web App]
D[交易机器人]
end
subgraph Gateway ["API 网关 / Load Balancer"]
E[ginx / Envoy]
end
subgraph Auth ["用户鉴权模块"]
F[用户注册/登录]
G[SDK Session]
H[交易账户绑定]
end
subgraph Signal ["信号中心模块"]
I[信号录入]
J[信号分发]
K[ACK确认]
end
subgraph Trade ["交易回报接收模块"]
L[开单/平单上报]
M[持仓快照<br/>10秒增量]
N[资产快照]
O[幂等性保证]
end
subgraph Stats ["统计分析模块"]
P[盈亏统计<br/>日/累计]
Q[全局排行榜]
R[策略统计]
end
subgraph Content ["内容消息模块"]
S[公告管理]
T[策略历史]
U[AI对话历史]
end
subgraph Database ["数据存储"]
V[(MySQL)]
W[(Redis)]
end
subgraph External ["外部服务"]
X[交易所 API<br/>Binance/OKX]
end
A --> E
B --> E
C --> E
D --> E
E --> F
E --> G
E --> H
E --> I
E --> L
E --> P
E --> S
F --> V
G --> V
H --> V
I --> V
L --> V
M --> V
N --> V
P --> V
Q --> V
S --> V
T --> V
U --> V
V <--> W
H --> X
Loading

数据流图

sequenceDiagram
participant Client as 客户端
participant Server as 服务端
participant DB as MySQL
participant Redis as Redis
Note over Client,Server: 认证流程
Client->>Server: POST /auth/register
Server->>DB: 创建用户
Server->>Client: {user_id, username}
Client->>Server: POST /auth/login
Server->>DB: 验证用户
Server->>DB: 创建Session
Server->>Client: {token, expires_at}
Note over Client,Server: 交易回报上报
Client->>Server: POST /trade/open (request_id)
Server->>DB: 检查request_id是否已存在
alt 幂等检查
Server->>DB: 插入订单记录
Server->>Client: {order_id}
else 已存在
Server->>Client: 返回已有记录
end
loop 每10秒增量同步
Client->>Server: POST /trade/sync
Server->>DB: 更新持仓快照
Server->>DB: 更新资产快照
Server->>Client: {message}
end
Loading

模块关系图

erDiagram
User ||--o{ UserExchangeAccount : has
User ||--o{ UserSDKSession : has
User ||--o{ Signal : creates
User ||--o{ SignalDispatchLog : receives
User ||--o{ TradeOrder : places
User ||--o{ UserPositionSnapshot : holds
User ||--o{ UserAssetSnapshot : owns
User ||--o{ UserPnlDaily : generates
User ||--o{ UserPnlTotal : accumulates
User ||--o{ GlobalRankSnapshot : appears_in
User ||--o{ AIChatHistory : chats
Signal ||--o{ SignalDispatchLog : dispatched_to
Signal ||--o{ SignalFollowRelation : followed_by
TradeOrder ||--o{ TradeFill : contains
Loading

已实现的功能

1. 账户与鉴权模块

  • 用户注册/登录
  • SDK会话管理
  • 交易账户绑定(API Key加密存储)

2. 信号中心

  • 手工信号录入
  • AI信号录入(预留)
  • 信号分发与ACK确认

3. 交易回报接收

  • 开单/平单上报
  • 持仓快照上报(每10秒增量)
  • 资产快照上报
  • 幂等性保证

4. 统计分析

  • 用户盈亏统计(日/累计)
  • 全局排行榜(按盈亏/收益率)
  • 排名更新

5. 内容消息

  • 公告管理
  • 策略信号历史
  • AI对话历史

6. 展示接口

  • 仪表盘数据
  • 订单/持仓/资产历史
  • 排行榜查询

数据库表

  • User、UserExchangeAccount、UserSDKSession
  • Signal、SignalDispatchLog、SignalFollowRelation
  • TradeOrder、TradeFill、UserPositionSnapshot、UserAssetSnapshot
  • UserPnlDaily、UserPnlTotal、GlobalRankSnapshot
  • Announcement、StrategySignalHistory、AIChatHistory

API 接口文档

通用说明

基础信息

  • 基础URL: http://localhost:8080/api/v1
  • 协议: HTTP JSON
  • 认证方式: Bearer Token (Session Token)

响应格式

// 成功响应
{
"code": 0,
"message": "success",
"data": {}
}
// 分页响应
{
"code": 0,
"message": "success",
"data": [],
"total": 100,
"page": 1,
"page_size": 20
}
// 错误响应
{
"code": 1001,
"message": "错误信息"
}

通用错误码

错误码说明
0成功
1001参数错误
1002未授权
1003禁止访问
1004资源不存在
1005资源冲突
1006用户不存在
1007用户已被禁用
1008用户名或密码错误
1009Token无效
1010Token已过期
5000服务器内部错误

请求头

Content-Type: application/json
Authorization: Bearer <session_token>
X-Device-ID: <设备ID>

一、用户与鉴权接口

1.1 用户注册

POST/auth/register

Request:

{
"username": "string", // 必填,用户名"password": "string", // 必填,密码"email": "string", // 选填,邮箱"nickname": "string"// 选填,昵称
}

Response:

{
"code": 0,
"message": "success",
"data": {
"user_id": 1,
"username": "testuser"
}
}

1.2 用户登录

POST/auth/login

Request:

{
"username": "string", // 必填"password": "string"// 必填
}

Response:

{
"code": 0,
"message": "success",
"data": {
"user_id": 1,
"username": "testuser",
"token": "uuid-token",
"expires_at": "2024-12-31T23:59:59Z"
}
}

1.3 SDK登录(Token续期)

POST/auth/sdk/login

Request:

{
"token": "string"// 必填,session token
}

Response:

{
"code": 0,
"message": "success",
"data": {
"user_id": 1,
"expires_at": "2024-12-31T23:59:59Z"
}
}

1.4 获取用户信息

GET/user/info

Headers: Authorization: Bearer <token>

Response:

{
"code": 0,
"message": "success",
"data": {
"id": 1,
"username": "testuser",
"nickname": "昵称",
"email": "email@example.com",
"avatar": "avatar_url",
"total_pnl": 1000.50,
"total_pnl_rate": 0.25,
"rank": 10,
"created_at": "2024-01-01T00:00:00Z"
}
}

1.5 绑定交易账户

POST/user/exchange/account

Headers: Authorization: Bearer <token>

Request:

{
"exchange": "binance", // 必填,交易所名称"api_key": "string", // 必填,API Key"api_secret": "string", // 必填,API Secret"account_type": "合约", // 必填,现货/合约"margin_type": "全仓", // 选填,全仓/逐仓"position_type": "单向持仓"// 选填,单向/双向
}

Response:

{
"code": 0,
"message": "success",
"data": {
"id": 1,
"exchange": "binance",
"api_key_masked": "abcd****1234",
"account_type": 2,
"status": 1
}
}

1.6 获取交易账户列表

GET/user/exchange/accounts

Headers: Authorization: Bearer <token>

Response:

{
"code": 0,
"message": "success",
"data": [
{
"id": 1,
"exchange": "binance",
"api_key_masked": "abcd****1234",
"account_type": 2,
"margin_type": 1,
"position_type": 1,
"status": 1,
"bind_time": "2024-01-01T00:00:00Z"
}
]
}

二、信号中心接口

2.1 创建信号(手工)

POST/signals

Headers: Authorization: Bearer <token>

Request:

{
"strategy_id": "str_001",
"strategy_name": "趋势策略",
"symbol": "BTCUSDT",
"side": "BUY", // BUY/SELL"position_side": "LONG", // LONG/SHORT"order_type": "MARKET", // MARKET/LIMIT"quantity": 0.01,
"price": 0, // 市价单填0"stop_price": 0, // 止损价"remark": "策略备注"
}

Response:

{
"code": 0,
"message": "success",
"data": {
"id": "sig_xxx",
"strategy_id": "str_001",
"symbol": "BTCUSDT",
"side": "BUY",
"status": 1,
"created_at": "2024-01-01T00:00:00Z"
}
}

2.2 获取信号列表

GET/signals

Query Parameters:

  • page: 页码,默认1
  • page_size: 每页数量,默认20

Response:

{
"code": 0,
"message": "success",
"data": [],
"total": 100,
"page": 1,
"page_size": 20
}

2.3 获取待执行信号

GET/signals/pending

Query Parameters:

  • limit: 数量限制,默认20

2.4 获取信号详情

GET/signals/:id

2.5 确认收到信号

POST/signals/:id/ack

Headers: Authorization: Bearer <token>

Response:

{
"code": 0,
"message": "success",
"data": {
"message": "信号已确认"
}
}

三、交易回报接口

3.1 上报开单

POST/trade/open

Headers: Authorization: Bearer <token>

Request:

{
"request_id": "unique_req_id", // 必填,幂等ID"order_id": "order_123",
"symbol": "BTCUSDT",
"side": "BUY",
"position_side": "LONG",
"order_type": "MARKET",
"quantity": 0.01,
"price": 50000.00,
"filled_quantity": 0.01,
"filled_price": 50000.00,
"commission": 0.00001,
"remark": "开仓备注"
}

3.2 上报平单

POST/trade/close

Headers: Authorization: Bearer <token>

Request:

{
"request_id": "unique_req_id", // 必填,幂等ID"order_id": "order_456",
"symbol": "BTCUSDT",
"side": "SELL",
"position_side": "LONG",
"order_type": "MARKET",
"quantity": 0.01,
"price": 51000.00,
"filled_quantity": 0.01,
"filled_price": 51000.00,
"commission": 0.00001,
"realized_pnl": 10.00,
"remark": "平仓备注"
}

3.3 上报失败订单

POST/trade/fail

Headers: Authorization: Bearer <token>

Request:

{
"request_id": "unique_req_id",
"order_id": "order_789",
"symbol": "BTCUSDT",
"error_code": "INSUFFICIENT_BALANCE",
"error_msg": "余额不足"
}

3.4 上报持仓快照

POST/trade/position/snapshot

Headers: Authorization: Bearer <token>

Request:

{
"request_id": "unique_req_id",
"symbol": "BTCUSDT",
"position_side": "LONG",
"quantity": 0.01,
"entry_price": 50000.00,
"mark_price": 51000.00,
"unrealized_pnl": 10.00,
"leverage": 10
}

3.5 上报资产快照

POST/trade/asset/snapshot

Headers: Authorization: Bearer <token>

Request:

{
"request_id": "unique_req_id",
"total_assets": 10000.00,
"total_pnl": 100.00,
"available_balance": 5000.00,
"frozen_balance": 4900.00,
"margin_balance": 100.00
}

3.6 增量同步(每10秒)

POST/trade/sync

Headers: Authorization: Bearer <token>

Request:

{
"positions": [
{
"request_id": "pos_001",
"symbol": "BTCUSDT",
"position_side": "LONG",
"quantity": 0.01,
"entry_price": 50000.00,
"mark_price": 51000.00,
"unrealized_pnl": 10.00,
"leverage": 10
}
],
"assets": {
"request_id": "asset_001",
"total_assets": 10000.00,
"total_pnl": 100.00,
"available_balance": 5000.00,
"frozen_balance": 4900.00,
"margin_balance": 100.00
}
}

四、查询接口

4.1 获取当前持仓

GET/trade/positions

Headers: Authorization: Bearer <token>

4.2 获取订单历史

GET/trade/orders

Headers: Authorization: Bearer <token>

Query Parameters:

  • page: 页码
  • page_size: 每页数量

4.3 获取最新资产

GET/trade/asset/latest

Headers: Authorization: Bearer <token>

4.4 获取资产历史

GET/trade/asset/history

Headers: Authorization: Bearer <token>

Query Parameters:

  • page: 页码
  • page_size: 每页数量

4.5 获取成交记录

GET/trade/fills

Headers: Authorization: Bearer <token>

Query Parameters:

  • page: 页码
  • page_size: 每页数量

五、统计与排行接口

5.1 获取用户盈亏统计

GET/stats/pnl

Headers: Authorization: Bearer <token>

5.2 获取排行榜

GET/stats/rank

Query Parameters:

  • type: 排序类型 (pnl/rate)
  • limit: 数量限制,默认20

5.3 获取用户排名

GET/stats/rank/me

Headers: Authorization: Bearer <token>

5.4 更新排行榜(管理员)

POST/stats/rank/update


六、内容与消息接口

6.1 获取活跃公告

GET/announcements/active

6.2 获取公告列表

GET/announcements

Query Parameters:

  • page: 页码
  • page_size: 每页数量

6.3 获取公告详情

GET/announcements/:id

6.4 创建公告(管理员)

POST/announcements

6.5 发布公告(管理员)

POST/announcements/:id/publish

6.6 获取策略信号历史

GET/strategy/history

Query Parameters:

  • strategy_id: 策略ID
  • page: 页码
  • page_size: 每页数量

6.7 获取对话历史

GET/chat/history

Headers: Authorization: Bearer <token>

Query Parameters:

  • page: 页码
  • page_size: 每页数量

6.8 发送对话消息

POST/chat/message

Headers: Authorization: Bearer <token>

Request:

{
"session_id": "session_001",
"content": "用户消息内容"
}

七、仪表盘接口

7.1 获取仪表盘数据

GET/dashboard

Headers: Authorization: Bearer <token>

Response:

{
"code": 0,
"message": "success",
"data": {
"user": {},
"asset": {},
"positions": [],
"pnl": {},
"rank": {},
"timestamp": "2024-01-01T00:00:00Z"
}
}

7.2 健康检查

GET/health


客户端对接手册

快速开始

1. 初始化配置

确保服务端已配置以下环境变量或配置文件:

# 数据库配置
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=password
DB_NAME=openmask
# Redis配置(可选)
REDIS_HOST=localhost
REDIS_PORT=6379
# 服务端口
SERVER_PORT=8080

2. 认证流程

┌─────────────┐ POST /api/v1/auth/register ┌─────────────┐
│ │ ─────────────────────────────────► │ │
│ 客户端 │ │ 服务端 │
│ │ ◄───────────────────────────────── │ │
└─────────────┘ {user_id, username} └─────────────┘
│ POST /api/v1/auth/login
│ ─────────────────────────────────►
│ ┌─────────────┐
│ ◄───────────────────────────────── │ 服务端 │
│ {token, expires_at} └─────────────┘
│
▼
后续请求携带 Token
Authorization: Bearer <token>

3. 交易回报上报时序

客户端(交易机器人) 服务端
│ │
│──── POST /trade/open ────────────►│
│ (request_id: "uuid") │
│◄───── {order_id, ...} ────────────│
│ │
│ (交易进行中) │
│ │
│──── POST /trade/sync ────────────►│
│ (positions + assets) │
│◄───── {message} ──────────────────│
│ │
│ (每10秒增量同步) │
│ │
│──── POST /trade/close ───────────►│
│ (request_id: "uuid") │
│◄───── {order_id, realized_pnl} ───│
│ │

4. 幂等性保证

所有交易回报接口支持幂等性,通过 request_id 防止重复提交:

// 客户端生成唯一IDrequestID:=uuid.New().String()
// 请求体包含 request_id
{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"order_id": "order_123",
...
}
// 服务端会根据 request_id 判断是否已处理// 相同 request_id 的请求会返回已存在的结果,不会重复处理

5. API Key 安全

  • 客户端提交 API Key 时使用明文
  • 服务端使用 AES-256-CFB 加密存储
  • 展示时返回脱敏后的 Key(如 abcd****1234

6. 错误处理示例

// Go 示例resp, err:=http.Post(url, "application/json", body)
iferr!=nil {
log.Fatal(err)
}
deferresp.Body.Close()
varresultmap[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
ifresult["code"].(float64) !=0 {
// 处理错误log.Printf("Error: %v", result["message"])
}
// Swift 示例
Alamofire.request(url, method:.post, parameters: params, encoding:JSONEncoding.default).responseJSON{ response iniflet json = response.result.value as?[String:Any]{ifjson["code"]as!Int!=0{print("Error: \(json["message"]!)")}}}
// Kotlin 示例RetrofitClient.api.login(request)
.enqueue(object:Callback<LoginResponse> {
overridefunonResponse(call:Call<LoginResponse>, response:Response<LoginResponse>) {
if (response.body()?.code !=0) {
println("Error: ${response.body()?.message}")
}
}
})

7. 常用场景

场景一:用户首次使用

  1. 调用 /auth/register 注册
  2. 调用 /auth/login 登录获取 Token
  3. 调用 /user/exchange/account 绑定交易所账户

场景二:交易机器人上报

  1. 启动时调用 /auth/sdk/login 验证 Token
  2. 开仓调用 /trade/open
  3. 定时(每10秒)调用 /trade/sync 同步持仓和资产
  4. 平仓调用 /trade/close
  5. 失败调用 /trade/fail

场景三:用户查看数据

  1. 登录获取 Token
  2. 调用 /dashboard 获取概览
  3. 调用 /trade/positions 查看持仓
  4. 调用 /stats/rank 查看排行榜

编译和测试

# 编译
go build -o openmask-server ./cmd/server
# 运行所有测试
go test -v -count=1 ./...
# 运行特定包的测试
go test -v -count=1 ./internal/tests/...
go test -v -count=1 ./pkg/...

测试覆盖

项目包含 46 个单元测试,覆盖以下模块:

模块测试文件测试数量
信号中心internal/tests/signal_service_test.go14
统计分析internal/tests/stats_service_test.go9
配置加载internal/config/config_test.go2
请求验证internal/services/*_test.go6
错误处理pkg/errors/errors_test.go3
加密工具pkg/utils/crypto_test.go5
响应封装pkg/utils/response_test.go7

测试文档

详细的单元测试说明请参阅:单元测试文档

该文档包含每个测试的:

  • 测试目的
  • 测试方法
  • 验证点
  • 代码示例

所有测试已通过。启动服务前需要配置MySQL数据库连接。

About

open mask imol

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages