private void LogChanges(WpfOcDispatcher wpfOcDispatcher, OcDispatcher logOcDispatcher, OcDispatcher logPropertyChangedOcDispatcher) { const string messageTemplate = "{0} {1} {2} ({4}). Status = {3}"; void log(Trade trade) { _logger.Info( string.Format(messageTemplate, trade.BuyOrSell, trade.Amount, trade.CurrencyPair, trade.Status, trade.Customer)); } All.CollectionDispatching(logOcDispatcher, wpfOcDispatcher) .CollectionItemProcessing( (newTrade, processing) => { if (!processing.ActivationInProgress) { log(newTrade); } }).For(_consumer); }
public RecentTradesViewer(ITradeService tradeService, OcDispatcher backgroundOcDispatcher, WpfOcDispatcher wpfOcDispatcher) { DateTime initialDateTime = DateTime.Now; Data = tradeService.All .Filtering(t => !t.Expired && t.Timestamp > initialDateTime) .Ordering(t => t.Timestamp, ListSortDirection.Descending) .Selecting(t => new TradeProxy(t)) .CollectionDisposing() .CollectionDispatching(wpfOcDispatcher, backgroundOcDispatcher, 0, 1) .For(_consumer); }
public LiveTradesViewer(ITradeService tradeService, SearchHints searchHints, OcDispatcher backgroundOcDispatcher, WpfOcDispatcher wpfOcDispatcher) { SearchHints = searchHints; Data = tradeService.Live .CollectionPausing(new Computing <bool>(() => Paused).ScalarDispatching(backgroundOcDispatcher, wpfOcDispatcher)) .Filtering(t => t.CurrencyPair.Contains(SearchHints.SearchTextThrottled.Value, StringComparison.OrdinalIgnoreCase) || t.Customer.Contains(SearchHints.SearchTextThrottled.Value, StringComparison.OrdinalIgnoreCase)) .Ordering(t => t.Timestamp, ListSortDirection.Descending) .Selecting(t => new TradeProxy(t)) .CollectionDisposing() .CollectionDispatching(wpfOcDispatcher, backgroundOcDispatcher, 0, 1) .For(_consumer); }
public PagedDataViewer(ITradeService tradeService, SearchHints searchHints, OcDispatcher backgroundOcDispatcher, WpfOcDispatcher wpfOcDispatcher) { SearchHints = searchHints; SortParameters = new SortParameterData( tradeService.Live .Selecting(t => new TradeProxy(t)) .CollectionDisposing(), _consumer); AllData = new Computing <ObservableCollection <TradeProxy> >( () => SortParameters.SelectedItem.SortedData) .Filtering(t => t.Trade.CurrencyPair.Contains(SearchHints.SearchTextThrottled.Value, StringComparison.OrdinalIgnoreCase) || t.Trade.Customer.Contains(SearchHints.SearchTextThrottled.Value, StringComparison.OrdinalIgnoreCase)) .CollectionDispatching(wpfOcDispatcher, backgroundOcDispatcher, 0, 1); Data = AllData.Paging(25, 1).For(_consumer); _nextPageCommand = new Command(() => Data.CurrentPage = Data.CurrentPage + 1, () => Data.CurrentPage < Data.PageCount); _previousPageCommand = new Command(() => Data.CurrentPage = Data.CurrentPage - 1, () => Data.CurrentPage > 1); }
public TradesByPercentDiff([NotNull] Group <Trade, int> group, OcConsumer consumer, OcDispatcher backgroundOcDispatcher, WpfOcDispatcher wpfOcDispatcher) { _group = group ?? throw new ArgumentNullException(nameof(group)); PercentBand = group.Key; Data = group .Ordering(t => t.Timestamp, ListSortDirection.Descending) .Selecting(trade => new TradeProxy(trade)) .CollectionDisposing() .CollectionDispatching(wpfOcDispatcher, backgroundOcDispatcher, 0, 1) .For(consumer); }
public NearToMarketViewer(INearToMarketService nearToMarketService, OcDispatcher backgroundOcDispatcher, WpfOcDispatcher wpfOcDispatcher) { Data = nearToMarketService.Query(() => (decimal)NearToMarketPercent) .Ordering(t => t.Timestamp, ListSortDirection.Descending) .Selecting(t => new TradeProxy(t)) .CollectionDisposing() .CollectionDispatching(wpfOcDispatcher, backgroundOcDispatcher, 0, 1) .For(_consumer); }
public SearchHints(ITradeService tradeService, UserInputThrottlingOcDispatcher throttling, OcDispatcher backgroundOcDispatcher, WpfOcDispatcher wpfOcDispatcher) { _searchTextThrottled = new Computing <string>(() => SearchText) .ScalarDispatching(throttling) .SetDefaultValue("") .For(_consumer); _searchTextThrottled.PreValueChanged += (sender, args) => wpfOcDispatcher.IsPaused = true; _searchTextThrottled.PostValueChanged += (sender, args) => { wpfOcDispatcher.IsPaused = false; wpfOcDispatcher.Invoke(CommandManager.InvalidateRequerySuggested); }; _hints = tradeService.Live.Selecting(t => t.CurrencyPair).Distincting() .Concatenating( tradeService.Live.Selecting(t => t.Customer).Distincting()) .Filtering(str => str.Contains(_searchTextThrottled.Value, StringComparison.OrdinalIgnoreCase) || str.Contains(_searchTextThrottled.Value, StringComparison.OrdinalIgnoreCase)) .Ordering(s => s) .CollectionDispatching(wpfOcDispatcher, backgroundOcDispatcher) .For(_consumer); }
public TradesByTimeViewer(ITradeService tradeService, OcDispatcher backgroundOcDispatcher, WpfOcDispatcher wpfOcDispatcher) { Data = tradeService.All .Grouping(trade => trade.Age) .Selecting(group => new TradesByTime(group, _consumer, backgroundOcDispatcher, wpfOcDispatcher)) .Ordering(t => t.Period) .CollectionDispatching(wpfOcDispatcher, backgroundOcDispatcher, 0, 1) .For(_consumer); }
public TradeService(ILogger logger, TradeGenerator tradeGenerator, WpfOcDispatcher wpfOcDispatcher, Dispatcher dispatcher) { _logger = logger; _tradeGenerator = tradeGenerator; _dispatcher = dispatcher; 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) { _dispatcher.Invoke(() => All.Add(trade), DispatcherPriority.Background); } }, 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++) { _dispatcher.Invoke(() => { Trade trade = All[random.Next(0, All.Count - 1)]; trade.Status = TradeStatus.Closed; trade.CloseTimestamp = DateTime.Now; closedTrades.Add(trade); }, DispatcherPriority.Background); } }, RandomInterval); //expire closed items from the cache to avoid unbounded data RecurringAction tradeRemover = new RecurringAction(() => { _dispatcher.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); } } }, DispatcherPriority.Background); }, () => TimeSpan.FromMinutes(1)); //log changes OcDispatcher logOcDispatcher = new OcDispatcher(); OcDispatcher logPropertyChangedOcDispatcher = new OcDispatcher(); LogChanges(wpfOcDispatcher, logOcDispatcher, logPropertyChangedOcDispatcher); _cleanup = new CompositeDisposable( _consumer, tradeEmitter, tradeCloser, logOcDispatcher, logPropertyChangedOcDispatcher, tradeRemover); }
public TradesByPercentViewer(INearToMarketService nearToMarketService, OcDispatcher backgroundOcDispatcher, WpfOcDispatcher wpfOcDispatcher) { Data = nearToMarketService.Query(() => 4) .Grouping(trade => (int)Math.Truncate(Math.Abs(trade.PercentFromMarket.Value))) .Selecting(group => new Domain.Model.TradesByPercentDiff(group, _consumer, backgroundOcDispatcher, wpfOcDispatcher)) .Ordering(tbpd => tbpd.PercentBand) .CollectionDispatching(wpfOcDispatcher, backgroundOcDispatcher, 0, 1) .For(_consumer); }
public PositionsViewer(ITradeService tradeService, OcDispatcher backgroundOcDispatcher, WpfOcDispatcher wpfOcDispatcher) { Data = tradeService.Live .Grouping(trade => trade.CurrencyPair) .Selecting(group => new CurrencyPairPosition(group, _consumer)) .Ordering(p => p.CurrencyPair) .CollectionDispatching(wpfOcDispatcher, backgroundOcDispatcher, 0, 1) .For(_consumer); }