/// <summary>
        /// Добавляем в базу новую сущность
        /// </summary>
        /// <param name="newTopPortfolio">Объект содержит значения полей для новой сущность</param>
        /// <returns></returns>
        private static TopPortfolio AddTopPortfolio(TopPortfolioItem newTopPortfolio)
        {
            try
            {
                using (var ctx = DatabaseContext.Instance.Make())
                {
                    var topPortfolio = new TOP_PORTFOLIO
                    {
                        Name             = newTopPortfolio.Name,
                        Criteria         = newTopPortfolio.Criteria,
                        ParticipantCount = newTopPortfolio.ParticipantCount,
                        DescendingOrder  = newTopPortfolio.DescendingOrder,
                        MarginValue      = newTopPortfolio.MarginValue,
                        ManagedAccount   = newTopPortfolio.ManagedAccount
                    };

                    ctx.TOP_PORTFOLIO.Add(topPortfolio);
                    ctx.SaveChanges();

                    return(LinqToEntity.DecoratePortfolio(topPortfolio));
                }
            }
            catch (Exception ex)
            {
                Logger.Error("AddTopPortfolio", ex);
                return(null);
            }
        }
示例#2
0
        public RequestStatus SubscribeUserOnPortfolio(
            TradeSharpConnection ctx,
            string subscriberLogin,
            TopPortfolio portfolio,
            decimal?maxFee,
            AutoTradeSettings tradeAutoSettings)
        {
            var user = ctx.PLATFORM_USER.FirstOrDefault(u => u.Login == subscriberLogin);

            if (user == null)
            {
                return(RequestStatus.Unauthorized);
            }

            TOP_PORTFOLIO targetPortfolio = null;

            if (portfolio.Id > 0)
            {
                targetPortfolio = ctx.TOP_PORTFOLIO.FirstOrDefault(p => p.Id == portfolio.Id);
            }
            if (targetPortfolio != null)
            {
                portfolio.ManagedAccount = targetPortfolio.ManagedAccount;
            }

            // если портфель - пользовательский - сохранить его
            // для пользователя или обновить его имеющийся портфель
            if (!portfolio.IsCompanyPortfolio)
            {
                Logger.Info("SubscribeOnPortfolio() - user portfolio");
                try
                {
                    var existPortfolio = ctx.TOP_PORTFOLIO.FirstOrDefault(p => p.OwnerUser == user.ID);
                    if (existPortfolio != null)
                    {
                        if (!LinqToEntity.DecoratePortfolio(existPortfolio).AreSame(portfolio))
                        {
                            // удалить старый портфель пользователя
                            ctx.TOP_PORTFOLIO.Remove(existPortfolio);
                            existPortfolio = null;
                        }
                        else
                        {
                            targetPortfolio = existPortfolio;
                        }
                    }
                    // создать портфель пользователя
                    if (existPortfolio == null)
                    {
                        targetPortfolio                = LinqToEntity.UndecoratePortfolio(portfolio);
                        targetPortfolio.OwnerUser      = user.ID;
                        targetPortfolio.ManagedAccount = null;
                        ctx.TOP_PORTFOLIO.Add(targetPortfolio);
                        ctx.SaveChanges();
                    }
                }
                catch (DbEntityValidationException dbEx)
                {
                    Logger.Error("SubscribeUserOnPortfolio - ошибка сохранения портфеля");
                    foreach (var validationErrors in dbEx.EntityValidationErrors)
                    {
                        foreach (var validationError in validationErrors.ValidationErrors)
                        {
                            Logger.ErrorFormat("Свойство: {0}, ошибка: {1}",
                                               validationError.PropertyName, validationError.ErrorMessage);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error("Ошибка в SubscribeOnPortfolio() - обновление портфеля", ex);
                    return(RequestStatus.ServerError);
                }
            }
            else
            {// портфель компании
                Logger.Info("SubscribeOnPortfolio() - company portfolio");
                if (targetPortfolio == null)
                {
                    Logger.Error("Пользователь запросил несуществующий портфель компании " + portfolio.Id);
                    return(RequestStatus.ServerError);
                }
            }

            // очистить подписки пользователя на портфели
            // и привязать его к целевому портфелю
            //Logger.Info("SubscribeOnPortfolio() - removing bindings");
            var oldBinding = ctx.USER_TOP_PORTFOLIO.FirstOrDefault(u => u.User == user.ID);

            // "посмотреть" настройки портфельной торговли в имеющейся подписке
            if (tradeAutoSettings == null)
            {
                if (oldBinding == null)
                {
                    Logger.ErrorFormat("Подписка пользователя {0} на портфель {1} - нет данных по автоматической торговле",
                                       user.Login, portfolio.Id > 0 ? portfolio.Id.ToString() : portfolio.Name);
                    return(RequestStatus.BadRequest);
                }
                tradeAutoSettings = new AutoTradeSettings
                {
                    FixedVolume          = oldBinding.FixedVolume,
                    HedgingOrdersEnabled = oldBinding.HedgingOrdersEnabled,
                    MaxLeverage          = oldBinding.MaxLeverage,
                    MaxVolume            = oldBinding.MaxVolume,
                    MinVolume            = oldBinding.MinVolume,
                    PercentLeverage      = oldBinding.PercentLeverage ?? 100,
                    StepVolume           = oldBinding.StepVolume,
                    TargetAccount        = oldBinding.TargetAccount,
                    TradeAuto            = oldBinding.AutoTrade ?? false,
                    VolumeRound          = (VolumeRoundType?)oldBinding.VolumeRound
                };
            }

            if (oldBinding != null)
            {
                ctx.USER_TOP_PORTFOLIO.Remove(oldBinding);
            }

            //Logger.Info("SubscribeOnPortfolio() - adding binding");
            ctx.USER_TOP_PORTFOLIO.Add(new USER_TOP_PORTFOLIO
            {
                User                 = user.ID,
                Portfolio            = targetPortfolio.Id,
                MaxFee               = maxFee,
                AutoTrade            = tradeAutoSettings.TradeAuto,
                MaxLeverage          = tradeAutoSettings.MaxLeverage,
                PercentLeverage      = tradeAutoSettings.PercentLeverage,
                HedgingOrdersEnabled = tradeAutoSettings.HedgingOrdersEnabled,
                FixedVolume          = tradeAutoSettings.FixedVolume,
                MinVolume            = tradeAutoSettings.MinVolume,
                MaxVolume            = tradeAutoSettings.MaxVolume,
                VolumeRound          = (int?)tradeAutoSettings.VolumeRound,
                StepVolume           = tradeAutoSettings.StepVolume,
                TargetAccount        = tradeAutoSettings.TargetAccount
            });
            ctx.SaveChanges();
            //Logger.Info("SubscribeOnPortfolio() - changes are saved");

            // найти трейдеров, удовлетворяющих критерию
            List <PerformerStat> performers;

            try
            {
                try
                {
                    performers = TradeSharpAccountStatistics.Instance.proxy.GetAllPerformersWithCriteria(true,
                                                                                                         targetPortfolio.Criteria, targetPortfolio.ParticipantCount,
                                                                                                         !targetPortfolio.DescendingOrder, (float?)targetPortfolio.MarginValue, 0);
                }
                catch (Exception ex)
                {
                    Logger.Error(
                        "Ошибка в SubscribeOnPortfolio() - получение перформеров (" + targetPortfolio.Criteria + ")",
                        ex);
                    return(RequestStatus.ServerError);
                }

                if (performers == null)
                {
                    Logger.Error("Ошибка в SubscribeOnPortfolio() - список перформеров не получен (" + targetPortfolio.Criteria + ")");
                    return(RequestStatus.ServerError);
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка в SubscribeOnPortfolio() - подписка", ex);
                return(RequestStatus.ServerError);
            }

            // сравнить полученный список с текущими подписками заказчика ("инвестора")
            // сформировать список для "отписки" и список для подписки
            var performerAcs = performers.Select(p => p.Account).ToList();
            var subsToRemove = ctx.SUBSCRIPTION.Where(s => s.User == user.ID &&
                                                      s.SERVICE1.ServiceType == (int)PaidServiceType.Signals &&
                                                      !performerAcs.Contains(s.SERVICE1.AccountId ?? 0)).ToList();

            foreach (var sub in subsToRemove)
            {
                WalletError error;
                SubscribeOnService(ctx, user.ID, sub.Service, false, true, tradeAutoSettings, out error);
                if (error != WalletError.OK)
                {
                    Logger.ErrorFormat("Portfolio - unsubscribe user {0} from srv {1}: error {2}",
                                       user.ID, sub.Service, error);
                }
            }

            // новоподписавшиеся
            foreach (var pf in performers)
            {
                WalletError error;
                SubscribeOnService(ctx, user.ID, pf.Service, true, false, tradeAutoSettings, out error);
                if (error != WalletError.OK)
                {
                    Logger.DebugFormat("Подписка SubscribeOnPortfolio({0}), сигн. {1}: {2}",
                                       subscriberLogin, pf.Service, error);
                }
            }
            return(RequestStatus.OK);
        }