public Model.Advisor ListDetails(string email, int advisorId) { User user = null; if (!string.IsNullOrEmpty(email)) { user = UserBusiness.GetValidUser(email); } var advisor = GetWithDetail(advisorId); var owned = (user != null && user.Id == advisor.UserId); if (advisor.Type == AdvisorType.Robo.Value || (!advisor.Detail.Enabled && !owned)) { throw new ArgumentException("Invalid advisor."); } Task <List <Buy> > purchases = null; if (user != null) { purchases = Task.Factory.StartNew(() => BuyBusiness.ListUserAdvisorPurchases(user.Id, advisorId)); } var advisorQty = Task.Factory.StartNew(() => BuyBusiness.ListAdvisorsPurchases(new int[] { advisorId })); var portfolios = PortfolioBusiness.ListWithHistory(advisorId, !owned); var portfolioQty = Task.Factory.StartNew(() => BuyBusiness.ListPortfoliosPurchases(portfolios.Select(x => x.Id))); if (user != null) { Task.WaitAll(purchases, advisorQty, portfolioQty); } else { Task.WaitAll(advisorQty, portfolioQty); } return(new Model.Advisor() { Id = advisor.Id, Name = advisor.Detail.Name, Description = advisor.Detail.Description, Owned = owned, Enabled = advisor.Detail.Enabled, PurchaseQuantity = advisorQty.Result.ContainsKey(advisor.Id) ? advisorQty.Result[advisor.Id] : 0, Portfolios = portfolios.Select(c => PortfolioBusiness.FillPortfolioModel(c, advisor, user, purchases?.Result, portfolioQty.Result)). OrderByDescending(c => c.PurchaseQuantity).ThenByDescending(c => c.ProjectionPercent).ToList() }); }
public void SetTransactionHash(string email, int buyId, string transactionHash) { var user = UserBusiness.GetValidUser(email); var buy = BuyBusiness.Get(buyId); if (buy == null || buy.UserId != user.Id || buy.ExpirationDate.HasValue) { throw new ArgumentException("Invalid purchase."); } if (buy.LastTransaction.TransactionStatus == TransactionStatus.Pending.Value && string.IsNullOrEmpty(buy.LastTransaction.TransactionHash)) { TransactionBusiness.SetTransactionHash(buy.LastTransaction, transactionHash); } else if (buy.LastTransaction.TransactionStatus == TransactionStatus.Error.Value) { Create(user.Id, buyId, transactionHash); } else if (buy.LastTransaction.TransactionStatus == TransactionStatus.Pending.Value && TransactionBusiness.TransactionCanBeConsideredLost(buy.LastTransaction) && buy.LastTransaction.TransactionHash != transactionHash.ToLower().Trim()) { try { var transaction = Web3.Web3Business.CheckTransaction(buy.LastTransaction.TransactionHash); throw new ArgumentException(transaction.BlockNumber.HasValue ? "Before transaction was processed." : "Before transaction is still pending."); } catch (DomainObjects.Web3.Web3Exception ex) { if (ex.Code == 404) { HandleLostTransaction(buy.LastTransaction, user.Id, buyId, transactionHash); } else { throw; } } } else { throw new ArgumentException("Invalid transaction status."); } }
public KeyValuePair <int, IEnumerable <Model.Portfolio> > ListRoboAdvisors(string email, int goalOptionId, int risk) { var user = UserBusiness.GetValidUser(email); var purchases = Task.Factory.StartNew(() => BuyBusiness.ListPurchases(user.Id)); var goalOption = GoalOptionsBusiness.Get(goalOptionId); var riskType = RiskType.Get(risk, goalOption.Risk); var riskPriority = RiskType.GetRiskPriority(riskType); var advisors = Data.ListRobosAvailable(); var portfolios = Task.Factory.StartNew(() => PortfolioBusiness.List(advisors.Select(c => c.Id))); Task.WaitAll(portfolios); var portfolioQty = Task.Factory.StartNew(() => BuyBusiness.ListPortfoliosPurchases(portfolios.Result.SelectMany(c => c.Value.Select(x => x.Id)))); List <Task <List <PortfolioHistory> > > histories = new List <Task <List <PortfolioHistory> > >(); foreach (DomainObjects.Portfolio.Portfolio portfolio in portfolios.Result.SelectMany(c => c.Value)) { histories.Add(Task.Factory.StartNew(() => PortfolioHistoryBusiness.ListHistory(portfolio.Id))); } Task.WaitAll(purchases, portfolioQty); Task.WaitAll(histories.ToArray()); List <Model.Portfolio> portfolioWithSameRisk = new List <Model.Portfolio>(); List <Model.Portfolio> portfolioWithLittleLowerRisk = new List <Model.Portfolio>(); List <Model.Portfolio> portfolioWithLittleHigherRisk = new List <Model.Portfolio>(); List <Model.Portfolio> portfolioWithLowerRisk = new List <Model.Portfolio>(); List <Model.Portfolio> portfolioWithHigherRisk = new List <Model.Portfolio>(); List <Model.Portfolio> portfolioWithVeryLowerRisk = new List <Model.Portfolio>(); List <Model.Portfolio> portfolioWithVeryHigherRisk = new List <Model.Portfolio>(); foreach (KeyValuePair <int, List <DomainObjects.Portfolio.Portfolio> > advisorPortfolios in portfolios.Result) { var advisor = advisors.Single(c => c.Id == advisorPortfolios.Key); advisorPortfolios.Value.ForEach(c => c.PortfolioHistory = histories.SelectMany(x => x.Result.Where(g => g.PortfolioId == c.Id)).ToList()); foreach (var r in riskPriority) { var riskFound = advisorPortfolios.Value.SingleOrDefault(c => c.Projection.RiskType == r); if (riskFound != null) { var port = PortfolioBusiness.FillPortfolioModel(riskFound, advisor, user, purchases.Result, portfolioQty.Result); var difference = riskFound.Projection.RiskType.Value - riskType.Value; if (difference == 0) { portfolioWithSameRisk.Add(port); } else if (difference == 1) { portfolioWithLittleHigherRisk.Add(port); } else if (difference == -1) { portfolioWithLittleLowerRisk.Add(port); } else if (difference == 2) { portfolioWithHigherRisk.Add(port); } else if (difference == -2) { portfolioWithLowerRisk.Add(port); } else if (difference > 2) { portfolioWithVeryHigherRisk.Add(port); } else { portfolioWithVeryLowerRisk.Add(port); } break; } } } var result = portfolioWithSameRisk.OrderByDescending(c => c.PurchaseQuantity).ThenByDescending(c => c.ProjectionPercent).ToList(); result.AddRange(portfolioWithLittleLowerRisk.OrderByDescending(c => c.PurchaseQuantity).ThenByDescending(c => c.ProjectionPercent)); result.AddRange(portfolioWithLittleHigherRisk.OrderByDescending(c => c.PurchaseQuantity).ThenByDescending(c => c.ProjectionPercent)); result.AddRange(portfolioWithLowerRisk.OrderByDescending(c => c.PurchaseQuantity).ThenByDescending(c => c.ProjectionPercent)); result.AddRange(portfolioWithHigherRisk.OrderByDescending(c => c.PurchaseQuantity).ThenByDescending(c => c.ProjectionPercent)); result.AddRange(portfolioWithVeryLowerRisk.OrderByDescending(c => c.PurchaseQuantity).ThenByDescending(c => c.ProjectionPercent)); result.AddRange(portfolioWithVeryHigherRisk.OrderByDescending(c => c.PurchaseQuantity).ThenByDescending(c => c.ProjectionPercent)); return(new KeyValuePair <int, IEnumerable <Model.Portfolio> >(riskType.Value, result)); }
public void Evaluate() { var purchases = BuyBusiness.ListPendingEscrowResult(); foreach (var purchase in purchases) { try { var history = PortfolioHistoryBusiness.ListHistory(purchase.PortfolioId); if (history.Max(c => c.Date) < purchase.ExpirationDate.Value) { continue; } var projection = ProjectionBusiness.Get(purchase.ProjectionId); var dailyEstimatedPercentage = Util.Util.ConvertMonthlyToDailyRate(projection.ProjectionValue); var estimatedPercentage = Math.Pow(1.0 + dailyEstimatedPercentage, purchase.Days) - 1.0; var startDate = purchase.ExpirationDate.Value.AddDays(-purchase.Days); if (startDate < history.Min(c => c.Date)) { startDate = history.Min(c => c.Date); } var historyOfPeriod = history.Where(c => c.Date >= startDate && c.Date <= purchase.ExpirationDate.Value); var historyResult = PortfolioHistoryBusiness.GetHistoryResult(historyOfPeriod); var performedPercentage = historyResult.Value / 100.0; decimal buyerTokenAmount = 0, ownerTokenAmount = 0; if (estimatedPercentage > performedPercentage) { buyerTokenAmount = purchase.Price; } else { ownerTokenAmount = purchase.Price; } using (var transaction = new TransactionalDapperCommand()) { var escrowResult = new EscrowResult() { BuyId = purchase.Id, CreationDate = DateTime.UtcNow, BuyerTokenResult = buyerTokenAmount, OwnerTokenResult = ownerTokenAmount }; transaction.Insert(escrowResult); var trans = TransactionBusiness.SetNew(purchase.UserId); transaction.Insert(trans); var escrowResultTrans = EscrowResultTransactionBusiness.SetNew(escrowResult.Id, trans.Id); transaction.Insert(escrowResultTrans); transaction.Commit(); } } catch (Exception ex) { Logger.LogCritical(ex, $"Error on evaluate purchase {purchase.Id}"); } } }
private TransactionStatus CheckAndProcessTransaction(Transaction buyTransaction, int buyId) { TransactionStatus status = TransactionStatus.Pending; try { var transaction = Web3.Web3Business.CheckTransaction(buyTransaction.TransactionHash, "Escrow(address,uint256)"); if (transaction.Status.HasValue) { if (transaction.Status.Value == 1) { if (transaction.EventData != null && transaction.EventData.Length == 2 && !string.IsNullOrEmpty(transaction.EventData[0]) && !string.IsNullOrEmpty(transaction.EventData[1])) { var wallet = WalletBusiness.GetByUser(buyTransaction.UserId); if (transaction.EventData[0].ToLower().Trim() != wallet.Address) { status = TransactionStatus.Fraud; } else { var purchase = BuyBusiness.GetSimple(buyId); var escrowedValue = Util.Util.ConvertBigNumber(transaction.EventData[1], 18); if (purchase.Price > escrowedValue) { status = TransactionStatus.Fraud; } else { var transactions = ListByUserAndHash(buyTransaction.UserId, buyTransaction.TransactionHash); if (transactions.Count > 1 && (transactions.Any(c => c.BuyId != buyId) || transactions.Any(c => c.Transaction.TransactionStatus != TransactionStatus.Pending.Value))) { status = TransactionStatus.Fraud; } else { status = TransactionStatus.Success; using (var trans = new TransactionalDapperCommand()) { purchase.ExpirationDate = DateTime.UtcNow.Date.AddDays(purchase.Days); trans.Update(purchase); buyTransaction.TransactionStatus = status.Value; buyTransaction.ProcessedDate = DateTime.UtcNow; trans.Update(buyTransaction); trans.Commit(); } } } } } else { status = TransactionStatus.Fraud; } } else { status = TransactionStatus.Error; } if (status != TransactionStatus.Success) { TransactionBusiness.Process(buyTransaction, status); } } } catch (DomainObjects.Web3.Web3Exception ex) { if (ex.Code == 404 && TransactionBusiness.TransactionCanBeConsideredLost(buyTransaction)) { HandleLostTransaction(buyTransaction, buyTransaction.UserId, buyId, null); } else { throw; } } return(status); }