646 lines
13 KiB
Markdown
646 lines
13 KiB
Markdown
# AssetManager Backend (个人资产策略管理系统)
|
||
|
||
基于 **.NET 8** + **MySQL** + **SqlSugar** 构建的高性能资产管理系统后端。采用 **Database First (数据库优先)** 模式开发,专注于量化策略管理与资产分析。
|
||
|
||
## 🛠 技术栈 (Tech Stack)
|
||
|
||
| 模块 | 技术选型 | 说明 |
|
||
| :--- | :--- | :--- |
|
||
| **核心框架** | .NET 8 Web API | 最新长期支持版,高性能 |
|
||
| **数据库** | MySQL 8.0+ | 稳定、开源的关系型数据库 |
|
||
| **ORM** | **SqlSugar** |哪怕是 .NET 老手也爱用的国产轻量级 ORM |
|
||
| **架构模式** | Repository Pattern | 仓储模式,解耦业务与数据访问 |
|
||
| **接口文档** | Swagger / Knife4j | 在线接口调试 |
|
||
|
||
## 📂 项目结构 (Project Structure)
|
||
|
||
```text
|
||
AssetManager
|
||
├── src
|
||
│ ├── AssetManager.API # [入口层] Controllers, DTOs, 全局Filter, IOC配置
|
||
│ ├── AssetManager.Services # [业务层] 核心逻辑 (计算盈亏, 策略信号, 校验)
|
||
│ ├── AssetManager.Repository # [数据层] SqlSugar 仓储实现, UnitOfWork
|
||
│ ├── AssetManager.Models # [实体层] POCO实体 (由数据库自动生成)
|
||
│ └── AssetManager.Infrastructure # [基础层] 常用工具类, 外部API调用
|
||
└── AssetManager.sln
|
||
```
|
||
|
||
## 📊 策略引擎 (Strategy Engine)
|
||
|
||
### 功能介绍
|
||
|
||
策略引擎是系统的核心组件,负责根据配置的策略参数计算交易信号。支持以下三种策略类型:
|
||
|
||
1. **双均线策略 (ma_trend)** - 经典的趋势跟踪策略,通过短期均线和长期均线的交叉产生买卖信号
|
||
2. **吊灯止损策略 (chandelier_exit)** - 趋势跟踪止损策略,通过计算最高价/最低价和 ATR(平均真实波幅)来设置止损止盈位
|
||
3. **风险平价策略 (risk_parity)** - 资产配置策略,通过调整各资产权重使每个资产对组合的风险贡献相等
|
||
|
||
### 策略配置示例
|
||
|
||
#### 1. 双均线策略 (ma_trend)
|
||
|
||
```json
|
||
{
|
||
"maType": "SMA", // 均线类型:SMA(简单移动平均) / EMA(指数移动平均)
|
||
"shortPeriod": 20, // 短期均线周期
|
||
"longPeriod": 60 // 长期均线周期
|
||
}
|
||
```
|
||
|
||
#### 2. 吊灯止损策略 (chandelier_exit)
|
||
|
||
```json
|
||
{
|
||
"period": 22, // 周期(通常为 22)
|
||
"multiplier": 3.0, // ATR 倍数(通常为 3.0)
|
||
"useClose": false // 是否使用收盘价计算(false 表示用最高价/最低价)
|
||
}
|
||
```
|
||
|
||
#### 3. 风险平价策略 (risk_parity)
|
||
|
||
```json
|
||
{
|
||
"lookbackPeriod": 60, // 历史数据回看周期
|
||
"rebalanceThreshold": 0.05, // 再平衡阈值(偏离度超过 5% 触发再平衡)
|
||
"assets": [ // 目标资产列表(可选,不指定则使用当前持仓)
|
||
{ "symbol": "AAPL", "targetWeight": 0.6 },
|
||
{ "symbol": "BTC/USD", "targetWeight": 0.4 }
|
||
]
|
||
}
|
||
```
|
||
|
||
## 📡 API 示例
|
||
|
||
## 🎯 策略 API (Strategy API)
|
||
|
||
### 1. 获取策略列表
|
||
|
||
**请求 URL**: `GET /api/v1/strategy/strategies`
|
||
|
||
**请求头**:
|
||
```
|
||
Authorization: Bearer {token}
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": [
|
||
{
|
||
"Id": "12345678-1234-1234-1234-1234567890ab",
|
||
"Title": "双均线策略",
|
||
"Type": "ma_trend",
|
||
"Description": "经典趋势跟踪策略",
|
||
"RiskLevel": "medium",
|
||
"Tags": ["趋势", "均线"],
|
||
"Parameters": {
|
||
"maType": "SMA",
|
||
"shortPeriod": 20,
|
||
"longPeriod": 60
|
||
},
|
||
"UserId": "user-123",
|
||
"CreatedAt": "2024-01-01T10:00:00",
|
||
"UpdatedAt": "2024-01-01T10:00:00"
|
||
},
|
||
{
|
||
"Id": "87654321-4321-4321-4321-210987654321",
|
||
"Title": "风险平价策略",
|
||
"Type": "risk_parity",
|
||
"Description": "资产配置策略",
|
||
"RiskLevel": "low",
|
||
"Tags": ["资产配置", "风险控制"],
|
||
"Parameters": {
|
||
"lookbackPeriod": 60,
|
||
"rebalanceThreshold": 0.05,
|
||
"assets": [
|
||
{ "symbol": "AAPL", "targetWeight": 0.6 },
|
||
{ "symbol": "BTC/USD", "targetWeight": 0.4 }
|
||
]
|
||
},
|
||
"UserId": "user-123",
|
||
"CreatedAt": "2024-01-02T10:00:00",
|
||
"UpdatedAt": "2024-01-02T10:00:00"
|
||
}
|
||
],
|
||
"message": "Success"
|
||
}
|
||
```
|
||
|
||
### 2. 获取单个策略详情
|
||
|
||
**请求 URL**: `GET /api/v1/strategy/{id}`
|
||
|
||
**请求头**:
|
||
```
|
||
Authorization: Bearer {token}
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"Id": "12345678-1234-1234-1234-1234567890ab",
|
||
"Title": "双均线策略",
|
||
"Type": "ma_trend",
|
||
"Description": "经典趋势跟踪策略",
|
||
"RiskLevel": "medium",
|
||
"Tags": ["趋势", "均线"],
|
||
"Parameters": {
|
||
"maType": "SMA",
|
||
"shortPeriod": 20,
|
||
"longPeriod": 60
|
||
},
|
||
"UserId": "user-123",
|
||
"CreatedAt": "2024-01-01T10:00:00",
|
||
"UpdatedAt": "2024-01-01T10:00:00"
|
||
},
|
||
"message": "Success"
|
||
}
|
||
```
|
||
|
||
### 3. 创建策略
|
||
|
||
**请求 URL**: `POST /api/v1/strategy`
|
||
|
||
**请求头**:
|
||
```
|
||
Authorization: Bearer {token}
|
||
Content-Type: application/json
|
||
```
|
||
|
||
**请求体示例**:
|
||
|
||
#### 3.1 创建双均线策略
|
||
|
||
```json
|
||
{
|
||
"name": "双均线策略",
|
||
"type": "ma_trend",
|
||
"description": "经典趋势跟踪策略",
|
||
"riskLevel": "medium",
|
||
"tags": ["趋势", "均线"],
|
||
"parameters": {
|
||
"maType": "SMA",
|
||
"shortPeriod": 20,
|
||
"longPeriod": 60
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 3.2 创建风险平价策略
|
||
|
||
```json
|
||
{
|
||
"name": "风险平价策略",
|
||
"type": "risk_parity",
|
||
"description": "资产配置策略",
|
||
"riskLevel": "low",
|
||
"tags": ["资产配置", "风险控制"],
|
||
"parameters": {
|
||
"lookbackPeriod": 60,
|
||
"rebalanceThreshold": 0.05,
|
||
"assets": [
|
||
{ "symbol": "AAPL", "targetWeight": 0.6 },
|
||
{ "symbol": "BTC/USD", "targetWeight": 0.4 }
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 3.3 创建吊灯止损策略
|
||
|
||
```json
|
||
{
|
||
"name": "吊灯止损策略",
|
||
"type": "chandelier_exit",
|
||
"description": "趋势跟踪止损策略",
|
||
"riskLevel": "high",
|
||
"tags": ["止损", "趋势"],
|
||
"parameters": {
|
||
"period": 22,
|
||
"multiplier": 3.0,
|
||
"useClose": false
|
||
}
|
||
}
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"Id": "12345678-1234-1234-1234-1234567890ab",
|
||
"Title": "双均线策略",
|
||
"Type": "ma_trend",
|
||
"Description": "经典趋势跟踪策略",
|
||
"RiskLevel": "medium",
|
||
"Tags": ["趋势", "均线"],
|
||
"Parameters": {
|
||
"maType": "SMA",
|
||
"shortPeriod": 20,
|
||
"longPeriod": 60
|
||
},
|
||
"UserId": "user-123",
|
||
"CreatedAt": "2024-01-01T10:00:00",
|
||
"UpdatedAt": "2024-01-01T10:00:00"
|
||
},
|
||
"message": "Strategy created successfully"
|
||
}
|
||
```
|
||
|
||
### 4. 更新策略
|
||
|
||
**请求 URL**: `PUT /api/v1/strategy/{id}`
|
||
|
||
**请求头**:
|
||
```
|
||
Authorization: Bearer {token}
|
||
Content-Type: application/json
|
||
```
|
||
|
||
**请求体示例**:
|
||
|
||
```json
|
||
{
|
||
"name": "双均线策略(更新)",
|
||
"type": "ma_trend",
|
||
"parameters": {
|
||
"maType": "EMA",
|
||
"shortPeriod": 15,
|
||
"longPeriod": 50
|
||
}
|
||
}
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"Id": "12345678-1234-1234-1234-1234567890ab",
|
||
"Title": "双均线策略(更新)",
|
||
"Type": "ma_trend",
|
||
"Description": "经典趋势跟踪策略",
|
||
"RiskLevel": "medium",
|
||
"Tags": ["趋势", "均线"],
|
||
"Parameters": {
|
||
"maType": "EMA",
|
||
"shortPeriod": 15,
|
||
"longPeriod": 50
|
||
},
|
||
"UserId": "user-123",
|
||
"CreatedAt": "2024-01-01T10:00:00",
|
||
"UpdatedAt": "2024-01-15T14:30:00"
|
||
},
|
||
"message": "Strategy updated successfully"
|
||
}
|
||
```
|
||
|
||
### 5. 删除策略
|
||
|
||
**请求 URL**: `DELETE /api/v1/strategy/{id}`
|
||
|
||
**请求头**:
|
||
```
|
||
Authorization: Bearer {token}
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"id": "12345678-1234-1234-1234-1234567890ab",
|
||
"status": "deleted"
|
||
},
|
||
"message": "Strategy deleted successfully"
|
||
}
|
||
```
|
||
|
||
### 错误响应格式
|
||
|
||
所有策略接口在发生错误时都会返回统一的错误格式:
|
||
|
||
```json
|
||
{
|
||
"code": 401,
|
||
"data": null,
|
||
"message": "用户未授权"
|
||
}
|
||
```
|
||
|
||
**常见错误码**:
|
||
- `401`: 用户未授权
|
||
- `404`: 策略不存在
|
||
- `500`: 服务器内部错误
|
||
|
||
## 💼 投资组合 API (Portfolio API)
|
||
|
||
### 1. 创建投资组合
|
||
|
||
**请求 URL**: `POST /api/v1/portfolio`
|
||
|
||
**请求头**:
|
||
```
|
||
Authorization: Bearer {token}
|
||
Content-Type: application/json
|
||
```
|
||
|
||
**请求体示例**:
|
||
|
||
```json
|
||
{
|
||
"name": "我的投资组合",
|
||
"strategyId": "strategy-123",
|
||
"currency": "USD",
|
||
"stocks": [
|
||
{
|
||
"name": "Apple Inc.",
|
||
"code": "AAPL",
|
||
"price": 150.50,
|
||
"amount": 100,
|
||
"date": "2024-01-01",
|
||
"currency": "USD"
|
||
},
|
||
{
|
||
"name": "Microsoft Corp.",
|
||
"code": "MSFT",
|
||
"price": 300.25,
|
||
"amount": 50,
|
||
"date": "2024-01-01",
|
||
"currency": "USD"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"id": "port-abc12345",
|
||
"totalValue": 30075.00,
|
||
"returnRate": 0.0,
|
||
"currency": "USD",
|
||
"createdAt": "2024-01-01 10:30:00"
|
||
},
|
||
"message": "success"
|
||
}
|
||
```
|
||
|
||
### 2. 获取投资组合列表
|
||
|
||
**请求 URL**: `GET /api/v1/portfolio`
|
||
|
||
**请求头**:
|
||
```
|
||
Authorization: Bearer {token}
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"items": [
|
||
{
|
||
"id": "port-abc12345",
|
||
"name": "我的投资组合",
|
||
"tags": "科技股",
|
||
"status": "运行中",
|
||
"statusType": "active",
|
||
"iconChar": "P",
|
||
"iconBgClass": "bg-blue-500",
|
||
"iconTextClass": "text-white",
|
||
"value": 30075.00,
|
||
"currency": "USD",
|
||
"returnRate": 0.15,
|
||
"returnType": "positive"
|
||
},
|
||
{
|
||
"id": "port-def67890",
|
||
"name": "保守组合",
|
||
"tags": "债券",
|
||
"status": "运行中",
|
||
"statusType": "active",
|
||
"iconChar": "C",
|
||
"iconBgClass": "bg-green-500",
|
||
"iconTextClass": "text-white",
|
||
"value": 50000.00,
|
||
"currency": "USD",
|
||
"returnRate": 0.08,
|
||
"returnType": "positive"
|
||
}
|
||
]
|
||
},
|
||
"message": "success"
|
||
}
|
||
```
|
||
|
||
### 3. 获取总资产情况
|
||
|
||
**请求 URL**: `GET /api/v1/portfolio/assets`
|
||
|
||
**请求头**:
|
||
```
|
||
Authorization: Bearer {token}
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"totalValue": 80075.00,
|
||
"currency": "USD",
|
||
"todayProfit": 1250.50,
|
||
"todayProfitCurrency": "USD",
|
||
"totalReturnRate": 0.12
|
||
},
|
||
"message": "success"
|
||
}
|
||
```
|
||
|
||
### 4. 获取单个投资组合详情
|
||
|
||
**请求 URL**: `GET /api/v1/portfolio/{id}`
|
||
|
||
**请求头**:
|
||
```
|
||
Authorization: Bearer {token}
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"id": "port-abc12345",
|
||
"name": "我的投资组合",
|
||
"currency": "USD",
|
||
"strategy": {
|
||
"id": "strategy-123",
|
||
"name": "双均线策略",
|
||
"description": "基于短期和长期移动平均线的趋势跟踪策略"
|
||
},
|
||
"portfolioValue": 30075.00,
|
||
"totalReturn": 0.15,
|
||
"todayProfit": 1250.50,
|
||
"todayProfitCurrency": "USD",
|
||
"positions": [
|
||
{
|
||
"id": "pos-xyz12345",
|
||
"stockCode": "AAPL",
|
||
"stockName": "Apple Inc.",
|
||
"amount": 100,
|
||
"averagePrice": 150.50,
|
||
"currentPrice": 155.00,
|
||
"totalValue": 15500.00,
|
||
"profit": 450.00,
|
||
"profitRate": 0.03,
|
||
"currency": "USD"
|
||
},
|
||
{
|
||
"id": "pos-xyz67890",
|
||
"stockCode": "MSFT",
|
||
"stockName": "Microsoft Corp.",
|
||
"amount": 50,
|
||
"averagePrice": 300.25,
|
||
"currentPrice": 291.50,
|
||
"totalValue": 14575.00,
|
||
"profit": -437.50,
|
||
"profitRate": -0.03,
|
||
"currency": "USD"
|
||
}
|
||
]
|
||
},
|
||
"message": "success"
|
||
}
|
||
```
|
||
|
||
### 5. 获取交易记录
|
||
|
||
**请求 URL**: `GET /api/v1/portfolio/transactions`
|
||
|
||
**请求头**:
|
||
```
|
||
Authorization: Bearer {token}
|
||
```
|
||
|
||
**查询参数**:
|
||
- `portfolioId` (必填): 投资组合ID
|
||
- `limit` (可选): 每页记录数,默认 10
|
||
- `offset` (可选): 偏移量,默认 0
|
||
|
||
**请求示例**:
|
||
```
|
||
GET /api/v1/portfolio/transactions?portfolioId=port-abc12345&limit=10&offset=0
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"items": [
|
||
{
|
||
"id": "trans-abc12345",
|
||
"portfolioId": "port-abc12345",
|
||
"date": "2024-01-15",
|
||
"time": "14:30:00",
|
||
"type": "buy",
|
||
"title": "买入AAPL",
|
||
"amount": 50,
|
||
"currency": "USD",
|
||
"status": "completed",
|
||
"remark": "加仓"
|
||
},
|
||
{
|
||
"id": "trans-def67890",
|
||
"portfolioId": "port-abc12345",
|
||
"date": "2024-01-10",
|
||
"time": "10:15:00",
|
||
"type": "sell",
|
||
"title": "卖出MSFT",
|
||
"amount": 25,
|
||
"currency": "USD",
|
||
"status": "completed",
|
||
"remark": "减仓"
|
||
}
|
||
],
|
||
"total": 25,
|
||
"page": 1,
|
||
"pageSize": 10
|
||
},
|
||
"message": "success"
|
||
}
|
||
```
|
||
|
||
### 6. 创建交易
|
||
|
||
**请求 URL**: `POST /api/v1/portfolio/transactions`
|
||
|
||
**请求头**:
|
||
```
|
||
Authorization: Bearer {token}
|
||
Content-Type: application/json
|
||
```
|
||
|
||
**请求体示例**:
|
||
|
||
```json
|
||
{
|
||
"portfolioId": "port-abc12345",
|
||
"type": "buy",
|
||
"stockCode": "AAPL",
|
||
"amount": 50,
|
||
"price": 155.00,
|
||
"currency": "USD",
|
||
"remark": "加仓"
|
||
}
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"id": "trans-xyz12345",
|
||
"totalAmount": 7750.00,
|
||
"status": "processing",
|
||
"createdAt": "2024-01-15 14:30:00"
|
||
},
|
||
"message": "success"
|
||
}
|
||
```
|
||
|
||
### 错误响应格式
|
||
|
||
所有接口在发生错误时都会返回统一的错误格式:
|
||
|
||
```json
|
||
{
|
||
"code": 401,
|
||
"data": null,
|
||
"message": "用户未授权"
|
||
}
|
||
```
|
||
|
||
**常见错误码**:
|
||
- `401`: 用户未授权
|
||
- `500`: 服务器内部错误 |