|
@ -4,12 +4,15 @@ using Binance.TradeRobot.Common.Extensions; |
|
|
using Binance.TradeRobot.Model.Base; |
|
|
using Binance.TradeRobot.Model.Base; |
|
|
using Binance.TradeRobot.Model.Db; |
|
|
using Binance.TradeRobot.Model.Db; |
|
|
using Binance.TradeRobot.Model.Dto; |
|
|
using Binance.TradeRobot.Model.Dto; |
|
|
|
|
|
using Binance.TradeRobot.Model.RuningInfo; |
|
|
using Microsoft.Extensions.Caching.Memory; |
|
|
using Microsoft.Extensions.Caching.Memory; |
|
|
using Microsoft.Extensions.DependencyInjection; |
|
|
using Microsoft.Extensions.DependencyInjection; |
|
|
using System; |
|
|
using System; |
|
|
using System.Collections.Generic; |
|
|
using System.Collections.Generic; |
|
|
using System.Data.Common; |
|
|
using System.Data.Common; |
|
|
using System.Linq; |
|
|
using System.Linq; |
|
|
|
|
|
using System.Threading; |
|
|
|
|
|
using System.Threading.Tasks; |
|
|
using Yitter.IdGenerator; |
|
|
using Yitter.IdGenerator; |
|
|
|
|
|
|
|
|
namespace Binance.TradeRobot.Business |
|
|
namespace Binance.TradeRobot.Business |
|
@ -20,9 +23,23 @@ namespace Binance.TradeRobot.Business |
|
|
private Lazy<GlobalContext> globalContextLazy; |
|
|
private Lazy<GlobalContext> globalContextLazy; |
|
|
private GlobalContext globalContext => globalContextLazy.Value; |
|
|
private GlobalContext globalContext => globalContextLazy.Value; |
|
|
|
|
|
|
|
|
public RobotBusiness(IFreeSql fsql, NLogManager logManager, IIdGenerator idGenerator, IMemoryCache memoryCache, IServiceProvider serviceProvider) : base(fsql, logManager, idGenerator, memoryCache) |
|
|
private IEnumerable<ITradeBusiness> tradeBusinessList; |
|
|
|
|
|
private TaskSchedulerManager taskSchedulerManager; |
|
|
|
|
|
private ExchangeBusiness exchangeBusiness; |
|
|
|
|
|
|
|
|
|
|
|
public RobotBusiness(IFreeSql fsql, |
|
|
|
|
|
NLogManager logManager, |
|
|
|
|
|
IIdGenerator idGenerator, |
|
|
|
|
|
IMemoryCache memoryCache, |
|
|
|
|
|
IEnumerable<ITradeBusiness> tradeBusinessList, |
|
|
|
|
|
TaskSchedulerManager taskSchedulerManager, |
|
|
|
|
|
ExchangeBusiness exchangeBusiness, |
|
|
|
|
|
IServiceProvider serviceProvider) : base(fsql, logManager, idGenerator, memoryCache) |
|
|
{ |
|
|
{ |
|
|
this.globalContextLazy = new Lazy<GlobalContext>(() => serviceProvider.GetService<GlobalContext>()); |
|
|
this.globalContextLazy = new Lazy<GlobalContext>(() => serviceProvider.GetService<GlobalContext>()); |
|
|
|
|
|
this.tradeBusinessList = tradeBusinessList; |
|
|
|
|
|
this.taskSchedulerManager = taskSchedulerManager; |
|
|
|
|
|
this.exchangeBusiness = exchangeBusiness; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
@ -82,6 +99,14 @@ namespace Binance.TradeRobot.Business |
|
|
globalContext.UnSubscribeOrderPublish(robot); |
|
|
globalContext.UnSubscribeOrderPublish(robot); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 刷新机器人运行时长
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void RefreshRobotRuningTime() |
|
|
|
|
|
{ |
|
|
|
|
|
fsql.Update<Robot>().Set(r => r.RunningTime + 60).Where(r => r.State == Enums.RobotState.Runing).ExecuteAffrows(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// 添加机器人和账户
|
|
|
/// 添加机器人和账户
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
@ -286,5 +311,55 @@ namespace Binance.TradeRobot.Business |
|
|
} |
|
|
} |
|
|
return robotList; |
|
|
return robotList; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void D21Remedy() |
|
|
|
|
|
{ |
|
|
|
|
|
var d21RobotList = GetD21PolicyRobotList(robotState: Enums.RobotState.Runing, isLoadRecentTradeProfit: false, isLoadAPIKey: true); |
|
|
|
|
|
if (d21RobotList == null || d21RobotList.Count() == 0) |
|
|
|
|
|
throw new BusinessException("未找到符合条件的机器人"); |
|
|
|
|
|
|
|
|
|
|
|
foreach (var d21Robot in d21RobotList) |
|
|
|
|
|
{ |
|
|
|
|
|
var runingInfo = RedisHelper.Get<D21RuningInfo>(d21Robot.Id.ToString()) ?? new D21RuningInfo() { RobotId = d21Robot.Id }; |
|
|
|
|
|
if (runingInfo.ErrorCrossSingal == null || runingInfo.ErrorCrossSingalTime == 0) |
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
var previouKID = DateTime.Now.GetKID(d21Robot.D21Policy.PeriodicSignal, true); |
|
|
|
|
|
var currentKID = DateTime.Now.GetKID(d21Robot.D21Policy.PeriodicSignal, false); |
|
|
|
|
|
var cycle = currentKID - previouKID; //单位周期的时间戳差距
|
|
|
|
|
|
|
|
|
|
|
|
if ((previouKID - runingInfo.ErrorCrossSingalTime) / cycle > 3) |
|
|
|
|
|
{ |
|
|
|
|
|
var errorCrossSingal = runingInfo.ErrorCrossSingal.Value; |
|
|
|
|
|
runingInfo.ErrorCrossSingal = null; |
|
|
|
|
|
runingInfo.ErrorCrossSingalTime = 0; |
|
|
|
|
|
RedisHelper.Set(d21Robot.Id.ToString(), runingInfo); |
|
|
|
|
|
|
|
|
|
|
|
var symbolInfo = exchangeBusiness.GetSymbol(d21Robot.ExchangeId, d21Robot.Symbol); |
|
|
|
|
|
var d21TradeBusiness = tradeBusinessList.FirstOrDefault(t => t.TradePolicy == Enums.TradePolicy.D21); |
|
|
|
|
|
|
|
|
|
|
|
if (errorCrossSingal == Enums.SingalType.多交叉) |
|
|
|
|
|
{ |
|
|
|
|
|
Task.Factory.StartNew(() => d21TradeBusiness.LongCross(new D21SingalRequest() |
|
|
|
|
|
{ |
|
|
|
|
|
RobotId = d21Robot.Id, |
|
|
|
|
|
KLinePeriodic = d21Robot.D21Policy.PeriodicSignal, |
|
|
|
|
|
SingalType = errorCrossSingal, |
|
|
|
|
|
Symbol = d21Robot.Symbol |
|
|
|
|
|
}, d21Robot, true, symbolInfo), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SingalTaskScheduler); |
|
|
|
|
|
} |
|
|
|
|
|
else if (errorCrossSingal == Enums.SingalType.空交叉) |
|
|
|
|
|
{ |
|
|
|
|
|
Task.Factory.StartNew(() => d21TradeBusiness.ShortCross(new D21SingalRequest() |
|
|
|
|
|
{ |
|
|
|
|
|
RobotId = d21Robot.Id, |
|
|
|
|
|
KLinePeriodic = d21Robot.D21Policy.PeriodicSignal, |
|
|
|
|
|
SingalType = errorCrossSingal, |
|
|
|
|
|
Symbol = d21Robot.Symbol |
|
|
|
|
|
}, d21Robot, true, symbolInfo), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SingalTaskScheduler); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|