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}");
}