Ejemplo n.º 1
0
        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;
            }
        }
Ejemplo n.º 2
0
        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();
        }