public static PaidService DecoratePaidService(SERVICE srv)
 {
     return(new PaidService
     {
         User = srv.User,
         Comment = srv.Comment,
         FixedPrice = srv.FixedPrice,
         Id = srv.ID,
         ServiceType = (PaidServiceType)srv.ServiceType,
         Currency = srv.Currency,
         AccountId = srv.AccountId,
         serviceRates = new List <PaidServiceRate>()
     });
 }
 private PaidService GetPaidServiceProgressiveFeeScaleDetail(TradeSharpConnection ctx, SERVICE srv)
 {
     var fees = ctx.SERVICE_RATE.Where(r => r.Service == srv.ID).OrderBy(r => r.UserBalance).ToList();
         if (fees.Count == 0) return null;
         var service = LinqToEntity.DecoratePaidService(srv);
         service.serviceRates = fees.Select(f => new PaidServiceRate
             {
                 Amount = f.Amount,
                 RateType = PaidServiceRate.ServiceRateType.Percent,
                 UserBalance = f.UserBalance
             }).ToList().ToList();
         return service;
 }
        /// <summary>
        /// возвращает - соклько раз была списана комиссия
        /// </summary>
        public int ReCalculateAccountShares(TradeSharpConnection ctx, SERVICE srv)
        {
            var feeTakenCount = 0;
            try
            {
                PaidService serviceWithFeeScale = null;

                // дольки
                var shares =
                    ctx.ACCOUNT_SHARE.Where(s => s.Account == srv.AccountId && s.ShareOwner != srv.User).ToList();
                if (shares.Count == 0) return feeTakenCount;

                var ownerShare =
                    ctx.ACCOUNT_SHARE.FirstOrDefault(s => s.Account == srv.AccountId && s.ShareOwner == srv.User);
                if (ownerShare == null)
                {
                    Logger.ErrorFormat(
                        "ReCalculateAccountShares(service={0}, account={1}, owner={2}) - доля владельца не найдена",
                        srv.ID, srv.AccountId, srv.User);
                    return feeTakenCount;
                }

                var account = ctx.ACCOUNT.First(a => a.ID == srv.AccountId);

                // получить актуальный баланс (средства) счета
                var positions =
                    ctx.POSITION.Where(p => p.AccountID == srv.AccountId && p.State == (int) PositionState.Opened)
                       .ToList().Select(LinqToEntity.DecorateOrder).ToList();

                var quotes = QuoteStorage.Instance.ReceiveAllData();

                bool noQuoteError;
                var profit = DalSpot.Instance.CalculateOpenedPositionsCurrentResult(positions,
                                                                                    quotes, account.Currency,
                                                                                    out noQuoteError);
                var equity = account.Balance + (decimal) profit;
                if (noQuoteError)
                {
                    Logger.Error("Ошибка в ReCalculateAccountShares - нет котировки для пересчета одного из тикеров (" +
                                 string.Join(", ", positions.Select(p => p.Symbol).Distinct()));
                    return feeTakenCount;
                }

                // пересчитать долю каждого пайщика
                var ownersMoney = equity * ownerShare.Share / 100M;
                serviceWithFeeScale = GetPaidServiceProgressiveFeeScaleDetail(ctx, srv);

                foreach (var share in shares)
                {
                    bool feeWasTaken;
                    var record = CalculateAccountShare(ctx, share, ownerShare,
                                                       ref ownersMoney, equity, serviceWithFeeScale, out feeWasTaken);
                    ctx.ACCOUNT_SHARE_HISTORY.Add(record);
                    if (feeWasTaken)
                        feeTakenCount++;
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка в ReCalculateAccountShares", ex);
            }

            return feeTakenCount;
        }
        private void MakeTestData()
        {
            paidService = conn.SERVICE.First(s => s.Currency == "USD");
            srvOwner = paidService.PLATFORM_USER;
            srvSubscriber = conn.PLATFORM_USER.First(u => u.WALLET.Currency == "USD" && u.ID != srvOwner.ID);
            // аккаунт с дольками и открытыми позами
            accountShared = conn.ACCOUNT.First(a => a.POSITION.Count > 1 && a.POSITION.Count < 200);
            accountSharedOwner = (from pa in conn.PLATFORM_USER_ACCOUNT
                                  join u in conn.PLATFORM_USER on pa.PlatformUser equals u.ID
                                  where pa.Account == accountShared.ID
                                  select u).First();
            // добавить ПАММ-сервис
            conn.SERVICE.Add(new SERVICE
                {
                    Currency = "USD",
                    ServiceType = (int) PaidServiceType.PAMM,
                    AccountId = accountShared.ID,
                    User = accountSharedOwner.ID,
                    Comment = "PAMMMmm"
                });

            // добавить дольки
            var oneMoreUser = conn.PLATFORM_USER.First(u => u.ID != accountSharedOwner.ID);
            conn.ACCOUNT_SHARE.Add(new ACCOUNT_SHARE
                {
                    Account = accountShared.ID,
                    Share = 55,
                    ShareOwner = accountSharedOwner.ID
                });
            conn.ACCOUNT_SHARE.Add(new ACCOUNT_SHARE
            {
                Account = accountShared.ID,
                Share = 45,
                ShareOwner = oneMoreUser.ID
            });
            conn.SaveChanges();
        }
        public void Setup()
        {
            // подыграть за торговый контракт
            SetupFakeServer();

            // инициализировать словари (прежде всего - словарь тикеров)
            TradeSharpDictionary.Initialize(MoqTradeSharpDictionary.Mock);

            connection = TradeSharpConnectionPersistent.InitializeTradeSharpConnection();

            // пользователь - владелец тестового сервиса
            var ownerUser = new PLATFORM_USER
                {
                    Email = "*****@*****.**",
                    Login = "******",
                    Title = "Vafel",
                    RoleMask = 0,
                    Password = "******",
                    RegistrationDate = DateTime.Now
                };
            connection.PLATFORM_USER.Add(ownerUser);
            connection.SaveChanges();

            // добавить категорию сигналов
            var srv = new SERVICE
                {
                    FixedPrice = 0,
                    Currency = "USD",
                    User = ownerUser.ID
                };
            connection.SERVICE.Add(srv);
            connection.SaveChanges();
            serviceId = srv.ID;

            // добавить пользователя
            var user = new PLATFORM_USER
                {
                    Email = "*****@*****.**",
                    Login = "******",
                    Password = "******",
                    Title = "test",
                    RegistrationDate = DateTime.Now
                };
            connection.PLATFORM_USER.Add(user);
            connection.SaveChanges();
            testUserId = user.ID;

            // добавить счет и сделок
            var group = connection.ACCOUNT_GROUP.First(g => !g.IsReal);
            var account = new ACCOUNT
                {
                    AccountGroup = group.Code,
                    Currency = AccountCurrency,
                    Balance = 30000
                };
            connection.ACCOUNT.Add(account);
            connection.SaveChanges();
            testAccountId = account.ID;

            // назначить пользователя владельцем счета
            connection.PLATFORM_USER_ACCOUNT.Add(new PLATFORM_USER_ACCOUNT
                {
                    Account = testAccountId,
                    PlatformUser = testUserId,
                    RightsMask = (int) AccountRights.Управление
                });

            // подписать счет на сигнал
            connection.SUBSCRIPTION.Add(new SUBSCRIPTION
                {
                    User = testUserId,
                    Service = serviceId,
                    RenewAuto = true,
                    TimeEnd = DateTime.Now.Date.AddDays(1)
                });
            connection.SUBSCRIPTION_SIGNAL.Add(new SUBSCRIPTION_SIGNAL
            {
                User = testUserId,
                Service = serviceId,
                AutoTrade = true,
                PercentLeverage = 120,
                MinVolume = 10000,
                TargetAccount = testAccountId
            });
            connection.SaveChanges();

            // позиции
            MakeOrdersForTest();
            foreach (var order in ordersForTest)
            {
                var pos = LinqToEntity.UndecorateOpenedPosition(order);
                connection.POSITION.Add(pos);
            }
            connection.SaveChanges();

            // прописать срез котировок
            var nowTime = DateTime.Now;
            Contract.Util.BL.QuoteStorage.Instance.UpdateValues(new []
                {
                    "EURUSD", "GBPUSD", "USDJPY", "EURGBP"
                },
                new []
                    {
                        new QuoteData(1.3820f, 1.3822f, nowTime),
                        new QuoteData(1.5350f, 1.5354f, nowTime),
                        new QuoteData(90.81f, 90.83f, nowTime),
                        new QuoteData(1.1107f, 1.1112f, nowTime)
                    }
                );
        }
 //, PLATFORM_USER usr)
 /// <summary>
 /// по средствам клиента определить сумму по прогрессивной шкале
 /// </summary>
 private decimal GetFeeByUserBalance(TradeSharpConnection ctx, SERVICE srv)
 {
     var rate = ctx.SERVICE_RATE.FirstOrDefault(r => r.Service == srv.ID);
     return rate == null ? 0 : rate.Amount;
 }
        public WalletError ChargeFeeOnSubscription(TradeSharpConnection ctx, SERVICE service, int usr, bool renewSubscription)
        {
            try
            {
                // создать платеж с кошелька usr на кошелек владельца сервиса (service)
                if (service.FixedPrice == 0)
                    return WalletError.OK; // все на шарку!
                var price = service.FixedPrice > 0
                                ? service.FixedPrice
                                : GetFeeByUserBalance(ctx, service);
                if (price == 0) return WalletError.OK;

                var usrWallet = ctx.WALLET.FirstOrDefault(w => w.User == usr);
                if (usrWallet == null)
                {
                    Logger.Error("ChargeFeeOnSubscription(usrId=" + usr + ") - wallet is not found");
                    return WalletError.ServerError;
                }

                if (HasUserPaidTheService(ctx, service, usr))
                    return WalletError.OK;

                // посчитать в валюте пользователя
                var usrAmount = price;
                if (usrWallet.Currency != service.Currency)
                {
                    string strError;
                    var targetAmount = DalSpot.Instance.ConvertSourceCurrencyToTargetCurrency(usrWallet.Currency, service.Currency,
                                                                           (double)usrAmount,
                                                                           QuoteStorage.Instance.ReceiveAllData(),
                                                                           out strError);
                    if (!targetAmount.HasValue)
                    {
                        Logger.ErrorFormat("ChargeFeeOnSubscription(usrId={0}) - currency rate is not found ({1}/{2})",
                            usr, usrWallet.Currency, service.Currency);
                        return WalletError.CurrencyExchangeFailed;
                    }
                    usrAmount = targetAmount.Value;
                }

                // если объем превышает возможности пользователя...
                if (usrWallet.Balance < usrAmount)
                {
                    Logger.InfoFormat("ChargeFeeOnSubscription(usrId={0}) - not enough money ({1}, needed {2})",
                            usr, usrAmount, usrWallet.Balance);
                    return WalletError.InsufficientFunds;
                }

                usrWallet.Balance -= usrAmount;
                var trans = ctx.TRANSFER.Add(new TRANSFER
                {
                    Amount = usrAmount,
                    TargetAmount = price,
                    Comment = "Fee on srv " + service.ID,
                    RefWallet = service.User,
                    User = usr,
                    ValueDate = DateTime.Now,
                    Subscription = service.ID
                });
                Logger.InfoFormat("Добавляется трансфер: usr={0}, comment={1}",
                    usr, trans.Comment);

                // добавить денег владельцу
                ctx.TRANSFER.Add(new TRANSFER
                {
                    Amount = price,
                    TargetAmount = usrAmount,
                    Comment = "Paid for srv " + service.ID,
                    RefWallet = usr,
                    User = service.User,
                    ValueDate = DateTime.Now,
                    Subscription = service.ID
                });
                var ownerWallet = ctx.WALLET.First(w => w.User == service.User);
                ownerWallet.Balance += price;

                // обновить подписку
                if (renewSubscription)
                {
                    var sub = ctx.SUBSCRIPTION.FirstOrDefault(s => s.Service == service.ID);
                    if (sub != null && sub.RenewAuto)
                    {
                        sub.TimeStarted = DateTime.Now.Date;
                        sub.TimeEnd = sub.TimeStarted.AddDays(1);
                    }
                }

                Logger.InfoFormat("ChargeFeeOnSubscription() - сохранение");
                ctx.SaveChanges();
            }
            catch (Exception ex)
            {
                Logger.Error("Error in ChargeFeeOnSubscription()", ex);
                return WalletError.ServerError;
            }
            return WalletError.OK;
        }
 public bool HasUserPaidTheService(TradeSharpConnection ctx, SERVICE service, int usr)
 {
     var nowDate = DateTime.Now.Date;
     // проверить - совершался ли платеж за подключение к подписке в ближайшие N минут?
     // если да - не снимать денег
     var hasTodayTransfers = ctx.TRANSFER.Any(t => t.User == usr &&
         EntityFunctions.TruncateTime(t.ValueDate) == nowDate && t.Subscription == service.ID);
     return hasTodayTransfers;
 }
        private RequestStatus FindPAMMServiceWithOwner()
        {
            owner = (from pa in ctx.PLATFORM_USER_ACCOUNT
                         join u in ctx.PLATFORM_USER on pa.PlatformUser equals u.ID
                         where pa.Account == accountId && pa.RightsMask == (int)AccountRights.Управление
                         select u).FirstOrDefault();
            if (owner == null)
            {
                Logger.ErrorFormat("InvestOrWithdrawFromPamm(acc={0}) - владелец счета не найден", accountId);
                return RequestStatus.IncorrectData;
            }

            // найти ПАММ-сервис для целевого акаунта
            service = (from srv in ctx.SERVICE
                           where srv.AccountId == accountId &&
                                 srv.User == owner.ID && srv.ServiceType == (int)PaidServiceType.PAMM
                           select srv).FirstOrDefault();
            if (service == null)
            {
                Logger.ErrorFormat("InvestOrWithdrawFromPamm(acc={0}) - счет не указан как ПАММ", accountId);
                return RequestStatus.BadRequest;
            }

            return RequestStatus.OK;
        }
Beispiel #10
0
 public static PaidService DecoratePaidService(SERVICE srv)
 {
     return new PaidService
         {
             User = srv.User,
             Comment = srv.Comment,
             FixedPrice = srv.FixedPrice,
             Id = srv.ID,
             ServiceType = (PaidServiceType)srv.ServiceType,
             Currency = srv.Currency,
             AccountId = srv.AccountId,
             serviceRates = new List<PaidServiceRate>()
         };
 }