币安量化交易
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
7.9 KiB

using Binance.TradeRobot.Business.Extensions;
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<ExchangeAccount>(addExchangeAccountRequest.Id).Any())
throw new BusinessException("交易所账号重复");
if (fsql.Select<ExchangeAPIKey>().Where(k => k.APIKey == addExchangeAccountRequest.APIKey || k.SecretKey == addExchangeAccountRequest.SecretKey).Any())
throw new BusinessException("重复的APIKey或SecretKey");
var exchangeAccount = addExchangeAccountRequest.Map<ExchangeAccount>();
exchangeAccount.BusinessType = addExchangeAccountRequest.TradePolicy.GetBusinessType();
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<ExchangeAPIKey>().Where(k => k.APIKey == addExchangeAPIKeyRequest.APIKey || k.SecretKey == addExchangeAPIKeyRequest.SecretKey).Any())
throw new BusinessException("重复的APIKey或SecretKey");
var exchangeAPIKey = addExchangeAPIKeyRequest.Map<ExchangeAPIKey>();
exchangeAPIKey.Id = idGenerator.NewLong();
fsql.Insert(exchangeAPIKey).ExecuteAffrows();
}
public IList<ExchangeAccountResponse> GetExchangeAccountList(Enums.TradePolicy tradePolicy)
{
var exchangeAccountList = fsql.Select<ExchangeAccount>().Where(ea => ea.TradePolicy == tradePolicy).ToList().Map<IList<ExchangeAccountResponse>>();
var accountIdList = exchangeAccountList.Select(ea => ea.Id);
var exchangeAPIKeyList = fsql.Select<ExchangeAPIKey, Robot>().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<WaitHandle>();
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();
}
}
/// <summary>
/// 获取APIKey未使用交易所账户列表
/// </summary>
/// <param name="tradePolicy"></param>
/// <param name="exchangeId"></param>
/// <returns></returns>
public IList<ExchangeAccountResponse> GetNoUsedExchangeAccountList(Enums.TradePolicy tradePolicy, Enums.Exchange exchangeId)
{
var exchangeAccountList = fsql.Select<ExchangeAccount>().Where(ea => ea.TradePolicy == tradePolicy && ea.ExchangeId == exchangeId)
.ToList().Map<IList<ExchangeAccountResponse>>();
var accountIdList = exchangeAccountList.Select(ea => ea.Id);
var exchangeAPIKeyList = fsql.Select<ExchangeAPIKey>().Where(k => k.RobotId == null && accountIdList.Contains(k.AccountId))
.ToList()
.Map<IList<ExchangeAPIKeyResponse>>();
foreach (var exchangeAccount in exchangeAccountList)
{
var currentExchangeAccountAPIKeyList = exchangeAPIKeyList.Where(k => k.AccountId == exchangeAccount.Id);
if (currentExchangeAccountAPIKeyList.Count() == 0)
continue;
exchangeAccount.ExchangeAPIKeyList.AddRange(currentExchangeAccountAPIKeyList);
}
return exchangeAccountList;
}
}
}