private IDisposable GenerateTradesAndMaintainCache()
        {
            //bit of code to generate trades
            var random = new Random();

            //initally load some trades
            _tradesSource.AddOrUpdate(_tradeGenerator.Generate(10000, true));

            Func <TimeSpan> randomInterval = () => {
                var ms = random.Next(150, 5000);
                return(TimeSpan.FromMilliseconds(ms));
            };

            // create a random number of trades at a random interval
            var tradeGenerator = _schedulerProvider.TaskPool
                                 .ScheduleRecurringAction(randomInterval, () =>
            {
                var number = random.Next(1, 7);
                _logger.Info("Adding {0} trades", number);
                var trades = _tradeGenerator.Generate(number);
                _tradesSource.AddOrUpdate(trades);
            });

            // close a random number of trades at a random interval
            var tradeCloser = _schedulerProvider.TaskPool
                              .ScheduleRecurringAction(randomInterval, () =>
            {
                var number = random.Next(1, 8);
                _logger.Info("Closing {0} trades", number);
                _tradesSource.BatchUpdate(updater =>
                {
                    var trades = updater.Items
                                 .Where(trade => trade.Status == TradeStatus.Live)
                                 .OrderBy(t => Guid.NewGuid()).Take(number).ToArray();

                    var toClose = trades
                                  .Select(trade => new Trade(trade, TradeStatus.Closed));

                    _tradesSource.AddOrUpdate(toClose);
                });
            });

            return(new CompositeDisposable(tradeGenerator, tradeCloser));
        }
Exemple #2
0
        private IObservable <IChangeSet <Trade, long> > GenerateTradesAndMaintainCache()
        {
            //construct an cache datasource specifying that the primary key is Trade.Id
            return(ObservableChangeSet.Create <Trade, long>(cache =>
            {
                /*
                 *  The following code emulates an external trade provider.
                 *  Alternatively you can use "new SourceCacheTrade, long>(t=>t.Id)" and manually maintain the cache.
                 *
                 *  For examples of creating a observable change sets, see https://github.com/RolandPheasant/DynamicData.Snippets
                 */

                //bit of code to generate trades
                var random = new Random();

                //initally load some trades
                cache.AddOrUpdate(_tradeGenerator.Generate(5_000, true));

                TimeSpan RandomInterval() => TimeSpan.FromMilliseconds(random.Next(2500, 5000));


                // create a random number of trades at a random interval
                var tradeGenerator = _schedulerProvider.Background
                                     .ScheduleRecurringAction(RandomInterval, () =>
                {
                    var number = random.Next(1, 5);
                    var trades = _tradeGenerator.Generate(number);
                    cache.AddOrUpdate(trades);
                });

                // close a random number of trades at a random interval
                var tradeCloser = _schedulerProvider.Background
                                  .ScheduleRecurringAction(RandomInterval, () =>
                {
                    var number = random.Next(1, 2);
                    cache.Edit(innerCache =>
                    {
                        var trades = innerCache.Items
                                     .Where(trade => trade.Status == TradeStatus.Live)
                                     .OrderBy(t => Guid.NewGuid()).Take(number).ToArray();

                        var toClose = trades.Select(trade => new Trade(trade, TradeStatus.Closed));

                        cache.AddOrUpdate(toClose);
                    });
                });

                //expire closed items from the cache to avoid unbounded data
                var expirer = cache
                              .ExpireAfter(t => t.Status == TradeStatus.Closed ? TimeSpan.FromMinutes(1) : (TimeSpan?)null, TimeSpan.FromMinutes(1), _schedulerProvider.Background)
                              .Subscribe(x => _logger.Info("{0} filled trades have been removed from memory", x.Count()));

                return new CompositeDisposable(tradeGenerator, tradeCloser, expirer);
            }, trade => trade.Id));
        }
Exemple #3
0
        private IDisposable GenerateTradesAndMaintainCache()
        {
            //bit of code to generate trades
            var random = new Random();

            //initally load some trades
            _tradesSource.AddOrUpdate(_tradeGenerator.Generate(5000, true));

            TimeSpan RandomInterval() => TimeSpan.FromMilliseconds(random.Next(1000, 2500));


            // create a random number of trades at a random interval
            var tradeGenerator = _schedulerProvider.Background
                                 .ScheduleRecurringAction(RandomInterval, () =>
            {
                var number = random.Next(1, 5);
                var trades = _tradeGenerator.Generate(number);
                _tradesSource.AddOrUpdate(trades);
            });

            // close a random number of trades at a random interval
            var tradeCloser = _schedulerProvider.Background
                              .ScheduleRecurringAction(RandomInterval, () =>
            {
                var number = random.Next(1, 2);
                _tradesSource.Edit(updater =>
                {
                    var trades = updater.Items
                                 .Where(trade => trade.Status == TradeStatus.Live)
                                 .OrderBy(t => Guid.NewGuid()).Take(number).ToArray();

                    var toClose = trades.Select(trade => new Trade(trade, TradeStatus.Closed));

                    _tradesSource.AddOrUpdate(toClose);
                });
            });

            return(new CompositeDisposable(tradeGenerator, tradeCloser));
        }
        public TradeService(ILogger logger, TradeGenerator tradeGenerator, OcDispatcher backgroundOcDispatcher)
        {
            _logger                 = logger;
            _tradeGenerator         = tradeGenerator;
            _backgroundOcDispatcher = backgroundOcDispatcher;

            All  = new ObservableCollection <Trade>(_tradeGenerator.Generate(5_000, true));
            Live = All.Filtering(t => t.Status == TradeStatus.Live).For(_consumer);

            var random = new Random();

            TimeSpan RandomInterval() => TimeSpan.FromMilliseconds(random.Next(2500, 5000));

            // create a random number of trades at a random interval
            RecurringAction tradeEmitter = new RecurringAction(() =>
            {
                var number = random.Next(1, 5);
                var trades = _tradeGenerator.Generate(number);

                foreach (Trade trade in trades)
                {
                    _backgroundOcDispatcher.Invoke(() => All.Add(trade));
                }
            }, RandomInterval);

            List <Trade> closedTrades = new List <Trade>();
            //close a random number of trades at a random interval
            RecurringAction tradeCloser = new RecurringAction(() =>
            {
                var number = random.Next(1, 2);
                for (int i = 1; i <= number; i++)
                {
                    _backgroundOcDispatcher.Invoke(() =>
                    {
                        Trade trade          = All[random.Next(0, All.Count - 1)];
                        trade.Status         = TradeStatus.Closed;
                        trade.CloseTimestamp = DateTime.Now;
                        closedTrades.Add(trade);
                    });
                }
            }, RandomInterval);


            //expire closed items from the cache to avoid unbounded data
            RecurringAction tradeRemover = new RecurringAction(() =>
            {
                _backgroundOcDispatcher.Invoke(() =>
                {
                    for (var index = closedTrades.Count - 1; index >= 0; index--)
                    {
                        Trade closedTrade = closedTrades[index];
                        if ((DateTime.Now - closedTrade.CloseTimestamp).Minutes >= 1)
                        {
                            All.Remove(closedTrade);
                            closedTrades.RemoveAt(index);
                        }
                    }
                });
            }, () => TimeSpan.FromMinutes(1));



            //log changes
            OcDispatcher logPropertyChangedOcDispatcher = new OcDispatcher();

            LogChanges(logPropertyChangedOcDispatcher);

            _cleanup = new CompositeDisposable(
                _consumer, tradeEmitter, tradeCloser, logPropertyChangedOcDispatcher, tradeRemover);
        }