Skip to content

EntySquare/openmask

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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 用户名或密码错误
1009 Token无效
1010 Token已过期
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 防止重复提交:

// 客户端生成唯一ID
requestID := 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)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)

if result["code"].(float64) != 0 {
    // 处理错误
    log.Printf("Error: %v", result["message"])
}
// Swift 示例
Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default)
    .responseJSON { response in
        if let json = response.result.value as? [String: Any] {
            if json["code"] as! Int != 0 {
                print("Error: \(json["message"]!)")
            }
        }
    }
// Kotlin 示例
RetrofitClient.api.login(request)
    .enqueue(object : Callback<LoginResponse> {
        override fun onResponse(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 ./...

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

About

open mask imol

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages