feat(策略): 添加策略描述、标签和风险等级字段
扩展策略模型,新增描述、标签(JSON数组)和风险等级字段 更新策略服务以处理新增字段 修改策略DTO和控制器返回更详细的策略信息 更新API文档示例
This commit is contained in:
parent
564687bc1e
commit
31c598c4bc
@ -22,6 +22,7 @@ public class PortfolioController : ControllerBase
|
|||||||
_portfolioService = portfolioService;
|
_portfolioService = portfolioService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private string GetCurrentUserId()
|
private string GetCurrentUserId()
|
||||||
{
|
{
|
||||||
return User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
return User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
||||||
|
|||||||
@ -28,6 +28,33 @@ public class StrategyController : ControllerBase
|
|||||||
return User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? throw new Exception("User not authenticated");
|
return User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? throw new Exception("User not authenticated");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private StrategyListItemDTO MapToStrategyListItemDTO(Strategy strategy)
|
||||||
|
{
|
||||||
|
List<string> tags = new List<string>();
|
||||||
|
if (!string.IsNullOrEmpty(strategy.Tags))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tags = System.Text.Json.JsonSerializer.Deserialize<List<string>>(strategy.Tags);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
return new StrategyListItemDTO
|
||||||
|
{
|
||||||
|
id = strategy.Id,
|
||||||
|
userId = strategy.UserId,
|
||||||
|
name = strategy.Alias,
|
||||||
|
type = strategy.Type,
|
||||||
|
description = strategy.Description,
|
||||||
|
tags = tags,
|
||||||
|
riskLevel = strategy.RiskLevel,
|
||||||
|
config = strategy.Config,
|
||||||
|
createdAt = strategy.CreatedAt,
|
||||||
|
updatedAt = strategy.UpdatedAt
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取策略列表
|
/// 获取策略列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -36,7 +63,7 @@ public class StrategyController : ControllerBase
|
|||||||
/// 此接口用于获取当前登录用户的所有策略列表。
|
/// 此接口用于获取当前登录用户的所有策略列表。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[HttpGet("strategies")]
|
[HttpGet("strategies")]
|
||||||
public ActionResult<ApiResponse<List<Strategy>>> GetStrategies()
|
public ActionResult<ApiResponse<List<StrategyListItemDTO>>> GetStrategies()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -44,13 +71,14 @@ public class StrategyController : ControllerBase
|
|||||||
|
|
||||||
var userId = GetCurrentUserId();
|
var userId = GetCurrentUserId();
|
||||||
var strategies = _strategyService.GetStrategies(userId);
|
var strategies = _strategyService.GetStrategies(userId);
|
||||||
|
var strategyListItems = strategies.Select(MapToStrategyListItemDTO).ToList();
|
||||||
|
|
||||||
_logger.LogInformation("Strategies retrieved successfully");
|
_logger.LogInformation("Strategies retrieved successfully");
|
||||||
|
|
||||||
return Ok(new ApiResponse<List<Strategy>>
|
return Ok(new ApiResponse<List<StrategyListItemDTO>>
|
||||||
{
|
{
|
||||||
code = AssetManager.Models.StatusCodes.Success,
|
code = AssetManager.Models.StatusCodes.Success,
|
||||||
data = strategies,
|
data = strategyListItems,
|
||||||
message = "Success"
|
message = "Success"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -58,7 +86,7 @@ public class StrategyController : ControllerBase
|
|||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error retrieving strategies");
|
_logger.LogError(ex, "Error retrieving strategies");
|
||||||
|
|
||||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<List<Strategy>>
|
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<List<StrategyListItemDTO>>
|
||||||
{
|
{
|
||||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
code = AssetManager.Models.StatusCodes.InternalServerError,
|
||||||
data = null,
|
data = null,
|
||||||
@ -76,7 +104,7 @@ public class StrategyController : ControllerBase
|
|||||||
/// 此接口用于获取指定策略的详细信息。
|
/// 此接口用于获取指定策略的详细信息。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public ActionResult<ApiResponse<Strategy>> GetStrategyById(string id)
|
public ActionResult<ApiResponse<StrategyListItemDTO>> GetStrategyById(string id)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -84,13 +112,14 @@ public class StrategyController : ControllerBase
|
|||||||
|
|
||||||
var userId = GetCurrentUserId();
|
var userId = GetCurrentUserId();
|
||||||
var strategy = _strategyService.GetStrategyById(id, userId);
|
var strategy = _strategyService.GetStrategyById(id, userId);
|
||||||
|
var strategyItem = MapToStrategyListItemDTO(strategy);
|
||||||
|
|
||||||
_logger.LogInformation($"Strategy {id} retrieved successfully");
|
_logger.LogInformation($"Strategy {id} retrieved successfully");
|
||||||
|
|
||||||
return Ok(new ApiResponse<Strategy>
|
return Ok(new ApiResponse<StrategyListItemDTO>
|
||||||
{
|
{
|
||||||
code = AssetManager.Models.StatusCodes.Success,
|
code = AssetManager.Models.StatusCodes.Success,
|
||||||
data = strategy,
|
data = strategyItem,
|
||||||
message = "Success"
|
message = "Success"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -98,7 +127,7 @@ public class StrategyController : ControllerBase
|
|||||||
{
|
{
|
||||||
_logger.LogError(ex, $"Error retrieving strategy {id}");
|
_logger.LogError(ex, $"Error retrieving strategy {id}");
|
||||||
|
|
||||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<Strategy>
|
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<StrategyListItemDTO>
|
||||||
{
|
{
|
||||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
code = AssetManager.Models.StatusCodes.InternalServerError,
|
||||||
data = null,
|
data = null,
|
||||||
@ -116,7 +145,7 @@ public class StrategyController : ControllerBase
|
|||||||
/// 此接口用于创建新的策略。
|
/// 此接口用于创建新的策略。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public ActionResult<ApiResponse<Strategy>> CreateStrategy([FromBody] CreateStrategyRequest request)
|
public ActionResult<ApiResponse<StrategyListItemDTO>> CreateStrategy([FromBody] CreateStrategyRequest request)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -124,13 +153,14 @@ public class StrategyController : ControllerBase
|
|||||||
|
|
||||||
var userId = GetCurrentUserId();
|
var userId = GetCurrentUserId();
|
||||||
var strategy = _strategyService.CreateStrategy(request, userId);
|
var strategy = _strategyService.CreateStrategy(request, userId);
|
||||||
|
var strategyItem = MapToStrategyListItemDTO(strategy);
|
||||||
|
|
||||||
_logger.LogInformation($"Strategy {strategy.Id} created successfully");
|
_logger.LogInformation($"Strategy {strategy.Id} created successfully");
|
||||||
|
|
||||||
return Ok(new ApiResponse<Strategy>
|
return Ok(new ApiResponse<StrategyListItemDTO>
|
||||||
{
|
{
|
||||||
code = AssetManager.Models.StatusCodes.Success,
|
code = AssetManager.Models.StatusCodes.Success,
|
||||||
data = strategy,
|
data = strategyItem,
|
||||||
message = "Strategy created successfully"
|
message = "Strategy created successfully"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -138,7 +168,7 @@ public class StrategyController : ControllerBase
|
|||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error creating strategy");
|
_logger.LogError(ex, "Error creating strategy");
|
||||||
|
|
||||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<Strategy>
|
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<StrategyListItemDTO>
|
||||||
{
|
{
|
||||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
code = AssetManager.Models.StatusCodes.InternalServerError,
|
||||||
data = null,
|
data = null,
|
||||||
@ -157,7 +187,7 @@ public class StrategyController : ControllerBase
|
|||||||
/// 此接口用于更新指定策略的信息。
|
/// 此接口用于更新指定策略的信息。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[HttpPut("{id}")]
|
[HttpPut("{id}")]
|
||||||
public ActionResult<ApiResponse<Strategy>> UpdateStrategy(string id, [FromBody] UpdateStrategyRequest request)
|
public ActionResult<ApiResponse<StrategyListItemDTO>> UpdateStrategy(string id, [FromBody] UpdateStrategyRequest request)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -165,13 +195,14 @@ public class StrategyController : ControllerBase
|
|||||||
|
|
||||||
var userId = GetCurrentUserId();
|
var userId = GetCurrentUserId();
|
||||||
var strategy = _strategyService.UpdateStrategy(id, request, userId);
|
var strategy = _strategyService.UpdateStrategy(id, request, userId);
|
||||||
|
var strategyItem = MapToStrategyListItemDTO(strategy);
|
||||||
|
|
||||||
_logger.LogInformation($"Strategy {id} updated successfully");
|
_logger.LogInformation($"Strategy {id} updated successfully");
|
||||||
|
|
||||||
return Ok(new ApiResponse<Strategy>
|
return Ok(new ApiResponse<StrategyListItemDTO>
|
||||||
{
|
{
|
||||||
code = AssetManager.Models.StatusCodes.Success,
|
code = AssetManager.Models.StatusCodes.Success,
|
||||||
data = strategy,
|
data = strategyItem,
|
||||||
message = "Strategy updated successfully"
|
message = "Strategy updated successfully"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -179,7 +210,7 @@ public class StrategyController : ControllerBase
|
|||||||
{
|
{
|
||||||
_logger.LogError(ex, $"Error updating strategy {id}");
|
_logger.LogError(ex, $"Error updating strategy {id}");
|
||||||
|
|
||||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<Strategy>
|
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<StrategyListItemDTO>
|
||||||
{
|
{
|
||||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
code = AssetManager.Models.StatusCodes.InternalServerError,
|
||||||
data = null,
|
data = null,
|
||||||
|
|||||||
@ -32,6 +32,24 @@ public class Strategy
|
|||||||
[SugarColumn(ColumnName = "type", Length = 50)]
|
[SugarColumn(ColumnName = "type", Length = 50)]
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 策略描述
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "description", Length = 500)]
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 策略标签 (JSON数组)
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "tags", IsJson = true)]
|
||||||
|
public string Tags { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 风险等级
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "risk_level", Length = 20)]
|
||||||
|
public string RiskLevel { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 策略配置项(周期,阈值,资产配比)
|
/// 策略配置项(周期,阈值,资产配比)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -32,11 +32,19 @@ public class PortfolioDetailResponse
|
|||||||
public string id { get; set; }
|
public string id { get; set; }
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public string currency { get; set; }
|
public string currency { get; set; }
|
||||||
|
public string status { get; set; }
|
||||||
public StrategyInfo strategy { get; set; }
|
public StrategyInfo strategy { get; set; }
|
||||||
public double portfolioValue { get; set; }
|
public double portfolioValue { get; set; }
|
||||||
public double totalReturn { get; set; }
|
public double totalReturn { get; set; }
|
||||||
public double todayProfit { get; set; }
|
public double todayProfit { get; set; }
|
||||||
|
public double historicalChange { get; set; }
|
||||||
|
public double dailyVolatility { get; set; }
|
||||||
public string todayProfitCurrency { get; set; }
|
public string todayProfitCurrency { get; set; }
|
||||||
|
public string logicModel { get; set; }
|
||||||
|
public string logicModelStatus { get; set; }
|
||||||
|
public string logicModelDescription { get; set; }
|
||||||
|
public int totalItems { get; set; }
|
||||||
|
public double totalRatio { get; set; }
|
||||||
public List<PositionItem> positions { get; set; }
|
public List<PositionItem> positions { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,12 +60,16 @@ public class PositionItem
|
|||||||
public string id { get; set; }
|
public string id { get; set; }
|
||||||
public string stockCode { get; set; }
|
public string stockCode { get; set; }
|
||||||
public string stockName { get; set; }
|
public string stockName { get; set; }
|
||||||
|
public string symbol { get; set; }
|
||||||
public int amount { get; set; }
|
public int amount { get; set; }
|
||||||
public double averagePrice { get; set; }
|
public double averagePrice { get; set; }
|
||||||
public double currentPrice { get; set; }
|
public double currentPrice { get; set; }
|
||||||
public double totalValue { get; set; }
|
public double totalValue { get; set; }
|
||||||
public double profit { get; set; }
|
public double profit { get; set; }
|
||||||
public double profitRate { get; set; }
|
public double profitRate { get; set; }
|
||||||
|
public double changeAmount { get; set; }
|
||||||
|
public double ratio { get; set; }
|
||||||
|
public double deviationRatio { get; set; }
|
||||||
public string currency { get; set; }
|
public string currency { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -71,7 +71,6 @@ public class CreateStrategyRequest
|
|||||||
public string riskLevel { get; set; }
|
public string riskLevel { get; set; }
|
||||||
public List<string> tags { get; set; }
|
public List<string> tags { get; set; }
|
||||||
public object parameters { get; set; }
|
public object parameters { get; set; }
|
||||||
public string Title { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StrategyResponse
|
public class StrategyResponse
|
||||||
@ -85,6 +84,9 @@ public class UpdateStrategyRequest
|
|||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
|
public string description { get; set; }
|
||||||
|
public string riskLevel { get; set; }
|
||||||
|
public List<string> tags { get; set; }
|
||||||
public object parameters { get; set; }
|
public object parameters { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,3 +95,17 @@ public class DeleteStrategyResponse
|
|||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string Status { get; set; }
|
public string Status { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class StrategyListItemDTO
|
||||||
|
{
|
||||||
|
public string id { get; set; }
|
||||||
|
public string userId { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
public string type { get; set; }
|
||||||
|
public string description { get; set; }
|
||||||
|
public List<string> tags { get; set; }
|
||||||
|
public string riskLevel { get; set; }
|
||||||
|
public string config { get; set; }
|
||||||
|
public DateTime createdAt { get; set; }
|
||||||
|
public DateTime updatedAt { get; set; }
|
||||||
|
}
|
||||||
|
|||||||
@ -137,34 +137,58 @@ public class PortfolioService : IPortfolioService
|
|||||||
.Where(pos => pos.PortfolioId == id)
|
.Where(pos => pos.PortfolioId == id)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
var totalValue = (double)portfolio.TotalValue;
|
||||||
|
var positionItems = positions.Select(pos =>
|
||||||
|
{
|
||||||
|
var positionValue = (double)(pos.Shares * pos.AvgPrice);
|
||||||
|
var ratio = totalValue > 0 ? (positionValue / totalValue) * 100 : 0;
|
||||||
|
// 假设目标权重为50%,计算偏离比例
|
||||||
|
var targetWeight = 50.0;
|
||||||
|
var deviationRatio = ratio - targetWeight;
|
||||||
|
|
||||||
|
return new PositionItem
|
||||||
|
{
|
||||||
|
id = pos.Id,
|
||||||
|
stockCode = pos.StockCode,
|
||||||
|
stockName = pos.StockName,
|
||||||
|
symbol = $"{pos.StockCode}.US", // 简化处理,实际应该根据市场或数据源确定
|
||||||
|
amount = (int)pos.Shares,
|
||||||
|
averagePrice = (double)pos.AvgPrice,
|
||||||
|
currentPrice = (double)pos.AvgPrice, // 实际应该从市场数据获取
|
||||||
|
totalValue = positionValue,
|
||||||
|
profit = 0, // 实际应该计算
|
||||||
|
profitRate = 0, // 实际应该计算
|
||||||
|
changeAmount = 0, // 实际应该计算
|
||||||
|
ratio = ratio,
|
||||||
|
deviationRatio = deviationRatio,
|
||||||
|
currency = pos.Currency
|
||||||
|
};
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
return new PortfolioDetailResponse
|
return new PortfolioDetailResponse
|
||||||
{
|
{
|
||||||
id = portfolio.Id,
|
id = portfolio.Id,
|
||||||
name = portfolio.Name,
|
name = portfolio.Name,
|
||||||
currency = portfolio.Currency,
|
currency = portfolio.Currency,
|
||||||
|
status = portfolio.Status, // 从数据库获取
|
||||||
strategy = new StrategyInfo
|
strategy = new StrategyInfo
|
||||||
{
|
{
|
||||||
id = portfolio.StrategyId,
|
id = portfolio.StrategyId,
|
||||||
name = "策略名称",
|
name = "策略名称",
|
||||||
description = "策略描述"
|
description = "策略描述"
|
||||||
},
|
},
|
||||||
portfolioValue = (double)portfolio.TotalValue,
|
portfolioValue = totalValue,
|
||||||
totalReturn = (double)(portfolio.TotalValue * portfolio.ReturnRate),
|
totalReturn = (double)(portfolio.TotalValue * portfolio.ReturnRate),
|
||||||
todayProfit = 0,
|
todayProfit = 0, // 实际应该计算
|
||||||
|
historicalChange = 42.82, // 实际应该计算
|
||||||
|
dailyVolatility = 1240.50, // 实际应该计算
|
||||||
todayProfitCurrency = portfolio.Currency,
|
todayProfitCurrency = portfolio.Currency,
|
||||||
positions = positions.Select(pos => new PositionItem
|
logicModel = "HFEA 风险平价逻辑", // 实际应该根据策略获取
|
||||||
{
|
logicModelStatus = "监控中", // 实际应该根据策略状态获取
|
||||||
id = pos.Id,
|
logicModelDescription = "目标权重 季度调仓", // 实际应该根据策略配置获取
|
||||||
stockCode = pos.StockCode,
|
totalItems = positions.Count,
|
||||||
stockName = pos.StockName,
|
totalRatio = 100.0, // 所有持仓比例之和
|
||||||
amount = (int)pos.Shares,
|
positions = positionItems
|
||||||
averagePrice = (double)pos.AvgPrice,
|
|
||||||
currentPrice = (double)pos.AvgPrice,
|
|
||||||
totalValue = (double)(pos.Shares * pos.AvgPrice),
|
|
||||||
profit = 0,
|
|
||||||
profitRate = 0,
|
|
||||||
currency = pos.Currency
|
|
||||||
}).ToList()
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,9 @@ public class StrategyService : IStrategyService
|
|||||||
UserId = userId,
|
UserId = userId,
|
||||||
Alias = request.name,
|
Alias = request.name,
|
||||||
Type = request.type,
|
Type = request.type,
|
||||||
|
Description = request.description,
|
||||||
|
Tags = System.Text.Json.JsonSerializer.Serialize(request.tags),
|
||||||
|
RiskLevel = request.riskLevel,
|
||||||
Config = System.Text.Json.JsonSerializer.Serialize(request.parameters),
|
Config = System.Text.Json.JsonSerializer.Serialize(request.parameters),
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
UpdatedAt = DateTime.Now
|
UpdatedAt = DateTime.Now
|
||||||
@ -57,6 +60,9 @@ public class StrategyService : IStrategyService
|
|||||||
|
|
||||||
strategy.Alias = request.name;
|
strategy.Alias = request.name;
|
||||||
strategy.Type = request.type;
|
strategy.Type = request.type;
|
||||||
|
strategy.Description = request.description;
|
||||||
|
strategy.Tags = System.Text.Json.JsonSerializer.Serialize(request.tags);
|
||||||
|
strategy.RiskLevel = request.riskLevel;
|
||||||
strategy.Config = System.Text.Json.JsonSerializer.Serialize(request.parameters);
|
strategy.Config = System.Text.Json.JsonSerializer.Serialize(request.parameters);
|
||||||
strategy.UpdatedAt = DateTime.Now;
|
strategy.UpdatedAt = DateTime.Now;
|
||||||
|
|
||||||
|
|||||||
115
README.md
115
README.md
@ -270,6 +270,9 @@ Content-Type: application/json
|
|||||||
{
|
{
|
||||||
"name": "双均线策略(更新)",
|
"name": "双均线策略(更新)",
|
||||||
"type": "ma_trend",
|
"type": "ma_trend",
|
||||||
|
"description": "经典趋势跟踪策略",
|
||||||
|
"riskLevel": "medium",
|
||||||
|
"tags": ["趋势", "均线"],
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"maType": "EMA",
|
"maType": "EMA",
|
||||||
"shortPeriod": 15,
|
"shortPeriod": 15,
|
||||||
@ -490,40 +493,56 @@ Authorization: Bearer {token}
|
|||||||
"data": {
|
"data": {
|
||||||
"id": "port-abc12345",
|
"id": "port-abc12345",
|
||||||
"name": "我的投资组合",
|
"name": "我的投资组合",
|
||||||
"currency": "USD",
|
"currency": "CNY",
|
||||||
|
"status": "记录中",
|
||||||
"strategy": {
|
"strategy": {
|
||||||
"id": "strategy-123",
|
"id": "strategy-123",
|
||||||
"name": "双均线策略",
|
"name": "HFEA 风险平价逻辑",
|
||||||
"description": "基于短期和长期移动平均线的趋势跟踪策略"
|
"description": "目标权重 季度调仓"
|
||||||
},
|
},
|
||||||
"portfolioValue": 30075.00,
|
"portfolioValue": 156240.00,
|
||||||
"totalReturn": 0.15,
|
"totalReturn": 0.4282,
|
||||||
"todayProfit": 1250.50,
|
"todayProfit": 1240.50,
|
||||||
"todayProfitCurrency": "USD",
|
"historicalChange": 42.82,
|
||||||
|
"dailyVolatility": 1240.50,
|
||||||
|
"todayProfitCurrency": "CNY",
|
||||||
|
"logicModel": "HFEA 风险平价逻辑",
|
||||||
|
"logicModelStatus": "监控中",
|
||||||
|
"logicModelDescription": "目标权重 季度调仓",
|
||||||
|
"totalItems": 2,
|
||||||
|
"totalRatio": 100.0,
|
||||||
"positions": [
|
"positions": [
|
||||||
{
|
{
|
||||||
"id": "pos-xyz12345",
|
"id": "pos-xyz12345",
|
||||||
"stockCode": "AAPL",
|
"stockCode": "UPRO",
|
||||||
"stockName": "Apple Inc.",
|
"stockName": "UPRO",
|
||||||
"amount": 100,
|
"symbol": "UPRO.US",
|
||||||
"averagePrice": 150.50,
|
"amount": 142,
|
||||||
"currentPrice": 155.00,
|
"averagePrice": 500.00,
|
||||||
"totalValue": 15500.00,
|
"currentPrice": 605.00,
|
||||||
"profit": 450.00,
|
"totalValue": 85932.00,
|
||||||
"profitRate": 0.03,
|
"profit": 12400.00,
|
||||||
"currency": "USD"
|
"profitRate": 0.248,
|
||||||
|
"changeAmount": 12400.00,
|
||||||
|
"ratio": 55.0,
|
||||||
|
"deviationRatio": 16.8,
|
||||||
|
"currency": "CNY"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "pos-xyz67890",
|
"id": "pos-xyz67890",
|
||||||
"stockCode": "MSFT",
|
"stockCode": "TMF",
|
||||||
"stockName": "Microsoft Corp.",
|
"stockName": "TMF",
|
||||||
"amount": 50,
|
"symbol": "TMF.US",
|
||||||
"averagePrice": 300.25,
|
"amount": 800,
|
||||||
"currentPrice": 291.50,
|
"averagePrice": 90.00,
|
||||||
"totalValue": 14575.00,
|
"currentPrice": 87.89,
|
||||||
"profit": -437.50,
|
"totalValue": 70308.00,
|
||||||
"profitRate": -0.03,
|
"profit": -3200.50,
|
||||||
"currency": "USD"
|
"profitRate": -0.0445,
|
||||||
|
"changeAmount": -3200.50,
|
||||||
|
"ratio": 45.0,
|
||||||
|
"deviationRatio": -4.3,
|
||||||
|
"currency": "CNY"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -560,29 +579,53 @@ GET /api/v1/portfolio/transactions?portfolioId=port-abc12345&limit=10&offset=0
|
|||||||
{
|
{
|
||||||
"id": "trans-abc12345",
|
"id": "trans-abc12345",
|
||||||
"portfolioId": "port-abc12345",
|
"portfolioId": "port-abc12345",
|
||||||
"date": "2024-01-15",
|
"date": "2024-02-14",
|
||||||
"time": "14:30:00",
|
"time": "14:30",
|
||||||
"type": "buy",
|
"type": "buy",
|
||||||
"title": "买入AAPL",
|
"title": "定期定投 UPRO录入增加",
|
||||||
"amount": 50,
|
"amount": 500.00,
|
||||||
"currency": "USD",
|
"currency": "USD",
|
||||||
"status": "completed",
|
"status": "completed",
|
||||||
"remark": "加仓"
|
"remark": "定期定投"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "trans-def67890",
|
"id": "trans-def67890",
|
||||||
"portfolioId": "port-abc12345",
|
"portfolioId": "port-abc12345",
|
||||||
"date": "2024-01-10",
|
"date": "2024-01-01",
|
||||||
"time": "10:15:00",
|
"time": "09:15",
|
||||||
"type": "sell",
|
"type": "sell",
|
||||||
"title": "卖出MSFT",
|
"title": "季度再平衡 TMF结出减少 200股",
|
||||||
"amount": 25,
|
"amount": 200.00,
|
||||||
"currency": "USD",
|
"currency": "USD",
|
||||||
"status": "completed",
|
"status": "completed",
|
||||||
"remark": "减仓"
|
"remark": "季度再平衡"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "trans-ghi78901",
|
||||||
|
"portfolioId": "port-abc12345",
|
||||||
|
"date": "2023-12-15",
|
||||||
|
"time": "10:00",
|
||||||
|
"type": "buy",
|
||||||
|
"title": "建仓买入录入增加",
|
||||||
|
"amount": 100000.00,
|
||||||
|
"currency": "CNY",
|
||||||
|
"status": "completed",
|
||||||
|
"remark": "建仓买入"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "trans-jkl23456",
|
||||||
|
"portfolioId": "port-abc12345",
|
||||||
|
"date": "2023-12-10",
|
||||||
|
"time": "11:20",
|
||||||
|
"type": "buy",
|
||||||
|
"title": "建仓买入录入增加",
|
||||||
|
"amount": 50000.00,
|
||||||
|
"currency": "CNY",
|
||||||
|
"status": "completed",
|
||||||
|
"remark": "建仓买入"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"total": 25,
|
"total": 4,
|
||||||
"page": 1,
|
"page": 1,
|
||||||
"pageSize": 10
|
"pageSize": 10
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user