public RequestStatus OpenPosition(string hash, string userLogin, long localTime, int accountId,
                                          string symbol, int volume, int side, float stopLoss, float takeProfit, int magic, string comment)
        {
            var status = CheckCredentials(hash, userLogin, localTime, accountId, true);

            if (status != RequestStatus.OK)
            {
                return(status);
            }

            status = managerTrade.SendNewOrderRequest(ProtectedOperationContext.MakeServerSideContext(),
                                                      RequestUniqueId.Next(), new MarketOrder
            {
                AccountID  = accountId,
                Symbol     = symbol,
                Volume     = volume,
                Side       = side,
                StopLoss   = stopLoss == 0 ? (float?)null : stopLoss,
                TakeProfit = takeProfit == 0 ? (float?)null : takeProfit,
                Magic      = magic,
                Comment    = comment
            },
                                                      OrderType.Market,
                                                      0, 0);
            return(status);
        }
        public Wallet GetUserWalletSubscriptionAndLastPayments(ProtectedOperationContext ctx, string userLogin, int maxPaymentsQuery,
                                                               out List <Subscription> subscriptions, out List <Transfer> transfers, out WalletError error)
        {
            subscriptions = null;
            transfers     = null;
            error         = WalletError.OK;

            if (Channel == null)
            {
                throw new Exception("WalletManagerProxy: связь не установлена");
            }
            try
            {
                return(Channel.GetUserWalletSubscriptionAndLastPayments(ctx, userLogin, maxPaymentsQuery, out subscriptions, out transfers, out error));
            }
            catch
            {
                RenewFactory();
                try
                {
                    return(Channel.GetUserWalletSubscriptionAndLastPayments(ctx, userLogin, maxPaymentsQuery,
                                                                            out subscriptions, out transfers, out error));
                }
                catch (Exception ex2)
                {
                    Logger.Error("GetUserWalletSubscriptionAndLastPayments() error: ", ex2);
                    return(null);
                }
            }
        }
Beispiel #3
0
 public CreateReadonlyUserRequestStatus MakeOrDeleteReadonlyUser(ProtectedOperationContext secCtx,
                                                                 int accountId, bool makeNew, string pwrd,
                                                                 out PlatformUser user)
 {
     user = null;
     return(CreateReadonlyUserRequestStatus.CommonError);
 }
 public Wallet TransferToWallet(ProtectedOperationContext ctx, string userLogin,
                                int accountId, decimal amountInAccountCurrency, out WalletError error)
 {
     error = WalletError.OK;
     if (Channel == null)
     {
         throw new Exception("WalletManagerProxy: связь не установлена");
     }
     try
     {
         return(Channel.TransferToWallet(ctx, userLogin, accountId, amountInAccountCurrency, out error));
     }
     catch
     {
         RenewFactory();
         try
         {
             return(Channel.TransferToWallet(ctx, userLogin, accountId, amountInAccountCurrency, out error));
         }
         catch (Exception ex2)
         {
             Logger.Error("TransferToWallet() error: ", ex2);
             return(null);
         }
     }
 }
 public WalletError ChangePaymentSystemWallets(ProtectedOperationContext ctx, UserPaymentSystem paySys,
                                               bool remove,
                                               string userLogin, string walletPwrd)
 {
     if (Channel == null)
     {
         throw new Exception("WalletManagerProxy: связь не установлена");
     }
     try
     {
         return(Channel.ChangePaymentSystemWallets(ctx, paySys, remove, userLogin, walletPwrd));
     }
     catch
     {
         RenewFactory();
         try
         {
             return(Channel.ChangePaymentSystemWallets(ctx, paySys, remove, userLogin, walletPwrd));
         }
         catch (Exception ex2)
         {
             Logger.Error("ChangePaymentSystemWallets() error: ", ex2);
             return(WalletError.CommonError);
         }
     }
 }
 public List <Transfer> GetAllUserPayments(ProtectedOperationContext ctx, PlatformUser user, out WalletError error)
 {
     error = WalletError.OK;
     if (Channel == null)
     {
         throw new Exception("WalletManagerProxy: связь не установлена");
     }
     try
     {
         return(Channel.GetAllUserPayments(ctx, user, out error));
     }
     catch
     {
         RenewFactory();
         try
         {
             return(Channel.GetAllUserPayments(ctx, user, out error));
         }
         catch (Exception ex2)
         {
             Logger.Error("GetAllUserPayments() error: ", ex2);
             return(null);
         }
     }
 }
 public bool SubscribeOnService(ProtectedOperationContext ctx,
                                string login, int serviceId, bool renewAuto, bool unsubscribe, out WalletError error)
 {
     error = WalletError.OK;
     if (Channel == null)
     {
         throw new Exception("WalletManagerProxy: связь не установлена");
     }
     try
     {
         return(Channel.SubscribeOnService(ctx, login, serviceId, renewAuto, unsubscribe, out error));
     }
     catch
     {
         RenewFactory();
         try
         {
             return(Channel.SubscribeOnService(ctx, login, serviceId, renewAuto, unsubscribe, out error));
         }
         catch (Exception ex2)
         {
             Logger.Error("SubscribeOnService() error: ", ex2);
             return(false);
         }
     }
 }
