using Binance.TradeRobot.Common.DI; using Binance.TradeRobot.Common.Extensions; using Binance.TradeRobot.Model.Base; using Binance.TradeRobot.Model.Db; using Binance.TradeRobot.Model.Dto; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Yitter.IdGenerator; namespace Binance.TradeRobot.Business.Exchange { [BatchRegistration(ServiceLifetime.Singleton, RegistrationType.Self)] public class ExchangeBusiness : BaseBusiness { public ExchangeBusiness(IFreeSql fsql, NLogManager logManager, IIdGenerator idGenerator, IMemoryCache memoryCache) : base(fsql, logManager, idGenerator, memoryCache) { } public void AddExchangeAccount(AddExchangeAccountRequest addExchangeAccountRequest) { if (addExchangeAccountRequest.Id == 0 || string.IsNullOrEmpty(addExchangeAccountRequest.LoginName) || string.IsNullOrEmpty(addExchangeAccountRequest.APIKey) || string.IsNullOrEmpty(addExchangeAccountRequest.SecretKey)) throw new BusinessException("交易所账号参数有误"); if (fsql.Select(addExchangeAccountRequest.Id).Any()) throw new BusinessException("交易所账号重复"); if (fsql.Select().Where(k => k.APIKey == addExchangeAccountRequest.APIKey || k.SecretKey == addExchangeAccountRequest.SecretKey).Any()) throw new BusinessException("重复的APIKey或SecretKey"); var exchangeAccount = addExchangeAccountRequest.Map(); if (addExchangeAccountRequest.TradePolicy == Enums.TradePolicy.金字塔) exchangeAccount.BusinessType = Enums.BusinessType.UPrep; if (addExchangeAccountRequest.TradePolicy == Enums.TradePolicy.动量趋势v2) exchangeAccount.BusinessType = Enums.BusinessType.Spot_Margin; var exchangeAPIKey = new ExchangeAPIKey() { Id = idGenerator.NewLong(), AccountId = addExchangeAccountRequest.Id, APIKey = addExchangeAccountRequest.APIKey, SecretKey = addExchangeAccountRequest.SecretKey }; fsql.Transaction(() => { fsql.Insert(exchangeAPIKey).ExecuteAffrows(); fsql.Insert(exchangeAccount).ExecuteAffrows(); }); } public void AddExchangeAPIKey(AddExchangeAPIKeyRequest addExchangeAPIKeyRequest) { if (addExchangeAPIKeyRequest.AccountId == 0 || string.IsNullOrEmpty(addExchangeAPIKeyRequest.APIKey) || string.IsNullOrEmpty(addExchangeAPIKeyRequest.SecretKey)) throw new BusinessException("参数有误"); if (fsql.Select().Where(k => k.APIKey == addExchangeAPIKeyRequest.APIKey || k.SecretKey == addExchangeAPIKeyRequest.SecretKey).Any()) throw new BusinessException("重复的APIKey或SecretKey"); var exchangeAPIKey = addExchangeAPIKeyRequest.Map(); exchangeAPIKey.Id = idGenerator.NewLong(); fsql.Insert(exchangeAPIKey).ExecuteAffrows(); } public IList GetExchangeAccountList(Enums.TradePolicy tradePolicy) { var exchangeAccountList = fsql.Select().Where(ea => ea.TradePolicy == tradePolicy).ToList().Map>(); var accountIdList = exchangeAccountList.Select(ea => ea.Id); var exchangeAPIKeyList = fsql.Select().LeftJoin((k, r) => k.RobotId == r.Id) .Where((k, r) => accountIdList.Contains(k.AccountId)) .ToList((k, r) => new ExchangeAPIKeyResponse() { Id = k.Id, AccountId = k.AccountId, APIKey = k.APIKey, SecretKey = k.SecretKey, CreateTime = k.CreateTime, RobotId = k.RobotId, RobotSymbol = r.Symbol }); var waitList = new List(); foreach (var exchangeAccount in exchangeAccountList) { var currentExchangeAccountAPIKeyList = exchangeAPIKeyList.Where(k => k.AccountId == exchangeAccount.Id); if (currentExchangeAccountAPIKeyList.Count() == 0) continue; exchangeAccount.ExchangeAPIKeyList.AddRange(currentExchangeAccountAPIKeyList); var ewh = new ManualResetEvent(false); waitList.Add(ewh); Task.Factory.StartNew(() => GetExchangeAssets(exchangeAccount, ewh)); } WaitHandle.WaitAll(waitList.ToArray(), 5000); return exchangeAccountList; } private void GetExchangeAssets(ExchangeAccountResponse exchangeAccount, EventWaitHandle ewh) { try { var binanceClient = GetBinanceClient(exchangeAccount.ExchangeAPIKeyList[0].APIKey, exchangeAccount.ExchangeAPIKeyList[0].SecretKey); if (exchangeAccount.BusinessType == Enums.BusinessType.UPrep) { var result = binanceClient.UsdFuturesApi.Account.GetBalancesAsync().Result; if (result.Success) { exchangeAccount.UPrepUSDT = result.Data.FirstOrDefault(b => b.Asset == "USDT")?.WalletBalance ?? 0; } } else if (exchangeAccount.BusinessType == Enums.BusinessType.Spot) { } else if (exchangeAccount.BusinessType == Enums.BusinessType.Spot_Margin) { } } catch (Exception ex) { } finally { ewh.Set(); } } } }