/// <summary> /// Initializes a new instance of the <see cref="PlaylistViewModel" /> class. /// </summary> /// <param name="playlist">The playlist info.</param> /// <param name="renameRequest"> /// A function that requests the rename of the playlist. Return true, if the rename is /// granted, otherwise false. /// </param> public PlaylistViewModel(Playlist playlist, Func<string, bool> renameRequest) { this.playlist = playlist; this.renameRequest = renameRequest; this.disposable = new CompositeDisposable(); this.entries = playlist .CreateDerivedCollection(entry => new PlaylistEntryViewModel(entry)) .DisposeWith(this.disposable); this.entries.ItemsRemoved.Subscribe(x => x.Dispose()); this.playlist.WhenAnyValue(x => x.CurrentSongIndex).ToUnit() .Merge(this.entries.Changed.ToUnit()) .Subscribe(_ => this.UpdateCurrentSong()) .DisposeWith(this.disposable); IObservable<List<PlaylistEntryViewModel>> remainingSongs = this.entries.Changed .Select(x => Unit.Default) .Merge(this.playlist.WhenAnyValue(x => x.CurrentSongIndex).ToUnit()) .Select(x => this.entries.Reverse().TakeWhile(entry => !entry.IsPlaying).ToList()); this.songsRemaining = remainingSongs .Select(x => x.Count) .ToProperty(this, x => x.SongsRemaining) .DisposeWith(this.disposable); this.timeRemaining = remainingSongs .Select(x => x.Any() ? x.Select(entry => entry.Duration).Aggregate((t1, t2) => t1 + t2) : (TimeSpan?)null) .ToProperty(this, x => x.TimeRemaining) .DisposeWith(this.disposable); this.CurrentPlayingEntry = this.Model.WhenAnyValue(x => x.CurrentSongIndex).Select(x => x == null ? null : this.entries[x.Value]); }
public OrganizationMenuViewModel(HDPApp _app) { Title = "Parti"; Action<OrganizationMenuItemViewModel> gotoCommand = null; gotoCommand = new Action<OrganizationMenuItemViewModel> (x => { if (x.Model.MenuType == MenuType.View) { var page = x.Model.Page; var vm = new OrganizationPageViewModel(); vm.Title = page.Title; vm.Document = page.Document; NavigateTo(vm); } else if (x.Model.MenuType == MenuType.SubMenu) { var subMenuItemVM = new OrganizationSubMenuItemViewModel(x.Model, gotoCommand); subMenuItemVM.Title = x.Title; NavigateTo(subMenuItemVM); } }); OrganizationItems = _app.State.OrganizationMenuItems.CreateDerivedCollection ( x => new OrganizationMenuItemViewModel (x, gotoCommand)); }
public OrganizationMenuItemViewModel(OrganizationMenuItem model, Action<OrganizationMenuItemViewModel> gotoCommand) { Model = model; ImageName = model.ImageName; Name = model.Name; Title = model.Name; SubMenuItems = model.SubMenuItems.CreateDerivedCollection (x => new OrganizationSubMenuItemViewModel(x, gotoCommand)); GoToCommand = ReactiveCommand.Create (); GoToCommand.Subscribe (x => gotoCommand (this)); }
public ChannelViewModel(string token, string teamId, IScreen screen = null) { HostScreen = screen ?? Locator.Current.GetService<IScreen>(); Messages = new ReactiveList<Message>(); var client = new HttpClient(NetCache.UserInitiated) { BaseAddress = new Uri("https://slack.com"), }; var api = RestService.For<ISlackApi>(client); LoadChannelToDisplay = ReactiveCommand.CreateAsyncTask(async _ => { var channelList = await BlobCache.LocalMachine.GetOrFetchObject("channels_" + teamId, () => api.GetChannels(token), RxApp.MainThreadScheduler.Now + TimeSpan.FromMinutes(5.0)); // Try to find ReactiveUI, then general, then whatever the first one is var channel = channelList.channels.FirstOrDefault(x => x.name.ToLowerInvariant() == "reactiveui") ?? channelList.channels.FirstOrDefault(x => x.name.ToLowerInvariant() == "general") ?? channelList.channels.First(); return channel.id; }); LoadChannelToDisplay.Subscribe(x => VisibleChannel = x); LoadMessages = ReactiveCommand.CreateAsyncTask(async _ => { var channelToLoad = VisibleChannel; if (channelToLoad == null) { channelToLoad = await LoadChannelToDisplay.ExecuteAsync(); } return await api.GetLatestMessages(token, channelToLoad); }); LoadMessages.Subscribe(xs => { Messages.Clear(); Messages.AddRange(xs.messages); }); LoadMessages.ThrownExceptions.Subscribe(ex => UserError.Throw("Couldn't load messages for room", ex)); MessageTiles = Messages.CreateDerivedCollection( x => new MessageTileViewModel(x), x => !String.IsNullOrWhiteSpace(x.text), (x, y) => x.Model.date.CompareTo(y.Model.date)); }
public CoinListViewModel(IReactiveDerivedList <CoinViewModel> coins) { Coins = coins; this.WhenAnyValue(x => x.SelectedCoin).Subscribe(async coin => { if (coin != null) { await Application.Current.Clipboard.SetTextAsync(coin.TransactionId); ClipboardNotificationVisible = true; ClipboardNotificationOpacity = 1; Dispatcher.UIThread.Post(async() => { await Task.Delay(1000); ClipboardNotificationOpacity = 0; }); } }); }
/// <summary> /// Constructor method. /// </summary> public TransparencyManagerPanelViewModel(IAppState appState = null) { _appState = appState ?? Locator.CurrentMutable.GetService <IAppState>(); _processInstances = _appState.GetProcessInstances().CreateDerivedCollection( selector: instance => instance ); _processInstances.ItemsAdded.Subscribe(instance => { SetTransparency(instance); }); this.WhenAnyValue(@this => @this.TransparencyLevel).Subscribe(alphaLevel => { foreach (var instance in _processInstances) { SetTransparency(instance); } }); }
public GamesViewModel(IDependencyResolver resolver) { var menuManager = resolver.GetService <IPinballXManager>(); var gameManager = resolver.GetService <IGameManager>(); // create platforms, filtered and sorted Systems = menuManager.Systems.CreateDerivedCollection( system => new SystemItemViewModel(this, system), system => system.Enabled, (x, y) => string.Compare(x.System.Name, y.System.Name, StringComparison.OrdinalIgnoreCase) ); // this is the list we only create once _allGameViewModels = gameManager.AggregatedGames.CreateDerivedCollection( game => new GameItemViewModel(game, resolver) { IsVisible = IsGameVisible(game) } ); // this is the list that gets filtered Games = _allGameViewModels.CreateDerivedCollection( gameViewModel => gameViewModel, gameViewModel => gameViewModel.IsVisible, (x, y) => string.Compare(Path.GetFileName(x.Game.FileId), Path.GetFileName(y.Game.FileId), StringComparison.OrdinalIgnoreCase) ); _allGameViewModels.ChangeTrackingEnabled = true; // update platform filter when platforms change Systems.Changed .Select(_ => Unit.Default) .StartWith(Unit.Default) .Subscribe(x => UpdateSystems()); menuManager.GamesUpdated.Subscribe(x => RefreshGameVisibility()); this.WhenAnyValue(vm => vm.ShowDisabled, vm => vm.ShowHidden).Subscribe(x => RefreshGameVisibility()); this.WhenAnyValue(vm => vm.StatusFilter).Subscribe(x => RefreshGameVisibility()); }
/// <summary> /// Constructor method. /// </summary> public ProcessesManagerViewModel(IProcessRepository processesRepository = null, IValidator <IProcessViewModel> processViewModelaValidator = null) { _processesRepository = processesRepository ?? Locator.CurrentMutable.GetService <IProcessRepository>(); _formDataValidator = processViewModelaValidator ?? Locator.CurrentMutable.GetService <IValidator <IProcessViewModel> >(); // Lists _processesSource = new ReactiveList <ProcessEntity>() { ChangeTrackingEnabled = true }; _processesList = _processesSource.CreateDerivedCollection( selector: entity => Mapper.Map <IProcessViewModel>(entity), filter: entity => FilterEntity(entity), signalReset: this.ObservableForProperty(@this => @this.FilterText).Throttle(TimeSpan.FromMilliseconds(175), RxApp.MainThreadScheduler) ); // Add _addProcessCommand = ReactiveCommand.Create(() => AddProcessCommandAction()); // Edit this.WhenAnyValue(viewModel => viewModel.SelectedProcess) .Where(option => option != null) .Subscribe(process => EditProcessCommandAction(process)); // Save _saveProcessCommand = ReactiveCommand.Create(() => SaveProcessAction()); // Cancel _cancelFormCommand = ReactiveCommand.Create(() => CancelFormCommandAction()); // Delete _deleteProcessCommand = ReactiveCommand.Create(() => DeleteProcessCommandAction()); // Load Processess _loadProcessesCommand = ReactiveCommand.CreateFromTask(async() => await LoadProcessesCommandAction()); _loadProcessesCommand.IsExecuting.BindTo(this, @this => @this.IsLoadingProcesses); _loadProcessesCommand.Subscribe(entities => LoadProcessesCommandHandler(entities)); }
/// <summary> /// Constructor method. /// </summary> public ConsolesPanelViewModel( IAppState appState = null, IProcessFactory processFactory = null, IProcessesTracker processesTracker = null, IProcessRepository processesRepository = null, IProcessesInteropAgent consolesInteropAgent = null, ISnackbarMessageQueue snackbarMessageQueue = null) { _appState = appState ?? Locator.CurrentMutable.GetService <IAppState>(); _processFactory = processFactory ?? Locator.CurrentMutable.GetService <IProcessFactory>(); _processesTracker = processesTracker ?? Locator.CurrentMutable.GetService <IProcessesTracker>(); _processesRepository = processesRepository ?? Locator.CurrentMutable.GetService <IProcessRepository>(); _consolesInteropAgent = consolesInteropAgent ?? Locator.CurrentMutable.GetService <IProcessesInteropAgent>(); _snackbarMessageQueue = snackbarMessageQueue ?? Locator.CurrentMutable.GetService <ISnackbarMessageQueue>(); // Lists _consoleProcessEntities = new ReactiveList <ProcessEntity>() { ChangeTrackingEnabled = false }; _consolesList = _consoleProcessEntities.CreateDerivedCollection( selector: process => Mapper.Map <IProcessViewModel>(process) ); // Load Processess _loadConsolesCommand = ReactiveCommand.CreateFromTask(async() => await LoadConsolesCommandAction()); _loadConsolesCommand.IsExecuting.BindTo(this, @this => @this.IsLoadingConsoles); _loadConsolesCommand.Subscribe(entities => LoadConsolesCommandHandler(entities)); // Create Instances _startConsoleProcessCommandFactory = () => { var command = ReactiveCommand.CreateFromTask <IProcessViewModel, IProcessInstanceViewModel>(async(option) => await StartConsoleProcessCommandAction(option)); command.ThrownExceptions.Subscribe(@exception => StartConsoleProcessCommandError(@exception)); command.Subscribe(instance => StartConsoleProcessCommandHandler(instance)); return(command); }; }
public MainViewModel() { this.activator = new ViewModelActivator(); this.dinosaurModels = new ReactiveList<Data.Dinosaur>( Data .Dinosaurs .All .Take(10)); this.dinosaurs = this .dinosaurModels .CreateDerivedCollection( selector: dinosaur => new DinosaurViewModel(dinosaur.Name)); this .WhenActivated( disposables => { Observable .Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler) .Do(_ => MakeRandomChange()) .Subscribe() .DisposeWith(disposables); }); }
public CoinListViewModel(IReactiveDerivedList <CoinViewModel> coins) { Coins = coins; }
public PlaylistViewModel(Playlist playlist, Library library, Guid accessToken, CoreSettings coreSettings) { if (playlist == null) { throw new ArgumentNullException(nameof(playlist)); } if (library == null) { throw new ArgumentNullException(nameof(library)); } if (coreSettings == null) { throw new ArgumentNullException(nameof(coreSettings)); } this.playlist = playlist; this.library = library; this.disposable = new CompositeDisposable(); this.entries = playlist .CreateDerivedCollection(entry => new PlaylistEntryViewModel(entry), x => x.Dispose()) .DisposeWith(this.disposable); this.playlist.WhenAnyValue(x => x.CurrentSongIndex).ToUnit() .Merge(this.entries.Changed.ToUnit()) .Subscribe(_ => this.UpdateCurrentSong()) .DisposeWith(this.disposable); IObservable <List <PlaylistEntryViewModel> > remainingSongs = this.entries.Changed .Select(x => Unit.Default) .Merge(this.playlist.WhenAnyValue(x => x.CurrentSongIndex).ToUnit()) .Select(x => this.entries.Reverse().TakeWhile(entry => !entry.IsPlaying).ToList()); this.songsRemaining = remainingSongs .Select(x => x.Count) .ToProperty(this, x => x.SongsRemaining) .DisposeWith(this.disposable); this.timeRemaining = remainingSongs .Select(x => x.Any() ? x.Select(entry => entry.Duration).Aggregate((t1, t2) => t1 + t2) : (TimeSpan?)null) .ToProperty(this, x => x.TimeRemaining) .DisposeWith(this.disposable); this.CurrentPlayingEntry = this.Model.WhenAnyValue(x => x.CurrentSongIndex).Select(x => x == null ? null : this.entries[x.Value]); this.canAlterPlaylist = this.library.LocalAccessControl.HasAccess(coreSettings.WhenAnyValue(x => x.LockPlaylist), accessToken) .ToProperty(this, x => x.CanAlterPlaylist) .DisposeWith(disposable); // We re-evaluate the selected entries after each up or down move here, because WPF // doesn't send us proper updates about the selection var reEvaluateSelectedPlaylistEntry = new Subject <Unit>(); this.MovePlaylistSongUpCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedEntries) .Merge(reEvaluateSelectedPlaylistEntry.Select(_ => this.SelectedEntries)) .Select(x => x != null && x.Count() == 1 && x.First().Index > 0) .CombineLatest(this.WhenAnyValue(x => x.CanAlterPlaylist), (canMoveUp, canAlterPlaylist) => canMoveUp && canAlterPlaylist)); this.MovePlaylistSongUpCommand.Subscribe(_ => { int index = this.SelectedEntries.First().Index; this.library.MovePlaylistSong(index, index - 1, accessToken); reEvaluateSelectedPlaylistEntry.OnNext(Unit.Default); }); this.MovePlaylistSongDownCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedEntries) .Merge(reEvaluateSelectedPlaylistEntry.Select(_ => this.SelectedEntries)) .Select(x => x != null && x.Count() == 1 && x.First().Index < this.Songs.Count - 1) .CombineLatest(this.WhenAnyValue(x => x.CanAlterPlaylist), (canMoveDown, canAlterPlaylist) => canMoveDown && canAlterPlaylist)); this.MovePlaylistSongDownCommand.Subscribe(_ => { int index = this.SelectedEntries.First().Index; this.library.MovePlaylistSong(index, index + 1, accessToken); reEvaluateSelectedPlaylistEntry.OnNext(Unit.Default); }); this.MovePlaylistSongCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedEntries) .Merge(reEvaluateSelectedPlaylistEntry.Select(_ => this.SelectedEntries)) .Select(x => x != null && x.Count() == 1) .CombineLatest(this.WhenAnyValue(x => x.CanAlterPlaylist), (canMoveUp, canAlterPlaylist) => canMoveUp && canAlterPlaylist)); this.MovePlaylistSongCommand.Subscribe(x => { int fromIndex = this.SelectedEntries.First().Index; int toIndex = (int?)x ?? this.Songs.Last().Index + 1; // If we move a song from the front of the playlist to the back, we want it move be // in front of the target song if (fromIndex < toIndex) { toIndex--; } this.library.MovePlaylistSong(fromIndex, toIndex, accessToken); reEvaluateSelectedPlaylistEntry.OnNext(Unit.Default); }); this.RemoveSelectedPlaylistEntriesCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedEntries, x => x.CanAlterPlaylist, (selectedPlaylistEntries, canAlterPlaylist) => selectedPlaylistEntries != null && selectedPlaylistEntries.Any() && canAlterPlaylist)); this.RemoveSelectedPlaylistEntriesCommand.Subscribe(x => this.library.RemoveFromPlaylist(this.SelectedEntries.Select(entry => entry.Index), accessToken)); }
private static void CleanReactiveBuySell <T>(ref CompositeDisposable subscribsion, ref IReactiveDerivedList <T> reaciveList) { if (subscribsion != null) { subscribsion.Dispose(); subscribsion = null; reaciveList.Dispose(); reaciveList = null; } }
void SubscribeToEntryOrderRelatedEvents() { var bsThrottleTimeSpan = 0.1.FromSeconds(); var cpThrottleTimeSpan = 0.25.FromSeconds(); var buySelPropsExceptions = new[] { "CanTradeEx", "IsGhost" }; Func <IReactivePropertyChangedEventArgs <SuppRes>, bool> buySellPropsFilter = _ => !buySelPropsExceptions.Contains(_.PropertyName); //ISubject<Action> fxWraper = new Subject<Action>(); //fxWraper.ObserveOn(TradesManagerStatic.TradingScheduler).Subscribe(a => a(), () => { Debugger.Break(); }); #region SetTradeNet Action <Trade, double, double> SetTradeNet = (trade, limit, stop) => { //fxWraper.OnNext(() => { var fw = TradesManager; if (!limit.IsNaN()) { try { if (fw.GetNetOrderRate(Pair, false).Abs(limit) > InPoints(1)) { //Log = new Exception("FixOrderSetLimit:" + new { trade.Pair, limit = limit.Round(Digits()) }); fw.FixOrderSetLimit(trade.Id, limit, ""); } } catch (Exception exc) { Log = exc; } } if (!stop.IsNaN()) { try { if (fw.GetNetOrderRate(Pair, true).Abs(stop) > InPoints(1)) { //Log = new Exception("FixOrderSetStop:" + new { trade.Pair, stop = stop.Round(Digits()) }); fw.FixOrderSetStop(trade.Id, stop, ""); } } catch (Exception exc) { Log = exc; } } TradeLastChangeDate = DateTime.Now; //}); }; Action <Trade, double> SetTradeNetLimit = (trade, limit) => SetTradeNet(trade, limit, double.NaN); Action <Trade, double> SetTradeNetStop = (trade, stop) => SetTradeNet(trade, double.NaN, stop); Action CloseAllNetLimits = () => Trades.Take(1).ForEach(trade => SetTradeNetLimit(trade, 0)); Action CloseAllNetStops = () => Trades.Take(1).ForEach(trade => SetTradeNetStop(trade, 0)); #endregion #region startBuySellLevelsTracking Action startBuySellLevelsTracking = () => { #region updateEntryOrders Action <string> updateEntryOrders = (reason) => { try { var buySellLevels = new[] { BuyLevel, SellLevel }; GetEntryOrders().GroupBy(eo => eo.IsBuy).SelectMany(eog => eog.Skip(1)).ForEach(OnDeletingOrder); Func <SuppRes, bool> canTrade = (sr) =>/* IsTradingHour() &&*/ sr.CanTrade && sr.TradesCount <= 0 && !Trades.IsBuy(sr.IsBuy).Any(); Func <bool, int> lotSize = isBuy => (buySellLevels.Where(sr => sr.IsBuy == isBuy).Any(canTrade) ? (isBuy ? LotSizeByLossBuy : LotSizeByLossSell) : 0) + (TradesManager.GetNetOrderRate(Pair, true) > 0 ? 0 : Trades.IsBuy(!isBuy).Lots()); buySellLevels.Select(sr => new { sr.IsBuy, sr.Rate, lotSize = lotSize(sr.IsBuy) }) .Do(sr => GetEntryOrders(sr.IsBuy).Where(a => sr.lotSize == 0).ForEach(OnDeletingOrder)) .Where(sr => sr.lotSize > 0 && !GetEntryOrders(sr.IsBuy).Any()) .ForEach(level => OnCreateEntryOrder(level.IsBuy, level.lotSize, level.Rate)); Action <Order> changeLimit = eo => TradesManager.YieldIf(!IsInVirtualTrading && eo.Lot.Ratio(lotSize(eo.IsBuy)) > 1.025) .ForEach(fw => { //Log = new Exception("ChangeEntryOrderLot:" + reason); fw.ChangeEntryOrderLot(eo.OrderID, lotSize(eo.IsBuy)); }); Func <bool, double> orderRate = isBuy => buySellLevels.Where(sr => sr.IsBuy == isBuy).First().Rate; Action <Order> changeRate = eo => TradesManager.YieldIf(!IsInVirtualTrading && eo.Rate.Abs(orderRate(eo.IsBuy)) > PointSize) .ForEach(fw => { //Log = new Exception("ChangeEntryOrderRate:" + reason); fw.ChangeEntryOrderRate(eo.OrderID, orderRate(eo.IsBuy)); }); GetEntryOrders().ForEach(eo => { changeLimit(eo); changeRate(eo); }); } catch (Exception exc) { Log = exc; } }; #endregion _reactiveBuySellLevels = new[] { BuyLevel, SellLevel, BuyCloseLevel, SellCloseLevel }.CreateDerivedCollection(sr => sr); _reactiveBuySellLevels.ChangeTrackingEnabled = true; _reactiveBuySellLevelsSubscribtion = (CompositeDisposable) _reactiveBuySellLevels.ItemChanged .Where(buySellPropsFilter) .Sample(bsThrottleTimeSpan) //.Do(_ => Log = new Exception(new { Name = "startBuySellLevelsTracking", _.PropertyName, Value = _.Value + "" } + "")) .Select(_ => _.Sender.IsBuy ? "Buy" + (_.Sender.IsExitOnly ? "Close" : "") + "Level" : "Sell" + (_.Sender.IsExitOnly ? "Close" : "") + "Level") .Merge(ReactiveTrades.ItemChanged.Where(_ => _.PropertyName == "Stop").Select(_ => _.Sender.IsBuy ? "BuyTrade" : "SellTrade")) .Merge(Observable.FromEventPattern <EventHandler <OrderEventArgs>, OrderEventArgs>( h => TradesManager.OrderAdded += h, h => TradesManager.OrderAdded -= h).Select(e => "OrderAdded")) .Merge(Observable.FromEventPattern <EventHandler <OrderEventArgs>, OrderEventArgs>( h => TradesManager.OrderChanged += h, h => TradesManager.OrderChanged -= h).Select(e => "OrderChanged")) .Merge(Observable.FromEvent <OrderRemovedEventHandler, Order>(h => TradesManager.OrderRemoved += h, h => TradesManager.OrderRemoved -= h).Select(_ => "OrderRemoved")) .Merge(this.WhenAny(tm => tm.CurrentPrice, tm => "CurrentPrice").Sample(cpThrottleTimeSpan)) .Merge(this.WhenAny(tm => tm.CanDoEntryOrders, tm => "CanDoEntryOrders")) .Merge(this.WhenAny(tm => tm.CanDoNetStopOrders, tm => "CanDoNetStopOrders")) .Subscribe(reason => _updateEntryOrdersBuffer.Push(() => updateEntryOrders(reason))); updateEntryOrders("Start Tracking"); }; #endregion #region startBuySellCloseLevelsTracking #region Net Update Implementations var bsCloseLevels = MonoidsCore.ToFunc(() => new[] { BuyCloseLevel, SellCloseLevel }.Where(sr => sr != null)); Action updateTradeLimitOrders = () => { Func <Trade, double[]> levelRate = trade => bsCloseLevels().Where(sr => sr.IsBuy == !trade.IsBuy).Select(sr => sr.Rate).Take(1).ToArray(); Action <Trade> changeRate = trade => levelRate(trade) .Where(_ => !IsInVirtualTrading) .Where(lr => trade.Limit.Abs(lr) > PointSize) .ForEach(lr => SetTradeNetLimit(trade, lr)); Trades.Take(1).ForEach(changeRate); }; Func <Trade, double[]> getDefaultStop = trade => // Take care of reversed corridor bsCloseLevels() .Where(_ => SellLevel.Rate > BuyLevel.Rate) .Where(bs => bs.IsBuy != trade.IsBuy) .Select(bs => trade.Open.Abs(bs.Rate) * 2) .Select(stop => trade.IsBuy ? -stop : stop) .Select(stop => trade.Open + stop) .ToArray(); Action updateTradeStopOrders = () => { var bsLevels = new[] { BuyLevel, SellLevel }.Where(sr => sr != null); Func <Trade, IEnumerable <double> > levelRate = trade => getDefaultStop(trade) .Concat(bsLevels .Where(sr => sr.IsBuy == !trade.IsBuy && (!CanDoEntryOrders || !sr.CanTrade)) .Select(t => t.Rate) .Take(1) ) .Take(1); Action <Trade> changeRate = trade => TradesManager.YieldNotNull(levelRate(trade).Any(rate => trade.Stop.Abs(rate) > PointSize)) .ForEach(fw => levelRate(trade).ForEach(rate => SetTradeNetStop(trade, rate))); Trades.Take(1).ForEach(changeRate); }; #endregion // New Limit Action startBuySellCloseLimitTracking = () => { _reactiveBuySellLimitLevels = new[] { BuyCloseLevel, SellCloseLevel, BuyLevel, SellLevel } .CreateDerivedCollection(sr => sr); _reactiveBuySellLimitLevels.ChangeTrackingEnabled = true; _reactiveBuySellCloseLimitSubscribtion = (CompositeDisposable)_reactiveBuySellLimitLevels .ItemChanged .Where(buySellPropsFilter) .Sample(bsThrottleTimeSpan) //.Do(_ => Log = new Exception(new { Name = "startBuySellCloseLevelsTracking", _.PropertyName, Value = _.Value + "" } + "")) .Select(_ => _.Sender.IsBuy ? "Buy(Close)Level" : "Sell(Close)Level") .Merge(this.WhenAny(tm => tm.CurrentPrice, tm => "CurrentPrice").Sample(cpThrottleTimeSpan)) .Merge(this.WhenAny(tm => tm.CanDoEntryOrders, tm => "CanDoEntryOrders")) .Merge(this.WhenAny(tm => tm.CanDoNetStopOrders, tm => "CanDoNetStopOrders")) .Merge(this.WhenAny(tm => tm.IsTrader, tm => "IsTrader")) .Subscribe(_ => { if (CanDoNetLimitOrders) { updateTradeLimitOrders(); } else { CloseAllNetLimits(); } }); }; // New Stop Action startBuySellCloseStopTracking = () => { _reactiveBuySellStopLevels = new[] { BuyCloseLevel, SellCloseLevel, BuyLevel, SellLevel } .CreateDerivedCollection(sr => sr); _reactiveBuySellStopLevels.ChangeTrackingEnabled = true; _reactiveBuySellCloseStopSubscribtion = (CompositeDisposable)_reactiveBuySellStopLevels .ItemChanged .Where(buySellPropsFilter) .Sample(bsThrottleTimeSpan) //.Do(_ => Log = new Exception(new { Name = "startBuySellCloseLevelsTracking", _.PropertyName, Value = _.Value + "" } + "")) .Select(_ => _.Sender.IsBuy ? "Buy(Close)Level" : "Sell(Close)Level") .Merge(this.WhenAny(tm => tm.CurrentPrice, tm => "CurrentPrice").Sample(cpThrottleTimeSpan)) .Merge(this.WhenAny(tm => tm.CanDoEntryOrders, tm => "CanDoEntryOrders")) .Merge(this.WhenAny(tm => tm.CanDoNetStopOrders, tm => "CanDoNetStopOrders")) .Merge(this.WhenAny(tm => tm.IsTrader, tm => "IsTrader")) .Subscribe(_ => { if (CanDoNetStopOrders) { updateTradeStopOrders(); } else { CloseAllNetStops(); } }); }; #endregion #region Init BuySellLevels this.WhenAny(tm => tm.Strategy , tm => tm.TrailingDistanceFunction , tm => tm.HasBuyLevel , tm => tm.HasSellLevel , tm => tm.CanDoEntryOrders , tm => tm.CanDoNetLimitOrders , tm => tm.MustStopTrading , (s, t, eo, no, ta, bl, sl) => Strategy == Strategies.Universal && HasBuyLevel && HasSellLevel && CanDoEntryOrders && !MustStopTrading && !IsInVirtualTrading ) .DistinctUntilChanged() .Sample(bsThrottleTimeSpan) .Subscribe(st => { // Turn on/off live entry orders try { if (st) // Subscribe to events in order to update live entry orders //Log = new Exception("startBuySellLevelsTracking"); { startBuySellLevelsTracking(); } else if (_reactiveBuySellLevelsSubscribtion != null) { try { GetEntryOrders().ToList().ForEach(order => OnDeletingOrder(order.OrderID)); } catch (Exception exc) { Log = exc; } CleanReactiveBuySell(ref _reactiveBuySellLevelsSubscribtion, ref _reactiveBuySellLevels); } } catch (Exception exc) { Log = exc; } }); #endregion #region Init BuySellCloseLevels //this.WhenAny( // tm => tm.BuyCloseLevel // , tm => tm.SellCloseLevel // , tm => tm.CanDoNetLimitOrders // , tm => tm.CanDoNetStopOrders // , tm => tm.CanDoEntryOrders // , (b, s, non, nos, eo) => // BuyCloseLevel != null && SellCloseLevel != null && CanDoNetOrders && !IsInVitualTrading) // .DistinctUntilChanged() // .Sample(bsThrottleTimeSpan) // .Subscribe(st => {// Turn on/off live net orders // try { // CleanReactiveBuySell(ref _reactiveBuySellCloseLevelsSubscribtion, ref _reactiveBuySellCloseLevels); // if (!CanDoNetLimitOrders) CloseAllNetLimits(); // if (!CanDoNetStopOrders) CloseAllNetStops(); // if (st) {// (Re)Subscribe to events in order to update live net orders // Log = new Exception("startBuySellCloseLevelsTracking"); // startBuySellCloseLevelsTracking(); // } // } catch (Exception exc) { Log = exc; } // }); // New Limit this.WhenAny( tm => tm.HasBuyCloseLevel , tm => tm.HasSellCloseLevel , tm => tm.CanDoNetLimitOrders , (b, s, non) => HasBuyCloseLevel && HasSellCloseLevel && CanDoNetLimitOrders && !IsInVirtualTrading) .DistinctUntilChanged() .Sample(bsThrottleTimeSpan) .Subscribe(st => {// Turn on/off live net orders try { CleanReactiveBuySell(ref _reactiveBuySellCloseLimitSubscribtion, ref _reactiveBuySellLimitLevels); if (!CanDoNetLimitOrders) { //Log = new Exception("Stop Limit Tracking"); CloseAllNetLimits(); } if (st)// (Re)Subscribe to events in order to update live net orders //Log = new Exception("Start Limit Tracking"); { startBuySellCloseLimitTracking(); } } catch (Exception exc) { Log = exc; } }); // Net Stop this.WhenAny( tm => tm.HasBuyCloseLevel , tm => tm.HasSellCloseLevel , tm => tm.CanDoNetStopOrders , (b, s, non) => HasBuyCloseLevel && HasSellCloseLevel && CanDoNetStopOrders && !IsInVirtualTrading) .DistinctUntilChanged() .Sample(bsThrottleTimeSpan) .Subscribe(st => {// Turn on/off live net orders try { CleanReactiveBuySell(ref _reactiveBuySellCloseStopSubscribtion, ref _reactiveBuySellStopLevels); if (!CanDoNetStopOrders) { //Log = new Exception("Stop Stop Tracking"); CloseAllNetStops(); } if (st)// (Re)Subscribe to events in order to update live net orders //Log = new Exception("Start Stop Tracking"); { startBuySellCloseStopTracking(); } } catch (Exception exc) { Log = exc; } }); #endregion }
public PlaylistViewModel(Playlist playlist, Library library, Guid accessToken, CoreSettings coreSettings) { if (playlist == null) throw new ArgumentNullException("playlist"); if (library == null) throw new ArgumentNullException("library"); if (coreSettings == null) throw new ArgumentNullException("coreSettings"); this.playlist = playlist; this.library = library; this.disposable = new CompositeDisposable(); this.entries = playlist .CreateDerivedCollection(entry => new PlaylistEntryViewModel(entry), x => x.Dispose()) .DisposeWith(this.disposable); this.playlist.WhenAnyValue(x => x.CurrentSongIndex).ToUnit() .Merge(this.entries.Changed.ToUnit()) .Subscribe(_ => this.UpdateCurrentSong()) .DisposeWith(this.disposable); IObservable<List<PlaylistEntryViewModel>> remainingSongs = this.entries.Changed .Select(x => Unit.Default) .Merge(this.playlist.WhenAnyValue(x => x.CurrentSongIndex).ToUnit()) .Select(x => this.entries.Reverse().TakeWhile(entry => !entry.IsPlaying).ToList()); this.songsRemaining = remainingSongs .Select(x => x.Count) .ToProperty(this, x => x.SongsRemaining) .DisposeWith(this.disposable); this.timeRemaining = remainingSongs .Select(x => x.Any() ? x.Select(entry => entry.Duration).Aggregate((t1, t2) => t1 + t2) : (TimeSpan?)null) .ToProperty(this, x => x.TimeRemaining) .DisposeWith(this.disposable); this.CurrentPlayingEntry = this.Model.WhenAnyValue(x => x.CurrentSongIndex).Select(x => x == null ? null : this.entries[x.Value]); this.canAlterPlaylist = this.library.LocalAccessControl.HasAccess(coreSettings.WhenAnyValue(x => x.LockPlaylist), accessToken) .ToProperty(this, x => x.CanAlterPlaylist) .DisposeWith(disposable); // We re-evaluate the selected entries after each up or down move here, because WPF // doesn't send us proper updates about the selection var reEvaluateSelectedPlaylistEntry = new Subject<Unit>(); this.MovePlaylistSongUpCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedEntries) .Merge(reEvaluateSelectedPlaylistEntry.Select(_ => this.SelectedEntries)) .Select(x => x != null && x.Count() == 1 && x.First().Index > 0) .CombineLatest(this.WhenAnyValue(x => x.CanAlterPlaylist), (canMoveUp, canAlterPlaylist) => canMoveUp && canAlterPlaylist)); this.MovePlaylistSongUpCommand.Subscribe(_ => { int index = this.SelectedEntries.First().Index; this.library.MovePlaylistSong(index, index - 1, accessToken); reEvaluateSelectedPlaylistEntry.OnNext(Unit.Default); }); this.MovePlaylistSongDownCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedEntries) .Merge(reEvaluateSelectedPlaylistEntry.Select(_ => this.SelectedEntries)) .Select(x => x != null && x.Count() == 1 && x.First().Index < this.Songs.Count - 1) .CombineLatest(this.WhenAnyValue(x => x.CanAlterPlaylist), (canMoveDown, canAlterPlaylist) => canMoveDown && canAlterPlaylist)); this.MovePlaylistSongDownCommand.Subscribe(_ => { int index = this.SelectedEntries.First().Index; this.library.MovePlaylistSong(index, index + 1, accessToken); reEvaluateSelectedPlaylistEntry.OnNext(Unit.Default); }); this.MovePlaylistSongCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedEntries) .Merge(reEvaluateSelectedPlaylistEntry.Select(_ => this.SelectedEntries)) .Select(x => x != null && x.Count() == 1) .CombineLatest(this.WhenAnyValue(x => x.CanAlterPlaylist), (canMoveUp, canAlterPlaylist) => canMoveUp && canAlterPlaylist)); this.MovePlaylistSongCommand.Subscribe(x => { int fromIndex = this.SelectedEntries.First().Index; int toIndex = (int?)x ?? this.Songs.Last().Index + 1; // If we move a song from the front of the playlist to the back, we want it move be // in front of the target song if (fromIndex < toIndex) { toIndex--; } this.library.MovePlaylistSong(fromIndex, toIndex, accessToken); reEvaluateSelectedPlaylistEntry.OnNext(Unit.Default); }); this.RemoveSelectedPlaylistEntriesCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedEntries, x => x.CanAlterPlaylist, (selectedPlaylistEntries, canAlterPlaylist) => selectedPlaylistEntries != null && selectedPlaylistEntries.Any() && canAlterPlaylist)); this.RemoveSelectedPlaylistEntriesCommand.Subscribe(x => this.library.RemoveFromPlaylist(this.SelectedEntries.Select(entry => entry.Index), accessToken)); }
public GamesViewModel(IDependencyResolver resolver) { _platformManager = resolver.GetService<IPlatformManager>(); var gameManager = resolver.GetService<IGameManager>(); // setup init listener gameManager.Initialized.Subscribe(_ => SetupTracking()); // create platforms, filtered and sorted Platforms = _platformManager.Platforms.CreateDerivedCollection( platform => platform, platform => platform.IsEnabled, (x, y) => string.Compare(x.Name, y.Name, StringComparison.Ordinal) ); // push all games into AllGames as view models and sorted _allGames = gameManager.Games.CreateDerivedCollection( game => new GameItemViewModel(game, resolver) { IsVisible = IsGameVisible(game) }, gameViewModel => true, (x, y) => string.Compare(x.Game.Id, y.Game.Id, StringComparison.Ordinal) ); // push filtered game view models into Games Games = _allGames.CreateDerivedCollection( gameViewModel => gameViewModel, gameViewModel => gameViewModel.IsVisible); // todo check if we can simplify this. IdentifyAll.Subscribe(_ => { /* Games .ToObservable() .Where(g => g.ShowIdentifyButton) .StepInterval(TimeSpan.FromMilliseconds(200)) // don't DOS the server... .Select(g => Observable.DeferAsync(async token => Observable.Return(await System.Windows.Application.Current. // must be on main thread Dispatcher.Invoke(async () => new { game = g, result = await g.IdentifyRelease.ExecuteAsyncTask() })))) .Merge(1) .Subscribe(x => { if (x.result.Count == 0) { System.Windows.Application.Current.Dispatcher.Invoke(delegate { x.game.CloseResults.Execute(null); }); } });*/ Games .ToObservable() .Where(g => !g.HasExecuted && !g.Game.HasRelease && !g.IsExecuting) .StepInterval(TimeSpan.FromMilliseconds(200)) // don't DOS the server... .Subscribe(g => { System.Windows.Application.Current.Dispatcher.Invoke(async () => { var result = await g.IdentifyRelease.ExecuteAsyncTask(); if (result.Count == 0) { g.CloseResults.Execute(null); } }); }); }); }