Beispiel #8
0
        public List <Transfer> GetAllUserPayments(ProtectedOperationContext secCtx, PlatformUser user, out WalletError error)
        {
            if (!UserSessionStorage.Instance.PermitUserOperation(secCtx, false, false))
            {
                error = WalletError.InsufficientRights;
                return(null);
            }

            error = WalletError.ServerError;
            var transfers = new List <Transfer>();

            try
            {
                using (var ctx = DatabaseContext.Instance.Make())
                {
                    var queryTrans = (from trans in ctx.TRANSFER where trans.User == user.ID select trans).ToList().Select(
                        LinqToEntity.DecorateTransfer).ToList();
                }

                return(transfers);
            }
            catch (Exception ex)
            {
                Logger.Error("GetAllUserPayments() error", ex);
                error = WalletError.ServerError;
                return(null);
            }
        }
        public void TestGetAccountTransfersPartByPart()
        {
            var user = conn.PLATFORM_USER.First(u => u.TRANSFER.Count > 30);
            var userTransfersCount = user.TRANSFER.Count;

            var startId    = 0;
            var totalCount = 0;

            while (true)
            {
                var transfers = testManager.GetAccountTransfersPartByPart(
                    ProtectedOperationContext.MakeServerSideContext(), user.Login, startId, 20);
                if (transfers.Count == 0)
                {
                    break;
                }

                totalCount += transfers.Count;
                startId     = transfers.Max(t => t.Id);
                Assert.IsTrue(transfers.All(t => t != null),
                              "GetAccountTransfersPartByPart - не жолжно быть пустых (null) трансферов");
            }
            Assert.AreEqual(userTransfersCount, totalCount,
                            "GetAccountTransfersPartByPart - неверное количество трансферов");
        }
Beispiel #10
0
        public Wallet TransferToTradingAccount(ProtectedOperationContext secCtx,
                                               string userLogin, int accountId, decimal amountInWalletCurrency, out WalletError error)
        {
            var rst = DepositOrWithdraw(secCtx, true, userLogin, accountId, amountInWalletCurrency, out error);

            return(rst);
        }
