public TradingViewModel(ViewModelContext viewModelContext,
                                AccountViewModel accountViewModel, SymbolsViewModel symbolsViewModel,
                                TradeViewModel tradeViewModel, OrdersViewModel ordersViewModel,
                                IWpfExchangeService exchangeService, IAccountsService accountsService,
                                IChartHelper chartHelper)
            : base(viewModelContext)
        {
            AccountViewModel = accountViewModel;
            SymbolsViewModel = symbolsViewModel;
            TradeViewModel   = tradeViewModel;
            OrdersViewModel  = ordersViewModel;

            Symbols = new ObservableCollection <SymbolViewModel>();
            symbolObservableSubscriptions = new Dictionary <string, IDisposable>();

            this.exchangeService = exchangeService;
            this.accountsService = accountsService;
            this.chartHelper     = chartHelper;

            ObserveSymbols();
            ObserveAccount();
            ObserveTrade();
            ObserveOrders();

            CloseCommand = new ViewModelCommand(Close);
        }
        private void ObserveAccount()
        {
            var accountObservable = Observable.FromEventPattern <AccountEventArgs>(
                eventHandler => AccountViewModel.OnAccountNotification += eventHandler,
                eventHandler => AccountViewModel.OnAccountNotification -= eventHandler)
                                    .Select(eventPattern => eventPattern.EventArgs);

            accountObservableSubscription = accountObservable.Subscribe(args =>
            {
                if (args.HasException)
                {
                    TradeViewModelException(args);
                }
                else if (args.AccountEventType.Equals(AccountEventType.LoggedIn) ||
                         args.AccountEventType.Equals(AccountEventType.LoggedOut))
                {
                    TradeViewModel.SetAccount(args.Value);
                    OrdersViewModel.SetAccount(args.Value).FireAndForget();
                }
                else if (args.AccountEventType.Equals(AccountEventType.UpdateOrders))
                {
                    TradeViewModel.Touch();
                    OrdersViewModel.UpdateOrders(args.Value).FireAndForget();
                }
                else if (args.AccountEventType.Equals(AccountEventType.SelectedAsset))
                {
                    TradeViewModel.SetSymbol(args.SelectedAsset);
                }
            });
        }
        private void ObserveSymbols()
        {
            var symbolsObservable = Observable.FromEventPattern <SymbolsEventArgs>(
                eventHandler => SymbolsViewModel.OnSymbolsNotification += eventHandler,
                eventHandler => SymbolsViewModel.OnSymbolsNotification -= eventHandler)
                                    .Select(eventPattern => eventPattern.EventArgs);

            symbolsObservableSubscription = symbolsObservable.Subscribe(async(args) =>
            {
                if (args.HasException)
                {
                    TradeViewModelException(args);
                }
                else if (args.Value != null)
                {
                    var symbol = Symbols.FirstOrDefault(s => s.Symbol.Name.Equals(args.Value.Name));
                    if (symbol != null)
                    {
                        SelectedSymbol = symbol;
                    }
                    else
                    {
                        symbol            = new SymbolViewModel(exchangeService, chartHelper, userAccount.Preferences, Logger);
                        symbol.Dispatcher = ViewModelContext.UiDispatcher;
                        Symbols.Add(symbol);
                        SelectedSymbol = symbol;

                        try
                        {
                            await symbol.SetSymbol(args.Value);
                            ObserveSymbol(symbol);
                        }
                        catch (Exception ex)
                        {
                            TradeViewModelException(ex.ToString(), ex);
                        }
                    }
                }
                else if (args.Symbols != null)
                {
                    TradeViewModel.SetSymbols(args.Symbols);
                }
            });
        }
        protected override void OnDisposing()
        {
            if (disposed)
            {
                return;
            }

            if (AccountViewModel != null)
            {
                accountObservableSubscription.Dispose();
                AccountViewModel.Dispose();
            }

            foreach (var subscription in symbolObservableSubscriptions.Values)
            {
                subscription.Dispose();
            }

            foreach (var symbol in Symbols)
            {
                symbol.Dispose();
            }

            if (SymbolsViewModel != null)
            {
                symbolsObservableSubscription.Dispose();
                SymbolsViewModel.Dispose();
            }

            if (TradeViewModel != null)
            {
                tradeObservableSubscription.Dispose();
                TradeViewModel.Dispose();
            }

            if (OrdersViewModel != null)
            {
                ordersObservableSubscription.Dispose();
                OrdersViewModel.Dispose();
            }

            disposed = true;
        }