diff --git a/Binance.TradeRobot.Business/Business/ExchangeBusiness.cs b/Binance.TradeRobot.Business/Business/ExchangeBusiness.cs index 3b02a64..b476e30 100644 --- a/Binance.TradeRobot.Business/Business/ExchangeBusiness.cs +++ b/Binance.TradeRobot.Business/Business/ExchangeBusiness.cs @@ -76,7 +76,7 @@ namespace Binance.TradeRobot.Business.Exchange Id = k.Id, AccountId = k.AccountId, APIKey = k.APIKey, - SecretKey = "********", + SecretKey = k.SecretKey, CreateTime = k.CreateTime, RobotId = k.RobotId, RobotSymbol = r.Symbol @@ -102,6 +102,8 @@ namespace Binance.TradeRobot.Business.Exchange { try { + var firstAPIKey = exchangeAccount.ExchangeAPIKeyList.FirstOrDefault(); + var apiClient = GetBaseAPIClient(exchangeAccount.ExchangeId, exchangeAccount.Id, firstAPIKey.APIKey, firstAPIKey.SecretKey); if (exchangeAccount.BusinessType == Enums.BusinessType.UPrep) { //var result = binanceClient.UsdFuturesApi.Account.GetBalancesAsync().Result; @@ -116,7 +118,20 @@ namespace Binance.TradeRobot.Business.Exchange } else if (exchangeAccount.BusinessType == Enums.BusinessType.Spot_Margin) { - + var isolatedMarginAccountAssetList = apiClient.GetIsolatedMarginAccountAssets(); + foreach (var apiKey in exchangeAccount.ExchangeAPIKeyList) + { + if (apiKey.RobotId == null) + continue; + var asset = isolatedMarginAccountAssetList.FirstOrDefault(s => s.Symbol == apiKey.RobotSymbol); + if (asset != null) + { + apiKey.BaseAmount = asset.BaseFree; + apiKey.QuoteAmount = asset.QuoteFree; + apiKey.QuoteNetAmount = asset.QuoteNetAsset; + apiKey.QuoteLoanAmount = asset.QuoteBorrowed; + } + } } } catch (Exception ex) @@ -125,6 +140,8 @@ namespace Binance.TradeRobot.Business.Exchange } finally { + foreach (var apiKey in exchangeAccount.ExchangeAPIKeyList) + apiKey.SecretKey = string.Empty; ewh.Set(); } } diff --git a/Binance.TradeRobot.Business/Business/RobotBusiness.cs b/Binance.TradeRobot.Business/Business/RobotBusiness.cs index 186baa2..067809a 100644 --- a/Binance.TradeRobot.Business/Business/RobotBusiness.cs +++ b/Binance.TradeRobot.Business/Business/RobotBusiness.cs @@ -83,7 +83,7 @@ namespace Binance.TradeRobot.Business fsql.Insert(new Robot() { Id = robotId, - Symbol = addRobotRequest.Symbol, + Symbol = addRobotRequest.Symbol.ToUpper(), TradePolicy = addRobotRequest.TradePolicy, BusinessType = addRobotRequest.TradePolicy.GetBusinessType(), ExchangeId = addRobotRequest.ExchangeId, diff --git a/Binance.TradeRobot.Business/Business/TradeBusiness/D21TradeBusiness.cs b/Binance.TradeRobot.Business/Business/TradeBusiness/D21TradeBusiness.cs index b636627..f3765b2 100644 --- a/Binance.TradeRobot.Business/Business/TradeBusiness/D21TradeBusiness.cs +++ b/Binance.TradeRobot.Business/Business/TradeBusiness/D21TradeBusiness.cs @@ -124,7 +124,7 @@ namespace Binance.TradeRobot.Business var diffRatio = Math.Round((newestPrice / d21RuningInfo.RecentShortCrossSignalTradePrice.Value - 1) * 100, 2); if (diffRatio > d21Robot.D21Policy.MaxFollowPurchaseRatio) { - throw new BusinessException($"触发限制追高,最近空交叉成交价{d21RuningInfo.RecentShortCrossSignalTradePrice},当前价格{newestPrice},追高比例{d21Robot.D21Policy.MaxFollowPurchaseRatio}%,当前比例{diffRatio}%,终止多交叉信号执行"); + throw new BusinessException($"触发追高限制,最近空交叉成交价{d21RuningInfo.RecentShortCrossSignalTradePrice},当前价格{newestPrice},最大追高比例{d21Robot.D21Policy.MaxFollowPurchaseRatio}%,当前追高比例{diffRatio}%,终止多交叉信号执行"); } } #endregion @@ -134,10 +134,65 @@ namespace Binance.TradeRobot.Business var apiClient = GetBaseAPIClient(robot.ExchangeId, robot.ExchangeAPIKey.AccountId, robot.ExchangeAPIKey.APIKey, robot.ExchangeAPIKey.SecretKey); //逐仓杠杆账户余额 var balance = apiClient.GetIsolatedMarginAccountAssets().FirstOrDefault(m => m.Symbol == robot.Symbol)?.QuoteFree ?? 0M; + if (balance == 0M) + throw new BusinessException("可用资产为0"); #endregion #region 计算下单数量 + step = "计算下单数量"; + var diffAmount = 0M; //借币金额 var previewTradeAmount = d21Robot.D21Policy.Position; //预估交易额 + if (balance < previewTradeAmount) + { + #region 借币 + step = "借币"; + diffAmount = previewTradeAmount - balance; + var diffRatio = diffAmount / balance * 100; //借币比例 + + #region 验证策略中的最大借币比例 + if (diffRatio > d21Robot.D21Policy.MaxExchangeLoanRatio) + { + logList.Add(new ExecutionLog() + { + Id = idGenerator.NewLong(), + SourceSingal = Enums.SingalType.多交叉, + RobotId = robot.Id, + CreateTime = DateTime.Now, + Content = $"触发策略中交易所最大借币比例限制,交易所最大借币比例{d21Robot.D21Policy.MaxExchangeLoanRatio}%,当前借币比例{diffRatio}%,按交易所最大借币比例借币" + }); + diffAmount = previewTradeAmount * (d21Robot.D21Policy.MaxExchangeLoanRatio / 100M); + //previewTradeAmount = balance + diffAmount; //在策略允许的借币比例范围内的最大下单金额 + } + #endregion + + #region 验证交易所的最大可借额度 + try + { + var exchangeMaxLoanAmount = apiClient.QueryMaxLoanAmount(robot.Symbol); + if (exchangeMaxLoanAmount < diffAmount) + { + + } + } + catch (Exception borrowex) + { + logList.Add(new ExecutionLog() + { + Id = idGenerator.NewLong(), + SourceSingal = Enums.SingalType.多交叉, + RobotId = robot.Id, + CreateTime = DateTime.Now, + Content = $"验证交易所的最大可借额度失败 {borrowex.Message}" + }); + previewTradeAmount = balance; //无法借币,使用余额下单 + } + #endregion + + #endregion + } + #endregion + + #region 下单 #endregion diff --git a/Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml b/Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml index ca4fc63..698bf7d 100644 --- a/Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml +++ b/Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml @@ -669,9 +669,24 @@ 逐仓杠杆USDT资产 - + - 逐仓杠杆USDT + 基础币金额(标的数量) + + + + + 报价币金额(USDT)(可转资金) + + + + + 报价币借款金额(USDT) + + + + + 报价币净资产(USDT)(不含借款) diff --git a/Binance.TradeRobot.Model/Dto/Response/Exchange/ExchangeAPIKeyResponse.cs b/Binance.TradeRobot.Model/Dto/Response/Exchange/ExchangeAPIKeyResponse.cs index 3af0aea..eeea34f 100644 --- a/Binance.TradeRobot.Model/Dto/Response/Exchange/ExchangeAPIKeyResponse.cs +++ b/Binance.TradeRobot.Model/Dto/Response/Exchange/ExchangeAPIKeyResponse.cs @@ -3,9 +3,24 @@ public class ExchangeAPIKeyResponse : Db.ExchangeAPIKey { /// - /// 逐仓杠杆USDT + /// 基础币金额(标的数量) /// - public decimal SpotMarginUSDT { get; set; } + public decimal BaseAmount { get; set; } + + /// + /// 报价币金额(USDT)(可转资金) + /// + public decimal QuoteAmount { get; set; } + + /// + /// 报价币借款金额(USDT) + /// + public decimal QuoteLoanAmount { get; set; } + + /// + /// 报价币净资产(USDT)(不含借款) + /// + public decimal QuoteNetAmount { get; set; } /// /// 关联机器人的交易对 diff --git a/SDKAdapter/APIClient/BaseAPIClient.cs b/SDKAdapter/APIClient/BaseAPIClient.cs index c8d638b..c6c3469 100644 --- a/SDKAdapter/APIClient/BaseAPIClient.cs +++ b/SDKAdapter/APIClient/BaseAPIClient.cs @@ -34,5 +34,16 @@ namespace SDKAdapter.APIClient { throw new NotImplementedException(); } + + /// + /// 查询最大借币额度(USDT) + /// + /// + /// + /// + public virtual decimal QueryMaxLoanAmount(string symbol) + { + throw new NotImplementedException(); + } } } diff --git a/SDKAdapter/APIClient/BinanceAPIClient.cs b/SDKAdapter/APIClient/BinanceAPIClient.cs index 0617f11..d732024 100644 --- a/SDKAdapter/APIClient/BinanceAPIClient.cs +++ b/SDKAdapter/APIClient/BinanceAPIClient.cs @@ -56,5 +56,13 @@ namespace SDKAdapter.APIClient QuoteNetAsset = asset.QuoteAsset.NetAsset }).ToList(); } + + public override decimal QueryMaxLoanAmount(string symbol) + { + var r = binanceClient.SpotApi.Account.GetMarginMaxBorrowAmountAsync("USDT", symbol).Result; + if (!r.Success) + throw new Exception($"查询最大借币额度失败 {r.Error?.Message}"); + return r.Data.Quantity; + } } } diff --git a/SDKTestConsole/Program.cs b/SDKTestConsole/Program.cs index e575dd9..069a352 100644 --- a/SDKTestConsole/Program.cs +++ b/SDKTestConsole/Program.cs @@ -14,11 +14,13 @@ namespace SDKTestConsole { var apiKey = "NnLXgcdUAZ8FAye4Qge3zrrdg5o7ufoWbgtYsKzgfIXz0OMz27G1Kx4SykMzw7YS"; var secret = "lpJ3t50osPx6lEUerVFMdoKsZ6uHPc769OFPGtfhcoPANpv97CEcvR3pz3Bezhhv"; + var client = BaseAPIClient.Create(Enums.Exchange.Binance, 0, apiKey, secret); + //逐仓杠杆账户资产 + //var marginList = client.GetIsolatedMarginAccountAssets(); + //var s = JsonConvert.SerializeObject(marginList); - var marginList = BaseAPIClient.Create(Enums.Exchange.Binance, 0, apiKey, secret).GetIsolatedMarginAccountAssets(); - - var s = JsonConvert.SerializeObject(marginList); - Console.WriteLine(s); + var maxLoan = client.QueryMaxLoanAmount("ETHUSDT"); + Console.WriteLine(maxLoan); Console.ReadKey(); } }