Browse Source

完善回调

master
shanji 3 years ago
parent
commit
a5897c28a4
  1. 7
      Binance.TradeRobot.Business/Binance.TradeRobot.Business.xml
  2. 5
      Binance.TradeRobot.Business/Business/OrderPublishBusiness/Spot/BaseSpotOrderPublishBusiness.cs
  3. 116
      Binance.TradeRobot.Business/Business/OrderPublishBusiness/Spot/D21OrderPublishBusiness.cs
  4. 2
      Binance.TradeRobot.Business/Business/RobotBusiness.cs
  5. 52
      Binance.TradeRobot.Business/Business/UserBusiness.cs
  6. 2
      Binance.TradeRobot.Model/Base/MappingProfiles.cs
  7. 12
      Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml
  8. 2
      Binance.TradeRobot.Model/Db/Robot/Robot.cs
  9. 4
      Binance.TradeRobot.Model/Db/Robot/RobotAccount.cs
  10. 40
      Binance.TradeRobot.Model/Dto/Response/User/UserResponse.cs

7
Binance.TradeRobot.Business/Binance.TradeRobot.Business.xml

@ -12,6 +12,13 @@
<param name="exchangeId"></param>
<returns></returns>
</member>
<member name="M:Binance.TradeRobot.Business.BaseSpotOrderPublishBusiness.CheckOrderExists(System.Int64)">
<summary>
检查订单是否存在
</summary>
<param name="orderId"></param>
<exception cref="T:Binance.TradeRobot.Model.Base.BusinessException">订单不存在异常</exception>
</member>
<member name="M:Binance.TradeRobot.Business.RobotBusiness.CheckRobotRegister(Binance.TradeRobot.Model.Dto.AddRobotRequest,Binance.TradeRobot.Model.Db.ExchangeAPIKey@)">
<summary>
检查机器人注册条件

5
Binance.TradeRobot.Business/Business/OrderPublishBusiness/Spot/BaseSpotOrderPublishBusiness.cs

@ -13,16 +13,19 @@ namespace Binance.TradeRobot.Business
{
protected DingBusiness dingBusiness;
protected RobotBusiness robotBusiness;
protected UserBusiness userBusiness;
public BaseSpotOrderPublishBusiness(IFreeSql fsql,
NLogManager logManager,
IIdGenerator idGenerator,
IMemoryCache memoryCache,
DingBusiness dingBusiness,
RobotBusiness robotBusiness) : base(fsql, logManager, idGenerator, memoryCache)
RobotBusiness robotBusiness,
UserBusiness userBusiness) : base(fsql, logManager, idGenerator, memoryCache)
{
this.dingBusiness = dingBusiness;
this.robotBusiness = robotBusiness;
this.userBusiness = userBusiness;
}
/// <summary>

116
Binance.TradeRobot.Business/Business/OrderPublishBusiness/Spot/D21OrderPublishBusiness.cs

