Skip to content

EntySquare/openmask

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

4 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 protected]",
    "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 -v -count=1 ./...

# ่ฟ่กŒ็‰นๅฎšๅŒ…็š„ๆต‹่ฏ•
go test -v -count=1 ./internal/tests/...
go test -v -count=1 ./pkg/...

ๆต‹่ฏ•่ฆ†็›–

้กน็›ฎๅŒ…ๅซ 46 ไธชๅ•ๅ…ƒๆต‹่ฏ•๏ผŒ่ฆ†็›–ไปฅไธ‹ๆจกๅ—๏ผš

ๆจกๅ— ๆต‹่ฏ•ๆ–‡ไปถ ๆต‹่ฏ•ๆ•ฐ้‡
ไฟกๅทไธญๅฟƒ internal/tests/signal_service_test.go 14
็ปŸ่ฎกๅˆ†ๆž internal/tests/stats_service_test.go 9
้…็ฝฎๅŠ ่ฝฝ internal/config/config_test.go 2
่ฏทๆฑ‚้ชŒ่ฏ internal/services/*_test.go 6
้”™่ฏฏๅค„็† pkg/errors/errors_test.go 3
ๅŠ ๅฏ†ๅทฅๅ…ท pkg/utils/crypto_test.go 5
ๅ“ๅบ”ๅฐ่ฃ… pkg/utils/response_test.go 7

ๆต‹่ฏ•ๆ–‡ๆกฃ

่ฏฆ็ป†็š„ๅ•ๅ…ƒๆต‹่ฏ•่ฏดๆ˜Ž่ฏทๅ‚้˜…๏ผšๅ•ๅ…ƒๆต‹่ฏ•ๆ–‡ๆกฃ

่ฏฅๆ–‡ๆกฃๅŒ…ๅซๆฏไธชๆต‹่ฏ•็š„๏ผš

  • ๆต‹่ฏ•็›ฎ็š„
  • ๆต‹่ฏ•ๆ–นๆณ•
  • ้ชŒ่ฏ็‚น
  • ไปฃ็ ็คบไพ‹

ๆ‰€ๆœ‰ๆต‹่ฏ•ๅทฒ้€š่ฟ‡ใ€‚ๅฏๅŠจๆœๅŠกๅ‰้œ€่ฆ้…็ฝฎMySQLๆ•ฐๆฎๅบ“่ฟžๆŽฅใ€‚

About

open mask imol

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors