public void Initiatize() { _dbContext = new CryptoBotDbContext(); _logger = LogManager.GetCurrentClassLogger(); _user = _dbContext .Users .Include(x => x.ApiSettings.Select(y => y.Exchange)) .Include(x => x.MessagingApps) .Include(x => x.MessagingApps.Select(y => y.MessagingAppSettings)) .Single(x => x.UserId == 1); // get the messaging app if any if (_user.MessagingApps.Any(x => x.Active)) { var app = _user.MessagingApps.First(x => x.Active); _messagingApp = MessagingAppFactory.GetMessagingApp(app, _logger, _dbContext); } }
public async Task BackTestAllBots() { // get user User user = _dbContext .Users .Include(x => x.ApiSettings.Select(y => y.Exchange)) .Include(x => x.MessagingApps) .Include(x => x.MessagingApps.Select(y => y.MessagingAppSettings)) .Single(x => x.UserId == 1); // get watches, get coins, get exchange List <Bot> bots = _dbContext .Bots .Include("User") .Include("User.ApiSettings") .Include("User.ApiSettings.Exchange") .Include("User.MessagingApps") .Include("User.MessagingApps.MessagingAppSettings") .Include("Exchange") .Include("Coin") .Include("BaseCoin") .Include("Positions") .Include("Indicators") .Include("Indicators.RuleSets") .Include("Indicators.RuleSets.Rules") .AsNoTracking() .Where(x => x.User.UserId == user.UserId) .Where(x => x.Active) .ToList(); // get the messaging app if any if (user.MessagingApps.Any(x => x.Active)) { var app = user.MessagingApps.First(x => x.Active); _messagingApp = MessagingAppFactory.GetMessagingApp(app, _logger, _dbContext); } int oneMinute = 60; int fifteenMinute = oneMinute * 15; int thirtyMinute = oneMinute * 30; int sixtyMinute = oneMinute * 60; foreach (Bot bot in bots) { IExchangeApi exchangeApi = ExchangeEngine.ExchangeFactory.GetExchangeApi( (Enumerations.ExchangesEnum)bot.Exchange.ExchangeId, _mapper.Map <ApiSetting, ExchangeSettings>( user.ApiSettings.Single(x => x.Exchange.ExchangeId == bot.Exchange.ExchangeId), new ExchangeSettings())); /* * Note from GDAX... * * The maximum number of data points for a single request is 200 candles. * If your selection of start/end time and granularity will result in more than 200 data points, your request will be rejected. * If you wish to retrieve fine granularity data over a larger time range, you will need to make multiple requests with new start/end ranges. * */ int requiredWeeks = 1; List <Candle> candles = new List <Candle>(); var requiredHours = 36; for (int k = requiredHours; k > 0; k--) { var fromDate = DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(60 * k)); fromDate = new DateTime(fromDate.Year, fromDate.Month, fromDate.Day, fromDate.Hour, 0, 0); // the start of the hour var toDate = fromDate.AddHours(1); toDate = new DateTime(toDate.Year, toDate.Month, toDate.Day, toDate.Hour, 0, 0); int candleSize = 60 * 5; // 60 second x ? try { candles.AddRange(exchangeApi.GetCandles(bot.BaseCoin, bot.Coin, candleSize, fromDate, toDate)); } catch (Exception e) { _logger.Error(e); } if (k % 2 == 0) // only three requests allowed per second on GDAX { Thread.Sleep(1000); } } candles = candles.OrderBy(x => x.Timestamp).ToList(); TradeBot tradeBot = new TradeBot(bot, _logger, _dbContext, _mapper, _IndicatorFactoryWrapper, _messagingApp); _messageDispatcher.AddMessageHandler(tradeBot); foreach (Candle candle in candles) { _messageDispatcher.Dispatch(new CandleMessage { Candles = new List <Candle>() { candle }, BaseCoin = bot.BaseCoin, Coin = bot.Coin }); } // close last order in case its open if (bot.CurrentPosition?.Status == Enumerations.PositionStatusEnum.Bought) { Position position = _dbContext.Positions.Single(x => x.PositionId == bot.CurrentPosition.PositionId); position.Status = Enumerations.PositionStatusEnum.Sold; _dbContext.SaveChanges(); } tradeBot.OnStop(); tradeBot = null; } }
private static async void Start(string[] args) { // onstart code here _dbContext = new CryptoBotDbContext(); _logger = LogManager.GetCurrentClassLogger(); _messageDispatcher = new MessageDispatcher(); _indicatorFactoryWrapper = new IndicatorFactoryWrapper(); SetupMapping(); // get user User user = _dbContext .Users .Include(x => x.ApiSettings.Select(y => y.Exchange)) .Include(x => x.MessagingApps) .Include(x => x.MessagingApps.Select(y => y.MessagingAppSettings)) .Single(x => x.UserId == 1); // get watches, get coins, get exchange List <Bot> bots = _dbContext .Bots .Include("User") .Include("User.ApiSettings") .Include("User.ApiSettings.Exchange") .Include("User.MessagingApps") .Include("User.MessagingApps.MessagingAppSettings") .Include("Exchange") .Include("Coin") .Include("BaseCoin") .Include("Positions") .Include("Indicators") .Include("Indicators.RuleSets") .Include("Indicators.RuleSets.Rules") .AsNoTracking() .Where(x => x.User.UserId == user.UserId) .Where(x => x.Active) .ToList(); var activeBots = bots.Where(x => x.Active).ToList(); // get the messaging app if any if (user.MessagingApps.Any(x => x.Active)) { var app = user.MessagingApps.First(x => x.Active); _messagingApp = MessagingAppFactory.GetMessagingApp(app, _logger, _dbContext); _messagingApp.SendMessage("CryptoBot starting.."); } foreach (var bot in activeBots) { var tradeBot = new TradeBot(bot, _logger, _dbContext, _mapper, _indicatorFactoryWrapper, _messagingApp); var exchangeApi = ExchangeEngine.ExchangeFactory.GetExchangeApi( (Enumerations.ExchangesEnum)bot.Exchange.ExchangeId, _mapper.Map <ApiSetting, ExchangeSettings>( user.ApiSettings.Single(x => x.Exchange.ExchangeId == bot.Exchange.ExchangeId), new ExchangeSettings())); var candles = new List <Candle>(); var requiredHours = 48; for (int k = requiredHours; k > 0; k--) { var fromDate = DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(60 * k)); fromDate = new DateTime(fromDate.Year, fromDate.Month, fromDate.Day, fromDate.Hour, 0, 0); // the start of the hour var toDate = fromDate.AddHours(1); toDate = new DateTime(toDate.Year, toDate.Month, toDate.Day, toDate.Hour, 0, 0); int candleSize = 60 * 5; // 60 second x ? try { candles.AddRange(exchangeApi.GetCandles(bot.BaseCoin, bot.Coin, candleSize, fromDate, toDate)); } catch (Exception e) { _logger.Error(e); } if (k % 2 == 0) // only three requests allowed per second on GDAX { Thread.Sleep(1000); } } candles = candles.OrderBy(x => x.Timestamp).ToList(); // ***** VERY IMPORTANT ***** // When candles are preloaded into the bot they do not go through any indicator rules. // When the bot starts, it could be starting 10 mins after the hour and it could go asleep unless we tell it to check the last candle. // // If we do not run the last candle through the indicators then no indicator logic will run until the next hour and we could be missing a move. // When we preload, we will not add the last two candles. When the scheduler starts, it asks for the last two candles. // So, we will allow it to pass these into the bot which will mean it will pass them through the indicators and take any action it might need to. tradeBot.PreLoadCandles(candles.Take(candles.Count() - 1).ToList()); _messageDispatcher.AddMessageHandler(tradeBot); tradeBot.Start(); _messagingApp.SendMessage($"{bot.Name} started"); } AddSchedulerForEachActiveBotExchange(activeBots, user); Console.ReadLine(); }