diff --git a/Binance.TradeRobot.API/Binance.TradeRobot.API.xml b/Binance.TradeRobot.API/Binance.TradeRobot.API.xml index 3cec8e8..4ea2d4d 100644 --- a/Binance.TradeRobot.API/Binance.TradeRobot.API.xml +++ b/Binance.TradeRobot.API/Binance.TradeRobot.API.xml @@ -61,6 +61,12 @@ + + + D21杠杆/合约信号接口 + + + 编辑动2.1策略 diff --git a/Binance.TradeRobot.API/Controllers/SingalController.cs b/Binance.TradeRobot.API/Controllers/SingalController.cs new file mode 100644 index 0000000..b0fd552 --- /dev/null +++ b/Binance.TradeRobot.API/Controllers/SingalController.cs @@ -0,0 +1,26 @@ +using Binance.TradeRobot.Business.Business; +using Binance.TradeRobot.Model.Dto; +using Microsoft.AspNetCore.Mvc; + +namespace Binance.TradeRobot.API.Controllers +{ + public class SingalController : BaseApiController + { + private SingalBusiness singalBusiness; + + public SingalController(SingalBusiness singalBusiness) + { + this.singalBusiness = singalBusiness; + } + + /// + /// D21杠杆/合约信号接口 + /// + /// + [HttpPost] + public void D21Singnal([FromBody] D21SingalRequest d21SingalRequest) + { + singalBusiness.D21Singnal(d21SingalRequest); + } + } +} diff --git a/Binance.TradeRobot.Business/Business/BaseBusiness.cs b/Binance.TradeRobot.Business/Business/BaseBusiness.cs index d8109d9..aa76080 100644 --- a/Binance.TradeRobot.Business/Business/BaseBusiness.cs +++ b/Binance.TradeRobot.Business/Business/BaseBusiness.cs @@ -21,6 +21,7 @@ namespace Binance.TradeRobot.Business this.fsql = fsql; this.logManager = logManager; this.idGenerator = idGenerator; + this.memoryCache = memoryCache; expirationTimeSpan = TimeSpan.FromDays(1); } diff --git a/Binance.TradeRobot.Business/Business/RobotBusiness.cs b/Binance.TradeRobot.Business/Business/RobotBusiness.cs index 9186379..f7e4357 100644 --- a/Binance.TradeRobot.Business/Business/RobotBusiness.cs +++ b/Binance.TradeRobot.Business/Business/RobotBusiness.cs @@ -133,47 +133,74 @@ namespace Binance.TradeRobot.Business /// /// 获取动2.1策略机器人列表 /// + /// 机器人状态 + /// 信号周期 + /// 交易对 + /// 是否加载近期交易利润,默认true + /// 是否加载机器人绑定的APIKey,默认false /// - public IList GetD21PolicyRobotList() + public IList GetD21PolicyRobotList(Enums.RobotState? robotState = null, + Enums.SignalPeriod? signalPeriod = null, + string symbol = "", + bool isLoadRecentTradeProfit = true, + bool isLoadAPIKey = false) { - var robotList = fsql.Select().InnerJoin((r, ra, d) => r.Id == ra.RobotId) - .InnerJoin((r, ra, d) => r.Id == d.RobotId) - .ToList((r, ra, d) => new Robot() - { - Id = r.Id, - BusinessType = r.BusinessType, - ExchangeId = r.ExchangeId, - Symbol = r.Symbol, - State = r.State, - RunningTime = r.RunningTime, - CreateTime = r.CreateTime, - TradePolicy = r.TradePolicy, - - RobotAccountId = ra.Id, - ClosePositionCount = ra.ClosePositionCount, - WinCount = ra.WinCount, - LoanAmount = ra.LoanAmount, - SoptCurrentcyAmount = ra.SoptCurrentcyAmount, - SpotCurrencyQuantity = ra.SpotCurrencyQuantity, - TotalProfit = ra.TotalProfit, - - D21ExecutionMode = d.ExecutionMode, - D21IsEnabledIncreasePurchase = d.IsEnabledIncreasePurchase, - D21IsEnableRemedyForErrorCrossSignal = d.IsEnableRemedyForErrorCrossSignal, - D21MaxFollowPurchaseRatio = d.MaxFollowPurchaseRatio, - D21PeriodicSignal = d.PeriodicSignal, - D21PolicyId = d.Id, - D21Position = d.Position, - D21Assets = d.Assets, - D21Level1PositionStopLossRatio = d.Level1PositionStopLossRatio, - D21Level1PriceStopLossRatio = d.Level1PriceStopLossRatio, - D21Level2PositionStopLossRatio = d.Level2PositionStopLossRatio, - D21Level2PriceStopLossRatio = d.Level2PriceStopLossRatio, - D21MaxExchangeLoanRatio = d.MaxExchangeLoanRatio, - D21MaxSystemLoanRatio = d.MaxSystemLoanRatio, - D21CreateTime = d.CreateTime - }).Map>(); + var robotList = fsql.Select().InnerJoin((r, ra, d, e) => r.Id == ra.RobotId) + .InnerJoin((r, ra, d, e) => r.Id == d.RobotId) + .InnerJoin((r, ra, d, e) => r.Id == e.RobotId) + .WhereIf(robotState != null, (r, ra, d, e) => r.State == robotState) + .WhereIf(signalPeriod != null, (r, ra, d, e) => d.PeriodicSignal == signalPeriod) + .WhereIf(!string.IsNullOrEmpty(symbol), (r, ra, d, e) => r.Symbol == symbol) + .Where((r, ra, d, e) => r.TradePolicy == Enums.TradePolicy.动量趋势v21) + .ToList((r, ra, d, e) => new Robot() + { + Id = r.Id, + BusinessType = r.BusinessType, + ExchangeId = r.ExchangeId, + Symbol = r.Symbol, + State = r.State, + RunningTime = r.RunningTime, + CreateTime = r.CreateTime, + TradePolicy = r.TradePolicy, + + RobotAccountId = ra.Id, + ClosePositionCount = ra.ClosePositionCount, + WinCount = ra.WinCount, + LoanAmount = ra.LoanAmount, + SoptCurrentcyAmount = ra.SoptCurrentcyAmount, + SpotCurrencyQuantity = ra.SpotCurrencyQuantity, + TotalProfit = ra.TotalProfit, + + ExchangeAccountId = e.AccountId, + ExchangeAPIKey = e.APIKey, + ExchangeSecretKey = e.SecretKey, + + D21ExecutionMode = d.ExecutionMode, + D21IsEnabledIncreasePurchase = d.IsEnabledIncreasePurchase, + D21IsEnableRemedyForErrorCrossSignal = d.IsEnableRemedyForErrorCrossSignal, + D21MaxFollowPurchaseRatio = d.MaxFollowPurchaseRatio, + D21PeriodicSignal = d.PeriodicSignal, + D21PolicyId = d.Id, + D21Position = d.Position, + D21Assets = d.Assets, + D21Level1PositionStopLossRatio = d.Level1PositionStopLossRatio, + D21Level1PriceStopLossRatio = d.Level1PriceStopLossRatio, + D21Level2PositionStopLossRatio = d.Level2PositionStopLossRatio, + D21Level2PriceStopLossRatio = d.Level2PriceStopLossRatio, + D21MaxExchangeLoanRatio = d.MaxExchangeLoanRatio, + D21MaxSystemLoanRatio = d.MaxSystemLoanRatio, + D21CreateTime = d.CreateTime + }).Map>(); + if (isLoadRecentTradeProfit) + { + //统计近期订单利润 + } + if (!isLoadAPIKey) + { + foreach (var r in robotList) + r.ExchangeAPIKey = null; + } return robotList; } diff --git a/Binance.TradeRobot.Business/Business/SingalBusiness.cs b/Binance.TradeRobot.Business/Business/SingalBusiness.cs new file mode 100644 index 0000000..eaff5cd --- /dev/null +++ b/Binance.TradeRobot.Business/Business/SingalBusiness.cs @@ -0,0 +1,48 @@ +using Binance.TradeRobot.Common.DI; +using Binance.TradeRobot.Model.Base; +using Binance.TradeRobot.Model.Dto; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.DependencyInjection; +using System.Linq; +using Yitter.IdGenerator; + +namespace Binance.TradeRobot.Business.Business +{ + [BatchRegistration(ServiceLifetime.Singleton, RegistrationType.Self)] + public class SingalBusiness : BaseBusiness + { + private RobotBusiness robotBusiness; + + public SingalBusiness(IFreeSql fsql, + NLogManager logManager, + IIdGenerator idGenerator, + IMemoryCache memoryCache, + RobotBusiness robotBusiness) : base(fsql, logManager, idGenerator, memoryCache) + { + this.robotBusiness = robotBusiness; + } + + public void D21Singnal(D21SingalRequest d21SingalRequest) + { + //logManager.GetLogger("D21").Info(JsonConvert.SerializeObject(d21SingalRequest)); + var robotList = robotBusiness.GetD21PolicyRobotList(Enums.RobotState.Runing, d21SingalRequest.KLinePeriodic, d21SingalRequest.Symbol, false, true); + if (robotList == null || robotList.Count() == 0) + throw new BusinessException("未找到符合条件的机器人"); + + var robot = robotList.FirstOrDefault(); + switch (d21SingalRequest.SingalType) + { + case Enums.SingalType.小趋势看空: + case Enums.SingalType.小趋势看多: + + break; + case Enums.SingalType.多交叉: + + break; + case Enums.SingalType.空交叉: + + break; + } + } + } +} diff --git a/Binance.TradeRobot.Model/Base/Enums.cs b/Binance.TradeRobot.Model/Base/Enums.cs index 40154fc..7a75bc4 100644 --- a/Binance.TradeRobot.Model/Base/Enums.cs +++ b/Binance.TradeRobot.Model/Base/Enums.cs @@ -147,5 +147,29 @@ namespace Binance.TradeRobot.Model.Base _1M } #endregion + + #region 信号 + /// + /// 信号类型 + /// + /// 买入=0,卖出=1,做多=2,做空=3,大趋势看多=4大趋势看空=5中趋势看多=6中趋势看空=7小趋势看多=8小趋势看空=9,多交叉=10,空交叉=11 + /// + /// + public enum SingalType + { + 买入 = 0, + 卖出 = 1, + 做多 = 2, + 做空 = 3, + 大趋势看多 = 4, + 大趋势看空 = 5, + 中趋势看多 = 6, + 中趋势看空 = 7, + 小趋势看多 = 8, + 小趋势看空 = 9, + 多交叉 = 10, + 空交叉 = 11 + } + #endregion } } diff --git a/Binance.TradeRobot.Model/Base/MappingProfiles.cs b/Binance.TradeRobot.Model/Base/MappingProfiles.cs index 4a9ef0d..97e3c2c 100644 --- a/Binance.TradeRobot.Model/Base/MappingProfiles.cs +++ b/Binance.TradeRobot.Model/Base/MappingProfiles.cs @@ -23,7 +23,10 @@ namespace Binance.TradeRobot.Model.Base .ForPath(t => t.RobotAccount.ClosePositionCount, opt => opt.MapFrom(f => f.ClosePositionCount)) .ForPath(t => t.RobotAccount.LoanAmount, opt => opt.MapFrom(f => f.LoanAmount)) .ForPath(t => t.RobotAccount.TotalProfit, opt => opt.MapFrom(f => f.TotalProfit)) - .ForPath(t => t.RobotAccount.WinCount, opt => opt.MapFrom(f => f.WinCount)); + .ForPath(t => t.RobotAccount.WinCount, opt => opt.MapFrom(f => f.WinCount)) + .ForPath(t => t.ExchangeAPIKey.AccountId, opt => opt.MapFrom(f => f.ExchangeAccountId)) + .ForPath(t => t.ExchangeAPIKey.APIKey, opt => opt.MapFrom(f => f.ExchangeAPIKey)) + .ForPath(t => t.ExchangeAPIKey.SecretKey, opt => opt.MapFrom(f => f.ExchangeSecretKey)); CreateMap().IncludeBase() .ForPath(t => t.D21Policy.Id, opt => opt.MapFrom(f => f.D21PolicyId)) .ForPath(t => t.D21Policy.RobotId, opt => opt.MapFrom(f => f.Id)) diff --git a/Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml b/Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml index ec5b4f0..470c6fc 100644 --- a/Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml +++ b/Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml @@ -109,6 +109,14 @@ 信号周期 1m=0,3m=1,5m=2,15m=3,30m=4,1h=5,2h=6,4h=7,6h=8,8h=9,12h=10,1d=11,3d=12,1w=13,1M=14 + + + 信号类型 + + 买入=0,卖出=1,做多=2,做空=3,大趋势看多=4大趋势看空=5中趋势看多=6中趋势看空=7小趋势看多=8小趋势看空=9,多交叉=10,空交叉=11 + + + 交易所账号UID @@ -504,6 +512,36 @@ 交易所APIKeyId + + + 交易对 + + + + + 备注 + + + + + 最高价 + + + + + 最低价 + + + + + 开盘价 + + + + + 收盘价 + + 最大系统借币比例 diff --git a/Binance.TradeRobot.Model/Db/Order/ExecutionLog.cs b/Binance.TradeRobot.Model/Db/Order/ExecutionLog.cs index 6c489dc..3734598 100644 --- a/Binance.TradeRobot.Model/Db/Order/ExecutionLog.cs +++ b/Binance.TradeRobot.Model/Db/Order/ExecutionLog.cs @@ -1,3 +1,4 @@ +using Binance.TradeRobot.Model.Base; using FreeSql.DataAnnotations; using System; @@ -19,6 +20,9 @@ namespace Binance.TradeRobot.Model.Db [Column(DbType = "bigint")] public long RobotId { get; set; } + [Column(MapType = typeof(int), DbType = "int")] + public Enums.SingalType SourceSingal { get; set; } + } } diff --git a/Binance.TradeRobot.Model/Db/Robot/Robot.cs b/Binance.TradeRobot.Model/Db/Robot/Robot.cs index 3fe9b6c..53c8fbf 100644 --- a/Binance.TradeRobot.Model/Db/Robot/Robot.cs +++ b/Binance.TradeRobot.Model/Db/Robot/Robot.cs @@ -78,6 +78,15 @@ namespace Binance.TradeRobot.Model.Db public decimal LoanAmount { get; set; } = 0.0M; #endregion + #region ExchangeAPIKey Extension + [Column(IsIgnore = true)] + public long ExchangeAccountId { get; set; } + [Column(IsIgnore = true)] + public string ExchangeAPIKey { get; set; } + [Column(IsIgnore = true)] + public string ExchangeSecretKey { get; set; } + #endregion + #region D21Policy Extension [Column(IsIgnore = true)] public long D21PolicyId { get; set; } diff --git a/Binance.TradeRobot.Model/Dto/Request/Singal/BaseSingalRequest.cs b/Binance.TradeRobot.Model/Dto/Request/Singal/BaseSingalRequest.cs new file mode 100644 index 0000000..a32e1b9 --- /dev/null +++ b/Binance.TradeRobot.Model/Dto/Request/Singal/BaseSingalRequest.cs @@ -0,0 +1,41 @@ +using Binance.TradeRobot.Model.Base; + +namespace Binance.TradeRobot.Model.Dto +{ + public class BaseSingalRequest + { + public Enums.SingalType SingalType { get; set; } + + /// + /// 交易对 + /// + public string Symbol { get; set; } + + public Enums.SignalPeriod KLinePeriodic { get; set; } + + /// + /// 备注 + /// + public string Remark { get; set; } + + /// + /// 最高价 + /// + public decimal HighestPrice { get; set; } + + /// + /// 最低价 + /// + public decimal LowestPrice { get; set; } + + /// + /// 开盘价 + /// + public decimal OpenPrice { get; set; } + + /// + /// 收盘价 + /// + public decimal ClosePrice { get; set; } + } +} diff --git a/Binance.TradeRobot.Model/Dto/Request/Singal/D21SingalRequest.cs b/Binance.TradeRobot.Model/Dto/Request/Singal/D21SingalRequest.cs new file mode 100644 index 0000000..365f73a --- /dev/null +++ b/Binance.TradeRobot.Model/Dto/Request/Singal/D21SingalRequest.cs @@ -0,0 +1,7 @@ +namespace Binance.TradeRobot.Model.Dto +{ + public class D21SingalRequest : BaseSingalRequest + { + + } +} diff --git a/Binance.TradeRobot.Model/Dto/Response/Exchange/ExchangeAPIKeyResponse.cs b/Binance.TradeRobot.Model/Dto/Response/Exchange/ExchangeAPIKeyResponse.cs index 7ca2013..3af0aea 100644 --- a/Binance.TradeRobot.Model/Dto/Response/Exchange/ExchangeAPIKeyResponse.cs +++ b/Binance.TradeRobot.Model/Dto/Response/Exchange/ExchangeAPIKeyResponse.cs @@ -12,4 +12,11 @@ /// public string RobotSymbol { get; set; } } + + public class SimpleExchangeAPIKeyResponse + { + public long AccountId { get; set; } + public string APIKey { get; set; } + public string SecretKey { get; set; } + } } diff --git a/Binance.TradeRobot.Model/Dto/Response/Robot/RobotResponse.cs b/Binance.TradeRobot.Model/Dto/Response/Robot/RobotResponse.cs index ebf8f4d..29d80ad 100644 --- a/Binance.TradeRobot.Model/Dto/Response/Robot/RobotResponse.cs +++ b/Binance.TradeRobot.Model/Dto/Response/Robot/RobotResponse.cs @@ -26,5 +26,10 @@ namespace Binance.TradeRobot.Model.Dto /// 机器人账户对象 /// public RobotAccountResponse RobotAccount { get; set; } + + /// + /// 机器人绑定的交易所APIKey对象 + /// + public SimpleExchangeAPIKeyResponse ExchangeAPIKey { get; set; } } }