@ -17,7 +17,7 @@ namespace Binance.TradeRobot.Business
{
public Enums.TradePolicy TradePolicy => Enums.TradePolicy.D21;
public D21OrderPublishBusiness(IFreeSql fsql, NLogManager logManager, IIdGenerator idGenerator, IMemoryCache memoryCache, DingBusiness dingBusiness, RobotBusiness robotBusiness) : base(fsql, logManager, idGenerator, memoryCache, dingBusiness, robotBusiness)
public D21OrderPublishBusiness(IFreeSql fsql, NLogManager logManager, IIdGenerator idGenerator, IMemoryCache memoryCache, DingBusiness dingBusiness, RobotBusiness robotBusiness, UserBusiness userBusiness) : base(fsql, logManager, idGenerator, memoryCache, dingBusiness, robotBusiness, userBusiness)
{
}
@ -26,19 +26,27 @@ namespace Binance.TradeRobot.Business
public void OnSpotOrderPublish(SpotOrderPublishInfo spotOrderPublishInfo)
{
//var logger = logManager.GetLogger(spotOrderPublishInfo.LoggerName);
var step = "";
var step = string.Empty;
var logList = new List<ExecutionLog>();
try
{
//step = "检查订单是否入库";
CheckOrderExists(spotOrderPublishInfo.OrderId);
//step = "查询订单所属机器人";
var robot = robotBusiness.GetD21PolicyRobotList(spotOrderPublishInfo.RobotId, isLoadRecentTradeProfit: false, isLoadAPIKey: true).FirstOrDefault();
if (robot == null)
throw new BusinessException($"未找到机器人");
IUpdate<SpotOrder> updateSpotOrder = fsql.Update<SpotOrder>(spotOrderPublishInfo.OrderId).Set(o => o.State, spotOrderPublishInfo.SpotOrderState);
IUpdate<RobotAccount> updateRobotAccount = null;
IList<IUpdate<User>> updateUserList = null;
List<UserAccountProfitLossRecord> insertUserAccountProfitLossRecordList = null;
if (spotOrderPublishInfo.SpotOrderState == Enums.SpotOrderState.Rejected || spotOrderPublishInfo.SpotOrderState == Enums.SpotOrderState.Expired)
if (spotOrderPublishInfo.SpotOrderState == Enums.SpotOrderState.Rejected ||
spotOrderPublishInfo.SpotOrderState == Enums.SpotOrderState.Expired ||
spotOrderPublishInfo.SpotOrderState == Enums.SpotOrderState.Canceled)
{
logList.Add(new ExecutionLog()
{
@ -47,12 +55,14 @@ namespace Binance.TradeRobot.Business
OrderId = spotOrderPublishInfo.OrderId,
RobotId = spotOrderPublishInfo.RobotId,
SourceSingal = Enums.SingalType.,
Content = $"收到订单推送,订单号:{spotOrderPublishInfo.OrderId},订单方向:{spotOrderPublishInfo.TradeDirection},订单类型:{spotOrderPublishInfo.OrderType},订单状态:{spotOrderPublishInfo.SpotOrderState}{(spotOrderPublishInfo.SpotOrderState == Enums.SpotOrderState.Rejected ? spotOrderPublishInfo.RejectedReason : "")}"
Content = $"收到订单推送,订单号:{spotOrderPublishInfo.OrderId},订单方向:{spotOrderPublishInfo.TradeDirection},订单类型:{spotOrderPublishInfo.OrderType},订单状态:{spotOrderPublishInfo.SpotOrderState}{(spotOrderPublishInfo.SpotOrderState == Enums.SpotOrderState.Rejected ? $",:{spotOrderPublishInfo.RejectedReason}" : string.Empty)}"
});
}
if (spotOrderPublishInfo.SpotOrderState == Enums.SpotOrderState.Filled)
{
var avgTradePrice = spotOrderPublishInfo.CummulativeTradeAmount / spotOrderPublishInfo.CummulativeTradeQuantity; //计算成交均价
logList.Add(new ExecutionLog()
{
Id = idGenerator.NewLong(),
@ -60,15 +70,107 @@ namespace Binance.TradeRobot.Business
OrderId = spotOrderPublishInfo.OrderId,
RobotId = spotOrderPublishInfo.RobotId,
SourceSingal = Enums.SingalType.,
Content = $"收到订单推送,订单号:{spotOrderPublishInfo.OrderId},订单方向:{spotOrderPublishInfo.TradeDirection},订单类型:{spotOrderPublishInfo.OrderType},订单状态:{spotOrderPublishInfo.SpotOrderState},成交额:{spotOrderPublishInfo.LastTradeAmount},成交量:{spotOrderPublishInfo.LastTradeQuantity},成交价:{spotOrderPublishInfo.LastTradePrice},手续费({spotOrderPublishInfo.FeeUnit}):{spotOrderPublishInfo.Fee}"
Content = $"收到订单" +
$"推送,订单号:{spotOrderPublishInfo.OrderId},订单方向:{spotOrderPublishInfo.TradeDirection},订单类型:{spotOrderPublishInfo.OrderType},订单状态:{spotOrderPublishInfo.SpotOrderState},成交额:{spotOrderPublishInfo.LastTradeAmount},成交量:{spotOrderPublishInfo.LastTradeQuantity},成交价:{spotOrderPublishInfo.LastTradePrice},手续费({spotOrderPublishInfo.FeeUnit}):{spotOrderPublishInfo.Fee}"
});
//更新交易信息
updateSpotOrder = updateSpotOrder.Set(o => o.TradeAmount, spotOrderPublishInfo.CummulativeTradeAmount)
.Set(o => o.TradeQuantity, spotOrderPublishInfo.CummulativeTradeQuantity)
.Set(o => o.TradePrice, spotOrderPublishInfo.CummulativeTradeAmount / spotOrderPublishInfo.CummulativeTradeQuantity)
.Set(o => o.TradePrice, avgTradePrice)
.Set(o => o.TradeFee, spotOrderPublishInfo.Fee)
.Set(o => o.TradeFeeUnit, spotOrderPublishInfo.FeeUnit);
.Set(o => o.TradeFeeUnit, spotOrderPublishInfo.FeeUnit)
.Set(o => o.LastTradeTime, spotOrderPublishInfo.LastTradeTime);
if (spotOrderPublishInfo.TradeDirection == Enums.TradeDirection.Buy)
{
var quantity = spotOrderPublishInfo.CummulativeTradeQuantity - spotOrderPublishInfo.Fee; //扣除基础币手续费,得到真实购买数量
updateRobotAccount = fsql.Update<RobotAccount>(robot.RobotAccount.Id).Set(ra => ra.SpotCurrencyQuantity + quantity)
.Set(ra => ra.SpotCurrencyAmount + spotOrderPublishInfo.CummulativeTradeAmount);
if (spotOrderPublishInfo.OrderType == Enums.OrderType.MARKET)
{
//市价买单完全成交,根据策略挂止损单
}
}
else if (spotOrderPublishInfo.TradeDirection == Enums.TradeDirection.Sell)
{
updateUserList = new List<IUpdate<User>>();
insertUserAccountProfitLossRecordList = new List<UserAccountProfitLossRecord>();
if (spotOrderPublishInfo.OrderType == Enums.OrderType.MARKET)
{
//市价卖单完全成交,取消尚未触发的限价止损单
}
var interest = 0M; //借币利息
var loanAmount = robot.RobotAccount.LoanAmount; //借币金额
if (loanAmount > 0M)
{
//还币
var apiClient = GetBaseAPIClient(robot.ExchangeId, robot.ExchangeAPIKey.AccountId, robot.ExchangeAPIKey.APIKey, robot.ExchangeAPIKey.SecretKey);
interest = apiClient.IsolatedMarginRepay(robot.Symbol, loanAmount);
}
var buyAmount = spotOrderPublishInfo.CummulativeTradeQuantity * robot.RobotAccount.SpotCurrencyAvgPrice; //本次卖出对应的持仓金额
var profit = spotOrderPublishInfo.CummulativeTradeQuantity * (avgTradePrice - robot.RobotAccount.SpotCurrencyAvgPrice) - spotOrderPublishInfo.Fee - interest; //计算利润
updateSpotOrder = updateSpotOrder.SetIf(interest > 0M, o => o.LoanInterest, interest)
.Set(o => o.Profit, profit)
.Set(o => o.HistoryTotalProfit, robot.RobotAccount.TotalProfit + profit);
updateRobotAccount = fsql.Update<RobotAccount>(robot.RobotAccount.Id).Set(ra => ra.SpotCurrencyQuantity - spotOrderPublishInfo.CummulativeTradeQuantity)
.Set(ra => ra.SpotCurrencyAmount - buyAmount)
.Set(ra => ra.TotalProfit + profit)
.Set(ra => ra.ClosePositionCount + 1)
.SetIf(profit > 0M, ra => ra.WinCount + 1)
.SetIf(interest > 0M, ra => ra.LoanAmount - loanAmount);
var capitalChangeType = profit > 0M ? Enums.CapitalChangeType.Add : Enums.CapitalChangeType.Reduce;
var userList = userBusiness.GetUserList(multiplyBy100: false);
foreach (var user in userList)
{
var changeAmount = profit * user.DividendRatio; //根据用户分红比例计算本次分红或亏损
user.ChangeAmount(capitalChangeType, Math.Abs(changeAmount), false);
var updateUser = fsql.Update<User>(user.Id).Set(u => u.CostAmount, user.CostAmount)
.Set(u => u.Profit, user.Profit);
updateUserList.Add(updateUser);
insertUserAccountProfitLossRecordList.Add(new UserAccountProfitLossRecord()
{
Id = idGenerator.NewLong(),
BusinessType = robot.BusinessType,
ChangeAmount = changeAmount,
CreateTime = DateTime.Now,
ExchangeId = robot.ExchangeId,
OrderId = spotOrderPublishInfo.OrderId,
OrderProfit = profit,
UserId = user.Id,
RobotId = robot.Id,
DividendRatio = user.DividendRatio,
UserProfit = user.Profit
});
}
}
}
fsql.Transaction(() =>
{
fsql.Insert(logList).ExecuteAffrows();
updateSpotOrder.ExecuteAffrows();
updateRobotAccount?.ExecuteAffrows();
if (insertUserAccountProfitLossRecordList != null && insertUserAccountProfitLossRecordList.Count() > 0)
fsql.Insert(insertUserAccountProfitLossRecordList).ExecuteAffrows();
if (updateUserList != null && updateUserList.Count() > 0)
foreach (var u in updateUserList)
u.ExecuteAffrows();
});
}
catch (Exception ex)
{

2
Binance.TradeRobot.Business/Business/RobotBusiness.cs

@ -248,7 +248,7 @@ namespace Binance.TradeRobot.Business
ClosePositionCount = ra.ClosePositionCount,
WinCount = ra.WinCount,
LoanAmount = ra.LoanAmount,
SoptCurrentcyAmount = ra.SoptCurrentcyAmount,
SpotCurrencyAmount = ra.SpotCurrencyAmount,
SpotCurrencyQuantity = ra.SpotCurrencyQuantity,
TotalProfit = ra.TotalProfit,

52
Binance.TradeRobot.Business/Business/UserBusiness.cs

@ -58,7 +58,7 @@ namespace Binance.TradeRobot.Business
};
}
public IList<UserResponse> GetUserList()
public IList<UserResponse> GetUserList(bool multiplyBy100 = true)
{
var userList = fsql.Select<User>().ToList(u => new UserResponse()
{
@ -70,7 +70,7 @@ namespace Binance.TradeRobot.Business
UserName = u.UserName,
WithdrawAmount = u.WithdrawAmount
});
userList.CalculateRatio();
userList.CalculateRatio(multiplyBy100);
return userList;
}
@ -102,30 +102,30 @@ namespace Binance.TradeRobot.Business
//if (totalBalance < changeAmount)
// throw new BusinessException("交易所总余额小于减持资金,不能提现");
}
if (capitalChangeType == Enums.CapitalChangeType.Add)
{
changeUser.CostAmount += changeAmount;
}
else if (capitalChangeType == Enums.CapitalChangeType.Reduce)
{
if (changeUser.Profit > 0)
{
if (changeUser.Profit >= changeAmount)
changeUser.Profit -= changeAmount; //收益足够提现,只扣收益
else
{
var lessChangeAmount = changeAmount; //收益不足提现,先扣收益,不足部分再扣本金
lessChangeAmount -= changeUser.Profit;
changeUser.Profit = 0;
changeUser.CostAmount -= lessChangeAmount;
}
}
else
{
changeUser.CostAmount -= changeAmount;
}
}
changeUser.ChangeAmount(capitalChangeType, changeAmount, true);
//if (capitalChangeType == Enums.CapitalChangeType.Add)
//{
// changeUser.CostAmount += changeAmount;
//}
//else if (capitalChangeType == Enums.CapitalChangeType.Reduce)
//{
// if (changeUser.Profit > 0)
// {
// if (changeUser.Profit >= changeAmount)
// changeUser.Profit -= changeAmount; //收益足够提现,只扣收益
// else
// {
// var lessChangeAmount = changeAmount; //收益不足提现,先扣收益,不足部分再扣本金
// lessChangeAmount -= changeUser.Profit;
// changeUser.Profit = 0;
// changeUser.CostAmount -= lessChangeAmount;
// }
// }
// else
// {
// changeUser.CostAmount -= changeAmount;
// }
//}
fsql.Transaction(() =>
{

2
Binance.TradeRobot.Model/Base/MappingProfiles.cs

@ -18,7 +18,7 @@ namespace Binance.TradeRobot.Model.Base
CreateMap<Robot, RobotResponse>().ForPath(t => t.RobotAccount.Id, opt => opt.MapFrom(f => f.RobotAccountId))
.ForPath(t => t.RobotAccount.RobotId, opt => opt.MapFrom(f => f.Id))
.ForPath(t => t.RobotAccount.SoptCurrentcyAmount, opt => opt.MapFrom(f => f.SoptCurrentcyAmount))
.ForPath(t => t.RobotAccount.SpotCurrencyAmount, opt => opt.MapFrom(f => f.SpotCurrencyAmount))
.ForPath(t => t.RobotAccount.SpotCurrencyQuantity, opt => opt.MapFrom(f => f.SpotCurrencyQuantity))
.ForPath(t => t.RobotAccount.ClosePositionCount, opt => opt.MapFrom(f => f.ClosePositionCount))
.ForPath(t => t.RobotAccount.LoanAmount, opt => opt.MapFrom(f => f.LoanAmount))

12
Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml

@ -354,7 +354,7 @@
平仓次数
</summary>
</member>
<member name="P:Binance.TradeRobot.Model.Db.Robot.SoptCurrentcyAmount">
<member name="P:Binance.TradeRobot.Model.Db.Robot.SpotCurrencyAmount">
<summary>
现货/杠杆持仓金额
</summary>
@ -449,7 +449,7 @@
平仓次数
</summary>
</member>
<member name="P:Binance.TradeRobot.Model.Db.RobotAccount.SoptCurrentcyAmount">
<member name="P:Binance.TradeRobot.Model.Db.RobotAccount.SpotCurrencyAmount">
<summary>
现货/杠杆持仓金额
</summary>
@ -790,6 +790,14 @@
分红比例
</summary>
</member>
<member name="M:Binance.TradeRobot.Model.Dto.UserResponse.ChangeAmount(Binance.TradeRobot.Model.Base.Enums.CapitalChangeType,System.Decimal,System.Boolean)">
<summary>
用户资金改变算法
</summary>
<param name="capitalChangeType"></param>
<param name="changeAmount"></param>
<param name="priorityAddCost">true:优先增加本金 false:优先增加利润</param>
</member>
<member name="P:Binance.TradeRobot.Model.RuningInfo.D21RuningInfo.RecentSmallTrendSingal">
<summary>
最近一次小趋势信号

2
Binance.TradeRobot.Model/Db/Robot/Robot.cs

@ -62,7 +62,7 @@ namespace Binance.TradeRobot.Model.Db
/// 现货/杠杆持仓金额
/// </summary>
[Column(IsIgnore = true)]
public decimal SoptCurrentcyAmount { get; set; } = 0.0M;
public decimal SpotCurrencyAmount { get; set; } = 0.0M;
/// <summary>
/// 现货/杠杆持仓数量

4
Binance.TradeRobot.Model/Db/Robot/RobotAccount.cs

@ -23,7 +23,7 @@ namespace Binance.TradeRobot.Model.Db
/// 现货/杠杆持仓金额
/// </summary>
[Column(DbType = "decimal(18,8)")]
public decimal SoptCurrentcyAmount { get; set; } = 0.0M;
public decimal SpotCurrencyAmount { get; set; } = 0.0M;
/// <summary>
/// 现货/杠杆持仓数量
@ -57,7 +57,7 @@ namespace Binance.TradeRobot.Model.Db
{
get
{
return SpotCurrencyQuantity == 0M ? 0M : SoptCurrentcyAmount / SpotCurrencyQuantity;
return SpotCurrencyQuantity == 0M ? 0M : SpotCurrencyAmount / SpotCurrencyQuantity;
}
}
}

40
Binance.TradeRobot.Model/Dto/Response/User/UserResponse.cs

@ -1,4 +1,6 @@
namespace Binance.TradeRobot.Model.Dto
using Binance.TradeRobot.Model.Base;
namespace Binance.TradeRobot.Model.Dto
{
public class UserResponse : Db.User
{
@ -16,5 +18,41 @@
/// 分红比例
/// </summary>
public decimal DividendRatio { get; set; }
/// <summary>
/// 用户资金改变算法
/// </summary>
/// <param name="capitalChangeType"></param>
/// <param name="changeAmount"></param>
/// <param name="priorityAddCost">true:优先增加本金 false:优先增加利润</param>
public void ChangeAmount(Enums.CapitalChangeType capitalChangeType, decimal changeAmount, bool priorityAddCost)
{
if (capitalChangeType == Enums.CapitalChangeType.Add)
{
if (priorityAddCost)
CostAmount += changeAmount;
else
Profit += changeAmount;
}
else if (capitalChangeType == Enums.CapitalChangeType.Reduce)
{
if (Profit > 0)
{
if (Profit >= changeAmount)
Profit -= changeAmount; //收益足够提现,只扣收益
else
{
var lessChangeAmount = changeAmount; //收益不足提现,先扣收益,不足部分再扣本金
lessChangeAmount -= Profit;
Profit = 0;
CostAmount -= lessChangeAmount;
}
}
else
{
CostAmount -= changeAmount;
}
}
}
}
}

Loading…
Cancel
Save