From 77d87d3be36e65a6050356eaf39b8f7198f81538 Mon Sep 17 00:00:00 2001
From: shanj <18996038927@163.com>
Date: Mon, 14 Mar 2022 04:18:03 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=88=9B=E5=BB=BA=E9=87=91?=
=?UTF-8?q?=E5=AD=97=E5=A1=94=E7=AD=96=E7=95=A5=E6=9C=BA=E5=99=A8=E4=BA=BA?=
=?UTF-8?q?=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.editorconfig | 3 +
.../Binance.TradeRobot.API.xml | 13 +++
.../Controllers/ExchangeAccountController.cs | 11 +++
.../Controllers/RobotController.cs | 29 ++++++
Binance.TradeRobot.API/Startup.cs | 2 -
.../Binance.TradeRobot.Business.xml | 36 ++++++-
.../{ => Business}/BaseBusiness.cs | 0
.../ExchangeBusiness.cs | 32 +++++--
.../Business/RobotBusiness.cs | 93 +++++++++++++++++++
.../{User => Business}/UserBusiness.cs | 0
.../Extensions/RobotExtension.cs | 24 +++++
.../Base/MappingProfiles.cs | 2 +
.../Binance.TradeRobot.Model.csproj | 4 -
.../Binance.TradeRobot.Model.xml | 70 ++++++++++++++
.../Db/Policy/UPrep/PyramidPolicy.cs | 17 +++-
.../Db/Robot/RobotAccount.cs | 46 +++++++++
.../Robot/AddPyramidPolicyRobotRequest.cs | 27 ++++++
.../Dto/Request/Robot/AddRobotRequest.cs | 17 ++++
18 files changed, 409 insertions(+), 17 deletions(-)
create mode 100644 Binance.TradeRobot.API/Controllers/RobotController.cs
rename Binance.TradeRobot.Business/{ => Business}/BaseBusiness.cs (100%)
rename Binance.TradeRobot.Business/{Exchange => Business}/ExchangeBusiness.cs (81%)
create mode 100644 Binance.TradeRobot.Business/Business/RobotBusiness.cs
rename Binance.TradeRobot.Business/{User => Business}/UserBusiness.cs (100%)
create mode 100644 Binance.TradeRobot.Business/Extensions/RobotExtension.cs
create mode 100644 Binance.TradeRobot.Model/Db/Robot/RobotAccount.cs
create mode 100644 Binance.TradeRobot.Model/Dto/Request/Robot/AddPyramidPolicyRobotRequest.cs
create mode 100644 Binance.TradeRobot.Model/Dto/Request/Robot/AddRobotRequest.cs
diff --git a/.editorconfig b/.editorconfig
index 0db2396..cd7ccf1 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -5,3 +5,6 @@ dotnet_diagnostic.CS8618.severity = none
# CS1591: 缺少对公共可见类型或成员的 XML 注释
dotnet_diagnostic.CS1591.severity = none
+
+# CS8625: 无法将 null 字面量转换为非 null 的引用类型。
+dotnet_diagnostic.CS8625.severity = none
diff --git a/Binance.TradeRobot.API/Binance.TradeRobot.API.xml b/Binance.TradeRobot.API/Binance.TradeRobot.API.xml
index ecc2412..a4bb4d5 100644
--- a/Binance.TradeRobot.API/Binance.TradeRobot.API.xml
+++ b/Binance.TradeRobot.API/Binance.TradeRobot.API.xml
@@ -23,6 +23,19 @@
交易策略
+
+
+ 获取APIKey未使用的交易所账户列表
+
+
+
+
+
+
+ 创建金字塔策略合约机器人
+
+
+
用户登录
diff --git a/Binance.TradeRobot.API/Controllers/ExchangeAccountController.cs b/Binance.TradeRobot.API/Controllers/ExchangeAccountController.cs
index da80604..eb88f78 100644
--- a/Binance.TradeRobot.API/Controllers/ExchangeAccountController.cs
+++ b/Binance.TradeRobot.API/Controllers/ExchangeAccountController.cs
@@ -48,5 +48,16 @@ namespace Binance.TradeRobot.API.Controllers
{
return exchangeBusiness.GetExchangeAccountList(tradePolicy);
}
+
+ ///
+ /// 获取APIKey未使用的交易所账户列表
+ ///
+ ///
+ ///
+ [HttpGet("{tradePolicy}")]
+ public IList GetNoUsedExchangeAccountList([FromRoute]Enums.TradePolicy tradePolicy)
+ {
+ return exchangeBusiness.GetNoUsedExchangeAccountList(tradePolicy);
+ }
}
}
diff --git a/Binance.TradeRobot.API/Controllers/RobotController.cs b/Binance.TradeRobot.API/Controllers/RobotController.cs
new file mode 100644
index 0000000..7e51e55
--- /dev/null
+++ b/Binance.TradeRobot.API/Controllers/RobotController.cs
@@ -0,0 +1,29 @@
+using Binance.TradeRobot.Business;
+using Binance.TradeRobot.Model.Dto;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Binance.TradeRobot.API.Controllers
+{
+ [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
+ public class RobotController : BaseApiController
+ {
+ private RobotBusiness robotBusiness;
+
+ public RobotController(RobotBusiness robotBusiness)
+ {
+ this.robotBusiness = robotBusiness;
+ }
+
+ ///
+ /// 创建金字塔策略合约机器人
+ ///
+ ///
+ [HttpPost]
+ public void AddPyramidPolicyRobot([FromBody] AddPyramidPolicyRobotRequest addPyramidPolicyRobotRequest)
+ {
+ robotBusiness.AddPyramidPolicyRobot(addPyramidPolicyRobotRequest);
+ }
+ }
+}
diff --git a/Binance.TradeRobot.API/Startup.cs b/Binance.TradeRobot.API/Startup.cs
index 0b2fc3d..ccd5fc5 100644
--- a/Binance.TradeRobot.API/Startup.cs
+++ b/Binance.TradeRobot.API/Startup.cs
@@ -4,13 +4,11 @@ using Binance.TradeRobot.Business;
using Binance.TradeRobot.Common.Extensions;
using Binance.TradeRobot.Common.Http;
using Binance.TradeRobot.Model.Base;
-using HY.TradingRobot.Model.Base;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
diff --git a/Binance.TradeRobot.Business/Binance.TradeRobot.Business.xml b/Binance.TradeRobot.Business/Binance.TradeRobot.Business.xml
index a3d173f..0d455e1 100644
--- a/Binance.TradeRobot.Business/Binance.TradeRobot.Business.xml
+++ b/Binance.TradeRobot.Business/Binance.TradeRobot.Business.xml
@@ -4,12 +4,26 @@
Binance.TradeRobot.Business
-
+
- 计算成员分红/本金比例
+ 获取APIKey未使用交易所账户列表
-
- 比例乘100
+
+
+
+
+
+ 检查机器人注册条件
+
+
+
+
+
+
+
+ 添加金字塔策略机器人
+
+
@@ -22,5 +36,19 @@
+
+
+ 获取交易策略对应的业务类型
+
+
+
+
+
+
+ 计算成员分红/本金比例
+
+
+ 比例乘100
+
diff --git a/Binance.TradeRobot.Business/BaseBusiness.cs b/Binance.TradeRobot.Business/Business/BaseBusiness.cs
similarity index 100%
rename from Binance.TradeRobot.Business/BaseBusiness.cs
rename to Binance.TradeRobot.Business/Business/BaseBusiness.cs
diff --git a/Binance.TradeRobot.Business/Exchange/ExchangeBusiness.cs b/Binance.TradeRobot.Business/Business/ExchangeBusiness.cs
similarity index 81%
rename from Binance.TradeRobot.Business/Exchange/ExchangeBusiness.cs
rename to Binance.TradeRobot.Business/Business/ExchangeBusiness.cs
index 3e19a6d..ca0b772 100644
--- a/Binance.TradeRobot.Business/Exchange/ExchangeBusiness.cs
+++ b/Binance.TradeRobot.Business/Business/ExchangeBusiness.cs
@@ -1,4 +1,5 @@
-using Binance.TradeRobot.Common.DI;
+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;
@@ -32,11 +33,7 @@ namespace Binance.TradeRobot.Business.Exchange
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;
+ exchangeAccount.BusinessType = addExchangeAccountRequest.TradePolicy.GetBusinessType();
var exchangeAPIKey = new ExchangeAPIKey()
{
@@ -133,5 +130,28 @@ namespace Binance.TradeRobot.Business.Exchange
ewh.Set();
}
}
+
+ ///
+ /// 获取APIKey未使用交易所账户列表
+ ///
+ ///
+ ///
+ public IList GetNoUsedExchangeAccountList(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().Where(k => k.RobotId == null && accountIdList.Contains(k.AccountId))
+ .ToList()
+ .Map>();
+
+ 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;
+ }
}
}
diff --git a/Binance.TradeRobot.Business/Business/RobotBusiness.cs b/Binance.TradeRobot.Business/Business/RobotBusiness.cs
new file mode 100644
index 0000000..6f798b1
--- /dev/null
+++ b/Binance.TradeRobot.Business/Business/RobotBusiness.cs
@@ -0,0 +1,93 @@
+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.Data.Common;
+using Yitter.IdGenerator;
+
+namespace Binance.TradeRobot.Business
+{
+ [BatchRegistration(ServiceLifetime.Singleton, RegistrationType.Self)]
+ public class RobotBusiness : BaseBusiness
+ {
+ public RobotBusiness(IFreeSql fsql, NLogManager logManager, IIdGenerator idGenerator, IMemoryCache memoryCache) : base(fsql, logManager, idGenerator, memoryCache)
+ {
+
+ }
+
+ ///
+ /// 检查机器人注册条件
+ ///
+ ///
+ ///
+ ///
+ private void CheckRobotRegister(AddRobotRequest addRobotRequest, out ExchangeAPIKey exchangeAPIKey)
+ {
+ exchangeAPIKey = null;
+ if (string.IsNullOrEmpty(addRobotRequest.Symbol) || addRobotRequest.ExchangeAPIKeyId == 0)
+ throw new BusinessException("参数不全");
+ exchangeAPIKey = fsql.Select(addRobotRequest.ExchangeAPIKeyId).ToOne();
+ if (exchangeAPIKey == null)
+ throw new BusinessException("选择的APIKey不存在");
+ if (exchangeAPIKey.RobotId != null)
+ throw new BusinessException("APIKey已被其他机器人使用");
+
+ var accountId = exchangeAPIKey.AccountId;
+ if (fsql.Select().InnerJoin((ea, ek, r) => ea.Id == ek.AccountId)
+ .LeftJoin((ea, ek, r) => ek.RobotId == r.Id)
+ .Where((ea, ek, r) => ea.Id == accountId &&
+ r.Symbol == addRobotRequest.Symbol).Any())
+ throw new BusinessException("同一个交易所账号下只允许存在一个交易对");
+ }
+
+ private Robot CreateRobot(AddRobotRequest addRobotRequest)
+ {
+ return new Robot()
+ {
+ Id = idGenerator.NewLong(),
+ Symbol = addRobotRequest.Symbol,
+ TradePolicy = addRobotRequest.TradePolicy,
+ BusinessType = addRobotRequest.TradePolicy.GetBusinessType()
+ };
+ }
+
+ private RobotAccount CreateRobotAccount(long robotId)
+ {
+ return new RobotAccount() { Id = idGenerator.NewLong(), RobotId = robotId };
+ }
+
+ private void ExecuteAddRobotWithTran(Robot robot, RobotAccount robotAccount, long exchangeAPIKeyId, DbTransaction tran)
+ {
+ fsql.Insert(robot).WithTransaction(tran).ExecuteAffrows();
+ fsql.Insert(robotAccount).WithTransaction(tran).ExecuteAffrows();
+ fsql.Update(exchangeAPIKeyId).WithTransaction(tran).Set(ek => ek.RobotId, robot.Id).ExecuteAffrows();
+ }
+
+ ///
+ /// 添加金字塔策略机器人
+ ///
+ ///
+ public void AddPyramidPolicyRobot(AddPyramidPolicyRobotRequest addPyramidPolicyRobotRequest)
+ {
+ CheckRobotRegister(addPyramidPolicyRobotRequest, out ExchangeAPIKey exchangeAPIKey);
+ var robot = CreateRobot(addPyramidPolicyRobotRequest);
+ var robotAccount = CreateRobotAccount(robot.Id);
+ var pyramidPolicy = addPyramidPolicyRobotRequest.Map();
+ pyramidPolicy.Id = idGenerator.NewLong();
+ pyramidPolicy.RobotId = robot.Id;
+ fsql.Transaction(() =>
+ {
+ var tran = fsql.Ado.TransactionCurrentThread;
+ ExecuteAddRobotWithTran(robot, robotAccount, addPyramidPolicyRobotRequest.ExchangeAPIKeyId, tran);
+ fsql.Insert(pyramidPolicy).ExecuteAffrows();
+ });
+
+ //调整仓位杠杆倍数
+
+ }
+ }
+}
diff --git a/Binance.TradeRobot.Business/User/UserBusiness.cs b/Binance.TradeRobot.Business/Business/UserBusiness.cs
similarity index 100%
rename from Binance.TradeRobot.Business/User/UserBusiness.cs
rename to Binance.TradeRobot.Business/Business/UserBusiness.cs
diff --git a/Binance.TradeRobot.Business/Extensions/RobotExtension.cs b/Binance.TradeRobot.Business/Extensions/RobotExtension.cs
new file mode 100644
index 0000000..af53670
--- /dev/null
+++ b/Binance.TradeRobot.Business/Extensions/RobotExtension.cs
@@ -0,0 +1,24 @@
+using Binance.TradeRobot.Model.Base;
+using System.Collections.Generic;
+
+namespace Binance.TradeRobot.Business.Extensions
+{
+ public static class RobotExtension
+ {
+ private static IDictionary BusinessTypeDic = new Dictionary()
+ {
+ {Enums.TradePolicy.金字塔, Enums.BusinessType.UPrep },
+ { Enums.TradePolicy.动量趋势v2, Enums.BusinessType.Spot_Margin}
+ };
+
+ ///
+ /// 获取交易策略对应的业务类型
+ ///
+ ///
+ ///
+ public static Enums.BusinessType GetBusinessType(this Enums.TradePolicy tradePolicy)
+ {
+ return BusinessTypeDic[tradePolicy];
+ }
+ }
+}
diff --git a/Binance.TradeRobot.Model/Base/MappingProfiles.cs b/Binance.TradeRobot.Model/Base/MappingProfiles.cs
index 2027e10..b5ea5f2 100644
--- a/Binance.TradeRobot.Model/Base/MappingProfiles.cs
+++ b/Binance.TradeRobot.Model/Base/MappingProfiles.cs
@@ -15,6 +15,8 @@ namespace Binance.TradeRobot.Model.Base
CreateMap();
CreateMap();
CreateMap();
+
+ CreateMap();
}
}
}
diff --git a/Binance.TradeRobot.Model/Binance.TradeRobot.Model.csproj b/Binance.TradeRobot.Model/Binance.TradeRobot.Model.csproj
index 8c08b5a..78b48d1 100644
--- a/Binance.TradeRobot.Model/Binance.TradeRobot.Model.csproj
+++ b/Binance.TradeRobot.Model/Binance.TradeRobot.Model.csproj
@@ -12,8 +12,4 @@
-
-
-
-
diff --git a/Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml b/Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml
index b25f981..4ce0f16 100644
--- a/Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml
+++ b/Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml
@@ -94,11 +94,51 @@
交易所账号Id
+
+
+ 杠杆倍数(1-125整数)
+
+
+
+
+ 仓位
+
+
+
+
+ 金字塔
+
+
运行时长(s)
+
+
+ 平仓次数
+
+
+
+
+ 现货/杠杆持仓金额
+
+
+
+
+ 现货/杠杆持仓数量
+
+
+
+
+ 总收益
+
+
+
+
+ 盈利次数
+
+
投资本金
@@ -164,6 +204,36 @@
交易策略
+
+
+ 信号周期
+
+
+
+
+ 杠杆倍数
+
+
+
+
+ 仓位
+
+
+
+
+ 金字塔
+
+
+
+
+ 交易对
+
+
+
+
+ 交易所APIKeyId
+
+
密码需要Md5小写加密
diff --git a/Binance.TradeRobot.Model/Db/Policy/UPrep/PyramidPolicy.cs b/Binance.TradeRobot.Model/Db/Policy/UPrep/PyramidPolicy.cs
index 090169f..0a0603a 100644
--- a/Binance.TradeRobot.Model/Db/Policy/UPrep/PyramidPolicy.cs
+++ b/Binance.TradeRobot.Model/Db/Policy/UPrep/PyramidPolicy.cs
@@ -6,7 +6,6 @@ namespace Binance.TradeRobot.Model.Db
[Table(DisableSyncStructure = true)]
public partial class PyramidPolicy
{
-
[Column(IsPrimary = true)]
public long Id { get; set; }
@@ -14,6 +13,22 @@ namespace Binance.TradeRobot.Model.Db
public Enums.SignalPeriod SignalPeriod { get; set; }
public long RobotId { get; set; }
+
+ ///
+ /// ܸ˱(1-125)
+ ///
+ public int Leverage { get; set; } = 1;
+
+ ///
+ /// λ
+ ///
+ [Column(DbType = "decimal(18,8)")]
+ public decimal Position { get; set; } = 0M;
+
+ ///
+ ///
+ ///
+ public int Pyramid { get; set; } = 0;
}
}
diff --git a/Binance.TradeRobot.Model/Db/Robot/RobotAccount.cs b/Binance.TradeRobot.Model/Db/Robot/RobotAccount.cs
new file mode 100644
index 0000000..838922f
--- /dev/null
+++ b/Binance.TradeRobot.Model/Db/Robot/RobotAccount.cs
@@ -0,0 +1,46 @@
+using FreeSql.DataAnnotations;
+
+namespace Binance.TradeRobot.Model.Db
+{
+
+ [Table(DisableSyncStructure = true)]
+ public partial class RobotAccount
+ {
+
+ [Column(IsPrimary = true)]
+ public long Id { get; set; }
+
+ ///
+ /// 平仓次数
+ ///
+ public long ClosePositionCount { get; set; } = 0;
+
+
+ public long RobotId { get; set; }
+
+ ///
+ /// 现货/杠杆持仓金额
+ ///
+ [Column(DbType = "decimal(18,8)")]
+ public decimal SoptCurrentcyAmount { get; set; } = 0.0M;
+
+ ///
+ /// 现货/杠杆持仓数量
+ ///
+ [Column(DbType = "decimal(18,8)")]
+ public decimal SpotCurrencyQuantity { get; set; } = 0.0M;
+
+ ///
+ /// 总收益
+ ///
+ [Column(DbType = "decimal(18,8)")]
+ public decimal TotalProfit { get; set; } = 0.0M;
+
+ ///
+ /// 盈利次数
+ ///
+ public long WinCount { get; set; } = 0;
+
+ }
+
+}
diff --git a/Binance.TradeRobot.Model/Dto/Request/Robot/AddPyramidPolicyRobotRequest.cs b/Binance.TradeRobot.Model/Dto/Request/Robot/AddPyramidPolicyRobotRequest.cs
new file mode 100644
index 0000000..ae46774
--- /dev/null
+++ b/Binance.TradeRobot.Model/Dto/Request/Robot/AddPyramidPolicyRobotRequest.cs
@@ -0,0 +1,27 @@
+using Binance.TradeRobot.Model.Base;
+
+namespace Binance.TradeRobot.Model.Dto
+{
+ public class AddPyramidPolicyRobotRequest : AddRobotRequest
+ {
+ ///
+ /// 信号周期
+ ///
+ public Enums.SignalPeriod SignalPeriod { get; set; }
+
+ ///
+ /// 杠杆倍数
+ ///
+ public int Leverage { get; set; }
+
+ ///
+ /// 仓位
+ ///
+ public decimal Position { get; set; }
+
+ ///
+ /// 金字塔
+ ///
+ public int Pyramid { get; set; }
+ }
+}
diff --git a/Binance.TradeRobot.Model/Dto/Request/Robot/AddRobotRequest.cs b/Binance.TradeRobot.Model/Dto/Request/Robot/AddRobotRequest.cs
new file mode 100644
index 0000000..e1f86fe
--- /dev/null
+++ b/Binance.TradeRobot.Model/Dto/Request/Robot/AddRobotRequest.cs
@@ -0,0 +1,17 @@
+using Binance.TradeRobot.Model.Base;
+
+namespace Binance.TradeRobot.Model.Dto
+{
+ public class AddRobotRequest
+ {
+ ///
+ /// 交易对
+ ///
+ public string Symbol { get; set; }
+ public Enums.TradePolicy TradePolicy { get; set; }
+ ///
+ /// 交易所APIKeyId
+ ///
+ public long ExchangeAPIKeyId { get; set; }
+ }
+}