|
|
@ -1,16 +1,15 @@ |
|
|
|
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 Binance.TradeRobot.Model.RuningInfo; |
|
|
|
using Microsoft.Extensions.Caching.Memory; |
|
|
|
using Microsoft.Extensions.DependencyInjection; |
|
|
|
using Newtonsoft.Json; |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Linq; |
|
|
|
using System.Text; |
|
|
|
using System.Threading; |
|
|
|
using Yitter.IdGenerator; |
|
|
|
|
|
|
@ -57,7 +56,7 @@ namespace Binance.TradeRobot.Business |
|
|
|
logList.Add(new ExecutionLog() |
|
|
|
{ |
|
|
|
Id = idGenerator.NewLong(), |
|
|
|
SourceSingal = Enums.SingalType.多交叉, |
|
|
|
SourceSingal = singalRequest.SingalType, |
|
|
|
RobotId = robot.Id, |
|
|
|
CreateTime = DateTime.Now, |
|
|
|
Content = $"收到信号{singalRequest.SingalType}{(isRemedy ? "(补救)" : string.Empty)}" |
|
|
@ -210,10 +209,12 @@ namespace Binance.TradeRobot.Business |
|
|
|
|
|
|
|
#region 下单
|
|
|
|
step = "下单"; |
|
|
|
var clientOrderId = CreateClientOrderId(robot.Id); |
|
|
|
var orderId = apiClient.IsolatedMarginPlaceOrder(robot.Symbol, |
|
|
|
Enums.TradeDirection.Buy, |
|
|
|
Enums.OrderType.MARKET, |
|
|
|
quoteAmount: previewTradeAmount); |
|
|
|
quoteAmount: previewTradeAmount, |
|
|
|
newClientOrderId: clientOrderId); |
|
|
|
var buyOrder = new SpotOrder() |
|
|
|
{ |
|
|
|
Id = orderId, |
|
|
@ -228,6 +229,14 @@ namespace Binance.TradeRobot.Business |
|
|
|
TradeDirection = Enums.TradeDirection.Buy |
|
|
|
}; |
|
|
|
|
|
|
|
logList.Add(new ExecutionLog() |
|
|
|
{ |
|
|
|
Id = idGenerator.NewLong(), |
|
|
|
SourceSingal = singalRequest.SingalType, |
|
|
|
RobotId = robot.Id, |
|
|
|
CreateTime = DateTime.Now, |
|
|
|
Content = $"市价买单挂单成功,orderId:{orderId}" |
|
|
|
}); |
|
|
|
fsql.Transaction(() => |
|
|
|
{ |
|
|
|
fsql.Insert(logList).ExecuteAffrows(); |
|
|
@ -241,24 +250,113 @@ namespace Binance.TradeRobot.Business |
|
|
|
catch (Exception ex) |
|
|
|
{ |
|
|
|
HandleError(ex, singalRequest.SingalType, logList, robot, step); |
|
|
|
//logList.Add(new ExecutionLog()
|
|
|
|
//{
|
|
|
|
// Id = idGenerator.NewLong(),
|
|
|
|
// SourceSingal = Enums.SingalType.多交叉,
|
|
|
|
// RobotId = robot.Id,
|
|
|
|
// CreateTime = DateTime.Now,
|
|
|
|
// Content = ex.Message
|
|
|
|
//});
|
|
|
|
//try { fsql.Insert(logList).ExecuteAffrows(); } catch { }
|
|
|
|
//var errorMsg = $"交易警报,{singalRequest.SingalType},{robot.ExecuteLogKey},{robot.Id},{step}";
|
|
|
|
//logManager.GetLogger(robot.ExecuteLogKey).Error(ex, errorMsg);
|
|
|
|
//dingBusiness.Send($"{errorMsg} {ex.Message}");
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void ShortCross<T, T1>(T singalRequest, T1 robot, bool isRemedy, SymbolInfoResponse symbolInfo) where T : BaseSingalRequest where T1 : RobotResponse |
|
|
|
{ |
|
|
|
string step = string.Empty; |
|
|
|
var logList = new List<ExecutionLog>(); |
|
|
|
logList.Add(new ExecutionLog() |
|
|
|
{ |
|
|
|
Id = idGenerator.NewLong(), |
|
|
|
SourceSingal = singalRequest.SingalType, |
|
|
|
RobotId = robot.Id, |
|
|
|
CreateTime = DateTime.Now, |
|
|
|
Content = $"收到信号{singalRequest.SingalType}{(isRemedy ? "(补救)" : string.Empty)}" |
|
|
|
}); |
|
|
|
|
|
|
|
try |
|
|
|
{ |
|
|
|
var d21RuningInfo = RedisHelper.Get<D21RuningInfo>(robot.Id.ToString()) ?? new D21RuningInfo() { RobotId = robot.Id }; |
|
|
|
|
|
|
|
#region 验证信号
|
|
|
|
step = "验证信号"; |
|
|
|
if (!isRemedy) |
|
|
|
{ |
|
|
|
if (d21RuningInfo.ErrorCrossSingal != null) |
|
|
|
{ |
|
|
|
d21RuningInfo.ErrorCrossSingal = null; |
|
|
|
d21RuningInfo.ErrorCrossSingalTime = 0; |
|
|
|
RedisHelper.Set(robot.Id.ToString(), d21RuningInfo); |
|
|
|
throw new BusinessException("前一个信号错误,终止空交叉信号执行"); |
|
|
|
} |
|
|
|
|
|
|
|
if (d21RuningInfo.RecentSmallTrendSingal == null) |
|
|
|
throw new BusinessException("缺少小趋势,终止空交叉信号执行"); |
|
|
|
|
|
|
|
if (d21RuningInfo.RecentSmallTrendSingal == Enums.SingalType.小趋势看多) |
|
|
|
{ |
|
|
|
var errorTimeStamp = DateTime.Now.GetKID(singalRequest.KLinePeriodic, false); |
|
|
|
Thread.Sleep(5000); //防止空交叉和小趋势看空同时接收造成误判
|
|
|
|
d21RuningInfo = RedisHelper.Get<D21RuningInfo>(robot.Id.ToString()) ?? new D21RuningInfo() { RobotId = robot.Id }; |
|
|
|
if (d21RuningInfo.RecentSmallTrendSingal == Enums.SingalType.小趋势看多) |
|
|
|
{ |
|
|
|
d21RuningInfo.ErrorCrossSingal = singalRequest.SingalType; |
|
|
|
d21RuningInfo.ErrorCrossSingalTime = errorTimeStamp; |
|
|
|
RedisHelper.Set(robot.Id.ToString(), d21RuningInfo); |
|
|
|
throw new BusinessException("小趋势看多,终止空交叉信号执行"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region 验证卖币数量
|
|
|
|
step = "验证卖币数量"; |
|
|
|
var saleQuantity = robot.RobotAccount.SpotCurrencyQuantity.CutDecimal(symbolInfo.SaleQuantityAccuracy); |
|
|
|
if (saleQuantity == 0M) |
|
|
|
throw new BusinessException("没有足够的卖币数量"); |
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region 下单
|
|
|
|
step = "下单"; |
|
|
|
var newestPrice = globalContext.GetSpotNewestPrice(robot.KLineKey) ?? singalRequest.ClosePrice; |
|
|
|
var apiClient = GetBaseAPIClient(robot.ExchangeId, robot.ExchangeAPIKey.AccountId, robot.ExchangeAPIKey.APIKey, robot.ExchangeAPIKey.SecretKey); |
|
|
|
|
|
|
|
var clientOrderId = CreateClientOrderId(robot.Id); |
|
|
|
var orderId = apiClient.IsolatedMarginPlaceOrder(robot.Symbol, |
|
|
|
Enums.TradeDirection.Sell, |
|
|
|
Enums.OrderType.MARKET, |
|
|
|
quantity: saleQuantity, |
|
|
|
newClientOrderId: clientOrderId); |
|
|
|
|
|
|
|
var sellOrder = new SpotOrder() |
|
|
|
{ |
|
|
|
Id = orderId, |
|
|
|
CreateTime = DateTime.Now, |
|
|
|
ExchangeId = robot.ExchangeId, |
|
|
|
OrderType = Enums.OrderType.MARKET, |
|
|
|
PolicyType = Enums.TradePolicy.D21, |
|
|
|
RobotId = robot.Id, |
|
|
|
State = Enums.SpotOrderState.Created, |
|
|
|
Symbol = robot.Symbol, |
|
|
|
TradeDirection = Enums.TradeDirection.Sell |
|
|
|
}; |
|
|
|
|
|
|
|
logList.Add(new ExecutionLog() |
|
|
|
{ |
|
|
|
Id = idGenerator.NewLong(), |
|
|
|
SourceSingal = singalRequest.SingalType, |
|
|
|
RobotId = robot.Id, |
|
|
|
CreateTime = DateTime.Now, |
|
|
|
Content = $"市价卖单挂单成功,orderId:{orderId}" |
|
|
|
}); |
|
|
|
fsql.Transaction(() => |
|
|
|
{ |
|
|
|
fsql.Insert(logList).ExecuteAffrows(); |
|
|
|
fsql.Insert(sellOrder).ExecuteAffrows(); |
|
|
|
}); |
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region 更新空交叉卖出成功时的成交价
|
|
|
|
d21RuningInfo.RecentShortCrossSignalTradePrice = newestPrice; |
|
|
|
RedisHelper.Set(robot.Id.ToString(), d21RuningInfo); |
|
|
|
#endregion
|
|
|
|
} |
|
|
|
catch (Exception ex) |
|
|
|
{ |
|
|
|
HandleError(ex, singalRequest.SingalType, logList, robot, step); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|