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; }
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>() }; }