private async Task Loop() { _state = _stateStorage.LastState(); _followers = _state .Stocks .Select(it => new StockFollower(it.CandleData, _contextProvider, _state.Orders.Add, it.Status)) .ToList(); while (true) { Console.WriteLine($"LOOP START {_timeProvider.Now}"); var lastLoopDate = _state.Time.Date; _state.Time = _timeProvider.Now; if (lastLoopDate < _timeProvider.Today) { _state.DayChanges++; var savedFollowers = _followers .Where(it => it.Status is WaitingForSell) .ToList(); var stocks = await _stocksProvider.GetStocks(_cancellationTokenSource.Token); _followers = stocks .Select(it => new StockFollower(it, _contextProvider, _state.Orders.Add)) .ToList(); _followers.AddRange(savedFollowers); _state.Stocks = _followers.Select(it => new FollowingStock(it.Stock, it.Status)).ToList(); } if (_followers.Count == 0 && _state.Time.Date == _timeProvider.Today) { var tomorrow = _timeProvider.Today.Add(TimeSpan.FromDays(1)); var waiting = tomorrow - _timeProvider.Now + TimeSpan.FromMinutes(5); Console.WriteLine($"GO SLEEPING FOR {waiting}"); await Task.Delay(waiting, _cancellationTokenSource.Token); Console.WriteLine("WAKE UP"); } foreach (var follower in _followers) { await follower.Perform(_timeProvider.Now, _cancellationTokenSource.Token); } _state.Stocks = _followers.Select(it => new FollowingStock(it.Stock, it.Status)).ToList(); _stateStorage.AddState(_state); _timeProvider.SaveTime(); await _contextProvider.Do(it => _state.Dump(it, _cancellationTokenSource.Token)); _followers.RemoveAll(it => it.Status is Closed); } }