diff --git a/AssetManager.Data/Portfolio.cs b/AssetManager.Data/Portfolio.cs index b9a316d..add23a2 100755 --- a/AssetManager.Data/Portfolio.cs +++ b/AssetManager.Data/Portfolio.cs @@ -68,161 +68,3 @@ public class Portfolio [SugarColumn(ColumnName = "updated_at")] public DateTime UpdatedAt { get; set; } } - -/// -/// 持仓明细表 -/// -[SugarTable("positions")] -public class Position -{ - /// - /// 主键 - /// - [SugarColumn(IsPrimaryKey = true, IsIdentity = false)] - public string? Id { get; set; } - - /// - /// 所属组合ID - /// - [SugarColumn(ColumnName = "portfolio_id", IndexGroupNameList = new string[] { "idx_portfolio_id" })] - public string? PortfolioId { get; set; } - - /// - /// 标的代码 (如: UPRO.US) - /// - [SugarColumn(ColumnName = "stock_code", Length = 50)] - public string? StockCode { get; set; } - - /// - /// 标的名称 - /// - [SugarColumn(ColumnName = "stock_name", Length = 200)] - public string? StockName { get; set; } - - /// - /// 资产类型 (Stock/Crypto) - /// - [SugarColumn(ColumnName = "asset_type", Length = 20)] - public string? AssetType { get; set; } - - /// - /// 持有数量 - /// - [SugarColumn(ColumnName = "shares", ColumnDataType = "decimal(18,8)")] - public decimal Shares { get; set; } - - /// - /// 持仓均价 - /// - [SugarColumn(ColumnName = "avg_price", ColumnDataType = "decimal(18,4)")] - public decimal AvgPrice { get; set; } - - /// - /// 标的币种 - /// - [SugarColumn(ColumnName = "currency", Length = 10)] - public string? Currency { get; set; } - - /// - /// 建仓时间 - /// - [SugarColumn(ColumnName = "created_at")] - public DateTime CreatedAt { get; set; } - - /// - /// 最后更新时间 - /// - [SugarColumn(ColumnName = "updated_at")] - public DateTime UpdatedAt { get; set; } -} - -/// -/// 交易流水表 -/// -[SugarTable("transactions")] -public class Transaction -{ - /// - /// 主键 - /// - [SugarColumn(IsPrimaryKey = true, IsIdentity = false)] - public string? Id { get; set; } - - /// - /// 所属组合ID - /// - [SugarColumn(ColumnName = "portfolio_id", IndexGroupNameList = new string[] { "idx_portfolio_id" })] - public string? PortfolioId { get; set; } - - /// - /// 交易类型 (buy/sell) - /// - [SugarColumn(ColumnName = "type", Length = 20)] - public string? Type { get; set; } - - /// - /// 标的代码 - /// - [SugarColumn(ColumnName = "stock_code", Length = 50)] - public string? StockCode { get; set; } - - /// - /// 资产类型 (Stock/Crypto) - /// - [SugarColumn(ColumnName = "asset_type", Length = 20)] - public string? AssetType { get; set; } - - /// - /// 交易标题 (如: 定期定投) - /// - [SugarColumn(ColumnName = "title", Length = 200)] - public string? Title { get; set; } - - /// - /// 交易数量 - /// - [SugarColumn(ColumnName = "amount", ColumnDataType = "decimal(18,8)")] - public decimal Amount { get; set; } - - /// - /// 成交价格 - /// - [SugarColumn(ColumnName = "price", ColumnDataType = "decimal(18,4)")] - public decimal Price { get; set; } - - /// - /// 交易总金额 - /// - [SugarColumn(ColumnName = "total_amount", ColumnDataType = "decimal(18,4)")] - public decimal TotalAmount { get; set; } - - /// - /// 交易币种 - /// - [SugarColumn(ColumnName = "currency", Length = 10)] - public string? Currency { get; set; } - - /// - /// 交易状态 (processing/completed) - /// - [SugarColumn(ColumnName = "status", Length = 50)] - public string? Status { get; set; } - - /// - /// 交易备注 - /// - [SugarColumn(ColumnName = "remark", Length = 500, IsNullable = true)] - public string? Remark { get; set; } - - /// - /// 交易发生时间 - /// - [SugarColumn(ColumnName = "transaction_time")] - public DateTime TransactionTime { get; set; } - - /// - /// 记录创建时间 - /// - [SugarColumn(ColumnName = "created_at")] - public DateTime CreatedAt { get; set; } -} diff --git a/AssetManager.Data/Position.cs b/AssetManager.Data/Position.cs new file mode 100644 index 0000000..c6459a1 --- /dev/null +++ b/AssetManager.Data/Position.cs @@ -0,0 +1,70 @@ +using SqlSugar; + +namespace AssetManager.Data; + +/// +/// 持仓明细表 +/// +[SugarTable("positions")] +public class Position +{ + /// + /// 主键 + /// + [SugarColumn(IsPrimaryKey = true, IsIdentity = false)] + public string? Id { get; set; } + + /// + /// 所属组合ID + /// + [SugarColumn(ColumnName = "portfolio_id", IndexGroupNameList = new string[] { "idx_portfolio_id" })] + public string? PortfolioId { get; set; } + + /// + /// 标的代码 (如: UPRO.US) + /// + [SugarColumn(ColumnName = "stock_code", Length = 50)] + public string? StockCode { get; set; } + + /// + /// 标的名称 + /// + [SugarColumn(ColumnName = "stock_name", Length = 200)] + public string? StockName { get; set; } + + /// + /// 资产类型 (Stock/Crypto) + /// + [SugarColumn(ColumnName = "asset_type", Length = 20)] + public string? AssetType { get; set; } + + /// + /// 持有数量 + /// + [SugarColumn(ColumnName = "shares", ColumnDataType = "decimal(18,8)")] + public decimal Shares { get; set; } + + /// + /// 持仓均价 + /// + [SugarColumn(ColumnName = "avg_price", ColumnDataType = "decimal(18,4)")] + public decimal AvgPrice { get; set; } + + /// + /// 标的币种 + /// + [SugarColumn(ColumnName = "currency", Length = 10)] + public string? Currency { get; set; } + + /// + /// 建仓时间 + /// + [SugarColumn(ColumnName = "created_at")] + public DateTime CreatedAt { get; set; } + + /// + /// 最后更新时间 + /// + [SugarColumn(ColumnName = "updated_at")] + public DateTime UpdatedAt { get; set; } +} diff --git a/AssetManager.Data/Transaction.cs b/AssetManager.Data/Transaction.cs new file mode 100644 index 0000000..fdda41f --- /dev/null +++ b/AssetManager.Data/Transaction.cs @@ -0,0 +1,94 @@ +using SqlSugar; + +namespace AssetManager.Data; + +/// +/// 交易流水表 +/// +[SugarTable("transactions")] +public class Transaction +{ + /// + /// 主键 + /// + [SugarColumn(IsPrimaryKey = true, IsIdentity = false)] + public string? Id { get; set; } + + /// + /// 所属组合ID + /// + [SugarColumn(ColumnName = "portfolio_id", IndexGroupNameList = new string[] { "idx_portfolio_id" })] + public string? PortfolioId { get; set; } + + /// + /// 交易类型 (buy/sell) + /// + [SugarColumn(ColumnName = "type", Length = 20)] + public string? Type { get; set; } + + /// + /// 标的代码 + /// + [SugarColumn(ColumnName = "stock_code", Length = 50)] + public string? StockCode { get; set; } + + /// + /// 资产类型 (Stock/Crypto) + /// + [SugarColumn(ColumnName = "asset_type", Length = 20)] + public string? AssetType { get; set; } + + /// + /// 交易标题 (如: 定期定投) + /// + [SugarColumn(ColumnName = "title", Length = 200)] + public string? Title { get; set; } + + /// + /// 交易数量 + /// + [SugarColumn(ColumnName = "amount", ColumnDataType = "decimal(18,8)")] + public decimal Amount { get; set; } + + /// + /// 成交价格 + /// + [SugarColumn(ColumnName = "price", ColumnDataType = "decimal(18,4)")] + public decimal Price { get; set; } + + /// + /// 交易总金额 + /// + [SugarColumn(ColumnName = "total_amount", ColumnDataType = "decimal(18,4)")] + public decimal TotalAmount { get; set; } + + /// + /// 交易币种 + /// + [SugarColumn(ColumnName = "currency", Length = 10)] + public string? Currency { get; set; } + + /// + /// 交易状态 (processing/completed) + /// + [SugarColumn(ColumnName = "status", Length = 50)] + public string? Status { get; set; } + + /// + /// 交易备注 + /// + [SugarColumn(ColumnName = "remark", Length = 500, IsNullable = true)] + public string? Remark { get; set; } + + /// + /// 交易发生时间 + /// + [SugarColumn(ColumnName = "transaction_time")] + public DateTime TransactionTime { get; set; } + + /// + /// 记录创建时间 + /// + [SugarColumn(ColumnName = "created_at")] + public DateTime CreatedAt { get; set; } +} diff --git a/AssetManager.Infrastructure/Services/MarketDataService.cs b/AssetManager.Infrastructure/Services/MarketDataService.cs index af50e99..792fce7 100755 --- a/AssetManager.Infrastructure/Services/MarketDataService.cs +++ b/AssetManager.Infrastructure/Services/MarketDataService.cs @@ -33,10 +33,12 @@ public class MarketDataService : IMarketDataService _logger = logger; _httpClient = httpClientFactory.CreateClient(); _databaseService = databaseService; - // 完全从环境变量读取 Tiingo API Key + + // 从环境变量读取 Tiingo API Key(必填) _tiingoApiKey = Environment.GetEnvironmentVariable("Tiingo__ApiKey") ?? Environment.GetEnvironmentVariable("TIINGO_API_KEY") - ?? "bd00fee76d3012b047473078904001b33322cb46"; + ?? throw new InvalidOperationException("Tiingo__ApiKey 环境变量未配置"); + _httpClient.DefaultRequestHeaders.Add("Authorization", $"Token {_tiingoApiKey}"); }