Beispiel #11
0
        public Wallet GetUserWallet(ProtectedOperationContext secCtx, string userLogin)
        {
            // запрос разрешен?
            if (!UserSessionStorage.Instance.PermitUserOperation(secCtx, false, false))
            {
                return(null);
            }

            // получить кошелек пользователя и вернуть его
            try
            {
                using (var ctx = DatabaseContext.Instance.Make())
                {
                    var queryWallet = from us in ctx.PLATFORM_USER where us.Login == userLogin select us.WALLET;

                    foreach (var walInf in queryWallet)
                    {
                        var wallet = LinqToEntity.DecorateWallet(walInf);
                        return(wallet);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("GetUserWallet({0}) - exception: {1}", userLogin, ex);
            }

            return(null);
        }
        private void TestSubscriptionFeeCharged(ManagerTrade tradeManager, SERVICE service, PLATFORM_USER serviceOwner)
        {
            RemoveSubscriptionIfAny(service.ID);

            var         cacheInWallet = GetUserCacheAmount(subscriber.ID);
            var         ownerCache    = GetUserCacheAmount(serviceOwner.ID);
            WalletError error;

            tradeManager.SubscribeOnService(ProtectedOperationContext.MakeServerSideContext(),
                                            subscriber.Login, service.ID, true, false, new AutoTradeSettings(),
                                            out error);
            Assert.AreEqual(WalletError.OK, error, "Тестовая подписка должна пройти успешно");
            var cacheInWalletAfter = GetUserCacheAmount(subscriber.ID);
            var ownerCacheAfter    = GetUserCacheAmount(serviceOwner.ID);

            var curxRate = service.Currency == SubscriberCurx
                               ? new QuoteData(1, 1, DateTime.Now)
                               : QuoteStorage.Instance.ReceiveValue("USDRUB");
            var userLost = service.FixedPrice / (decimal)curxRate.bid;
            var ownerGot = service.FixedPrice;

            Assert.IsTrue((cacheInWallet - userLost).SameMoney(cacheInWalletAfter),
                          "Подписка сняла оговоренную сумму (валюта одна)");
            Assert.IsTrue((ownerCache + ownerGot).SameMoney(ownerCacheAfter),
                          "Подписка принесла владельцу оговоренную сумму (валюта одна)");
        }
Beispiel #13
0
        /// <summary>
        /// клиент выполнил логаут
        /// </summary>
        public void Logout(ProtectedOperationContext ctx)
        {
            // проверить контекст
            var userHash = CredentialsHash.MakeOperationParamsHash(ctx.clientLocalTime, ctx.sessionTag, ctx.terminalId);

            if (ctx.hash != userHash)
            {
                return;
            }

            // найти сессию
            try
            {
                sessionLocker.AcquireWriterLock(SessionLockTimeout);
            }
            catch (ApplicationException)
            {
                Logger.Error("Logout read timout");
                return;
            }
            try
            {
                sessions.Remove(ctx.terminalId);
            }
            catch (Exception ex)
            {
                Logger.Error("Logout error", ex);
                return;
            }
            finally
            {
                sessionLocker.ReleaseLock();
            }
        }
        /// <summary>
        /// Перевод средств на счёт / со счёта
        /// </summary>
        /// <returns></returns>
        public bool WalletTransfer(int walletId, decimal transferVolue,
                                   string userLogin, int accountId, bool deposit)
        {
            try
            {
                Wallet      res;
                WalletError error;
                if (deposit)
                {
                    res = TradeSharpWalletManager.Instance.proxy.TransferToTradingAccount(
                        ProtectedOperationContext.MakeServerSideContext(), userLogin,
                        accountId, transferVolue, out error);
                }
                else
                {
                    res = TradeSharpWalletManager.Instance.proxy.TransferToWallet(
                        ProtectedOperationContext.MakeServerSideContext(), userLogin,
                        accountId, transferVolue, out error);
                }

                Logger.Error("WalletTransfer() " + error);
                return(error == WalletError.OK && res != null);
            }
            catch (Exception ex)
            {
                Logger.Error("WalletTransfer()", ex);
            }

            return(false);
        }
Beispiel #15
0
        private static void ProcessSignalCloseOrder(TradeSignalActionClose action)
        {
            try
            {
                using (var ctx = DatabaseContext.Instance.Make())
                {
                    var targetPositions = ctx.POSITION.Where(p => p.MasterOrder ==
                                                             action.OrderId).ToList().Select(LinqToEntity.DecorateOrder);

                    foreach (var order in targetPositions)
                    {
                        // исполнить сигнал - закрыть ордер
                        try
                        {
                            var status = ProxyTrade.SendCloseRequest(ProtectedOperationContext.MakeServerSideContext(),
                                                                     order.AccountID, order.ID,
                                                                     PositionExitReason.ClosedBySignal);
                            if (status != RequestStatus.OK)
                            {
                                Logger.DebugFormat("ProcessSignalCloseOrder(#{0}) - ошибка: {1}", action.OrderId, status);
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.DebugFormat("ProcessSignalCloseOrder(#{0}) - исключение при отправке запроса: {1}",
                                               action.OrderId, ex);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.DebugFormat("ProcessSignalCloseOrder(#{0}) - исключение: {1}", action.OrderId, ex);
            }
        }
        public void TestGetAccountShares()
        {
            var shares = testManager.GetAccountShares(
                ProtectedOperationContext.MakeServerSideContext(), testAccount.ID, false);

            Assert.AreEqual(3, shares.Count, "GetAccountShares - должно вернуться 3 записи");
            Assert.AreEqual(100, shares.Sum(s => s.SharePercent), "GetAccountShares - сумма частей должна дать 100%");
            Assert.AreEqual(1, shares.Count(s => s.UserLogin == shareOwner.Login),
                            "GetAccountShares - (не) содержит логин владельца");

            // теперь - то же самое, но еще и посчитать в деньгах
            var quotes          = Contract.Util.BL.QuoteStorage.Instance.ReceiveAllData();
            var allOpenedOrders = conn.POSITION.Where(p => p.AccountID == testAccount.ID &&
                                                      p.State == (int)PositionState.Opened)
                                  .ToList()
                                  .Select(LinqToEntity.DecorateOrder)
                                  .ToList();
            var currentProfit =
                allOpenedOrders.Sum(o => DalSpot.Instance.CalculateProfitInDepoCurrency(o, quotes, testAccount.Currency));
            var equity = testAccount.Balance + (decimal)currentProfit.Value;

            shares = testManager.GetAccountShares(
                ProtectedOperationContext.MakeServerSideContext(), testAccount.ID, true);
            Assert.AreEqual(3, shares.Count, "GetAccountShares (equity) - должно вернуться 3 записи");
            var equitySum = shares.Sum(s => s.ShareMoney);
            var delta     = Math.Abs(equity - equitySum);

            Assert.Less(delta, 1, "GetAccountShares - сумма в деньгах должна совпадать, около "
                        + equity.ToStringUniformMoneyFormat());
        }
Beispiel #17
0
        private static void ProcessSignalEditOrder(TradeSignalActionMoveStopTake action)
        {
            try
            {
                using (var ctx = DatabaseContext.Instance.Make())
                {
                    var targetOrders = ctx.POSITION.Where(p => p.MasterOrder == action.OrderId).ToList();
                    foreach (var order in targetOrders.Select(LinqToEntity.DecorateOrder))
                    {
                        // исполнить сигнал - просто модифицировать ордер
                        order.TakeProfit = (float?)action.NewTakeProfit;
                        order.StopLoss   = (float?)action.NewStopLoss;

                        try
                        {
                            var status = ProxyTrade.SendEditMarketRequest(
                                ProtectedOperationContext.MakeServerSideContext(), order);
                            if (status != RequestStatus.OK)
                            {
                                Logger.DebugFormat("ProcessSignalEditOrder(#{0}) - ошибка: {1}", action.OrderId, status);
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.DebugFormat("ProcessSignalEditOrder(#{0}) - исключение при отправке запроса: {1}",
                                               action.OrderId, ex);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.DebugFormat("ProcessSignalEditOrder(#{0}) - исключение: {1}", action.OrderId, ex);
            }
        }
Beispiel #18
0
 public void ReviveChannel(ProtectedOperationContext ctx, string login, int accountId, string terminalVersion)
 {
     // уже был сделан вызов?
     if (Interlocked.CompareExchange(ref revivesCount, 1, 0) == 1)
     {
         return;
     }
     try
     {
         Proxy.ReviveChannel(ctx, login, accountId, terminalVersion);
     }
     catch (Exception)
     {
         RenewChannel();
         try
         {
             Proxy.ReviveChannel(ctx, login, accountId, terminalVersion); //wait communication exception
         }
         catch
         {
         }
     }
     finally
     {
         Interlocked.CompareExchange(ref revivesCount, 0, 1);
     }
 }
 public bool DisableService(ProtectedOperationContext ctx, int serviceId, out WalletError error)
 {
     error = WalletError.OK;
     if (Channel == null)
     {
         throw new Exception("WalletManagerProxy: связь не установлена");
     }
     try
     {
         return(Channel.DisableService(ctx, serviceId, out error));
     }
     catch
     {
         RenewFactory();
         try
         {
             return(Channel.DisableService(ctx, serviceId, out error));
         }
         catch (Exception ex2)
         {
             Logger.Error("DisableService() error: ", ex2);
             return(false);
         }
     }
 }
Beispiel #20
0
 public RequestStatus SendNewOrderRequest(ProtectedOperationContext secCtx,
                                          int requestUniqueId,
                                          MarketOrder order,
                                          OrderType orderType,
                                          decimal requestedPrice,
                                          decimal slippagePoints)
 {
     try
     {
         return(Proxy.SendNewOrderRequest(secCtx, requestUniqueId, order, orderType,
                                          requestedPrice, slippagePoints));
     }
     catch (Exception)
     {
         RenewChannel();
         try
         {
             return(Proxy.SendNewOrderRequest(secCtx, requestUniqueId, order, orderType,
                                              requestedPrice, slippagePoints));
         }
         catch (Exception)
         {
             return(RequestStatus.ServerError);
         }
     }
 }
 public Wallet TransferToTradingAccount(ProtectedOperationContext ctx, string userLogin,
                                        int accountId, decimal amountInWalletCurrency, out WalletError error)
 {
     error = WalletError.OK;
     if (Channel == null)
     {
         RenewFactory();
     }
     try
     {
         return(Channel.TransferToTradingAccount(ctx, userLogin, accountId, amountInWalletCurrency, out error));
     }
     catch
     {
         RenewFactory();
         try
         {
             return(Channel.TransferToTradingAccount(ctx, userLogin, accountId, amountInWalletCurrency, out error));
         }
         catch (Exception ex2)
         {
             Logger.Error("TransferToTradingAccount() error: ", ex2);
             return(null);
         }
     }
 }
Beispiel #22
0
 public WalletManager4Pamm(ProtectedOperationContext secCtx,
                           string login, int accountId)
 {
     this.secCtx    = secCtx;
     this.login     = login;
     this.accountId = accountId;
 }
 public List <UserPaymentSystem> GetUserRegistredPaymentSystemWallets(ProtectedOperationContext ctx,
                                                                      string userLogin,
                                                                      string walletPwrd,
                                                                      out WalletError error)
 {
     if (Channel == null)
     {
         throw new Exception("WalletManagerProxy: связь не установлена");
     }
     try
     {
         return(Channel.GetUserRegistredPaymentSystemWallets(ctx, userLogin, walletPwrd, out error));
     }
     catch
     {
         RenewFactory();
         try
         {
             return(Channel.GetUserRegistredPaymentSystemWallets(ctx, userLogin, walletPwrd, out error));
         }
         catch (Exception ex2)
         {
             Logger.Error("GetPaidServiceDetail() error: ", ex2);
             error = WalletError.CommonError;
             return(null);
         }
     }
 }
Beispiel #24
0
        /// <summary>
        /// Отписать пользователя от сигналов
        /// </summary>
        /// <param name="userLogin">Логин потзователя, который больше не хочет быть подписчиком</param>
        /// <param name="serviceId">Сигналы, которые пользователь больше не хочет получать</param>
        /// <returns></returns>
        public string UnSubscribe(string userLogin, int serviceId)
        {
            string errorMessage;

            try
            {
                var         proxy = new TradeSharpServerTrade(EmptyTradeSharpCallbackReceiver.Instance).proxy;
                WalletError walletError;
                var         status = proxy.SubscribeOnService(ProtectedOperationContext.MakeServerSideContext(),
                                                              userLogin, serviceId, false, true, null, out walletError);
                if (!status || walletError != WalletError.OK)
                {
                    errorMessage = Resource.ErrorMessageCampaignAccount;
                    Logger.Error(errorMessage);
                    return(errorMessage);
                }
                return(string.Empty);
            }
            catch (Exception ex)
            {
                errorMessage = Resource.ErrorMessageUnableSignAccount + ": " + ex.Message;
                Logger.Error("AddTopPortfolio", ex);
            }
            return(errorMessage);
        }
 public WalletError SetPaymentWalletsBySystem(ProtectedOperationContext secCtx,
                                              PaymentSystem syst,
                                              List <UserPaymentSystem> actualPaySys,
                                              string userLogin, string walletPwrd)
 {
     if (Channel == null)
     {
         throw new Exception("WalletManagerProxy: связь не установлена");
     }
     try
     {
         return(Channel.SetPaymentWalletsBySystem(secCtx, syst, actualPaySys, userLogin, walletPwrd));
     }
     catch
     {
         RenewFactory();
         try
         {
             return(Channel.SetPaymentWalletsBySystem(secCtx, syst, actualPaySys, userLogin, walletPwrd));
         }
         catch (Exception ex2)
         {
             Logger.Error("SetPaymentWalletsBySystem() error: ", ex2);
             return(WalletError.CommonError);
         }
     }
 }
        public void ReviveChannel(ProtectedOperationContext ctx, string login, int accountId, string terminalVersion)
        {
            string address;
            var    clientCallback = GetContextParams(out address);

            UserSessionStorage.Instance.ReviveChannel(ctx, clientCallback, address, login, accountId, terminalVersion);
        }
 public override RequestStatus SendNewPendingOrderRequest(
     ProtectedOperationContext ctx,
     int requestUniqueId,
     PendingOrder order)
 {
     return(proxyTrade.proxy.SendNewPendingOrderRequest(ctx, requestUniqueId, order));
 }
Beispiel #28
0
        public void TransferToTradingAccount()
        {
            var ctx  = connectionPersistent;
            var user = ctx.PLATFORM_USER.FirstOrDefault(x => x.TRANSFER.Count > 0 && x.PLATFORM_USER_ACCOUNT.Count > 0 && x.WALLET.Currency == "USD");

            if (user == null)
            {
                Assert.Fail("В БД нет необходимых для теста данных");
            }

            var accountFirst = user.PLATFORM_USER_ACCOUNT.First().ACCOUNT1;

            var walletBalanceBefore       = user.WALLET.Balance;
            var walletTransfersBefore     = user.TRANSFER.Count();
            var walletBalanceChengeBefore = ctx.BALANCE_CHANGE.Count();
            var accountBalanceBefore      = accountFirst.Balance;

            WalletError error;

            walletManager.TransferToTradingAccount(
                ProtectedOperationContext.MakeServerSideContext(),
                user.Login, accountFirst.ID, Deposit, out error);

            Assert.AreEqual(walletTransfersBefore + 1, user.TRANSFER.Count());
            Assert.AreEqual(walletBalanceChengeBefore + 1, ctx.BALANCE_CHANGE.Count());
            Assert.IsTrue(user.WALLET.Balance.RoughCompares(walletBalanceBefore - Deposit, 0.0001m));
            Assert.IsTrue(accountFirst.Balance.RoughCompares(accountBalanceBefore + Deposit, 0.0001m));
        }
Beispiel #29
0
        public override RequestStatus SendNewOrderRequest(ProtectedOperationContext secCtx,
                                                          int requestUniqueId,
                                                          MarketOrder order,
                                                          OrderType orderType,
                                                          decimal requestedPrice,
                                                          decimal slippagePoints)
        {
            // проверить, разрешен ли вход
            decimal equity;

            if (!tradeManager.IsEnterEnabled(AccountInfo.ID, order.Symbol, order.Side, order.Volume, out equity))
            {
                return(RequestStatus.MarginOrLeverageExceeded);
            }

            order.PriceEnter = requestedPrice > 0
                                   ? (float)requestedPrice
                                   : (order.Side == 1
                                          ? quotesStorage.ReceiveValue(order.Symbol).ask
                                          : quotesStorage.ReceiveValue(order.Symbol).bid);
            order.TimeEnter = curModelTime; //quotesStorage.ReceiveValue(order.Symbol).time;
            order.State     = PositionState.Opened;
            order.ID        = nextOrderId++;
            positions.Add(order);
            return(RequestStatus.OK);
        }
        /// <summary>
        /// Выбираем пользователей, которые подписаны на портфель, и отписываем их от портфеля
        /// </summary>
        /// <param name="id">уникальный идентификатор портфеля</param>
        /// <returns></returns>
        private static bool UnsubscribeSubscribersFromPortfolio(int id)
        {
            var errorsUnsubscribe = new List <string>();

            try
            {
                using (var ctx = DatabaseContext.Instance.Make())
                {
                    var logins = ctx.USER_TOP_PORTFOLIO.Where(x => x.Portfolio == id).Select(x => x.PLATFORM_USER.Login);

                    var proxy = new TradeSharpServerTrade(EmptyTradeSharpCallbackReceiver.Instance).proxy;
                    Logger.Info("Начинаем отписывать пользователей от портфеля id = " + id);
                    foreach (var login in logins)
                    {
                        var result = proxy.UnsubscribePortfolio(ProtectedOperationContext.MakeServerSideContext(), login, false, true);
                        if (result != RequestStatus.OK)
                        {
                            errorsUnsubscribe.Add(login);
                        }
                    }
                }
                if (errorsUnsubscribe.Count > 0)
                {
                    Logger.Error(string.Format("От портфеля {0} не удалось отписать следующих пользователей: {1}", id, string.Join(Environment.NewLine, errorsUnsubscribe)));
                    return(false);
                }
                return(true);
            }
            catch (Exception ex)
            {
                Logger.Error("UnsubscribeOnPortfolio()", ex);
                return(false);
            }
        }