コード例 #1
0
        public ActionResult AddSell(AddSellTransactionVm addSellTransactionVm)
        {
            if (ModelState.IsValid)
            {
                var brokerageAccount =
                    BrokerageAccountService.GetBrokerageAccount(addSellTransactionVm.BrokerageAccountId);
                // Did we find the requested account and does it belong to the active user?
                if (brokerageAccount == null || brokerageAccount.UserId != ActiveUserService.GetUserId())
                {
                    this.FlashError("Please ensure the requested brokerage account is setup under the active user and try again.", "Index", "BrokerageAccounts");
                    return RedirectToAction("Index", "BrokerageAccounts", new { area = "" });
                }

                int sellTransactionId = SellTransactionService.CreateSellTransaction(addSellTransactionVm);

                if (sellTransactionId > 0)
                {
                    this.FlashSuccess("Successfully created the sell transaction.", "SellDetails", "StockTransactions");
                    return RedirectToAction("SellDetails", "StockTransactions", new { area = "", id = sellTransactionId });
                }
                this.FlashError("Could not create the sell transaction. Please try again.", "AddSell", "StockTransactions");
            }

            foreach (var transactionMatch in addSellTransactionVm.MatchingPurchaseTransactions)
            {
                transactionMatch.PurchaseTransaction =
                    PurchaseTransactionService.GetPurchaseTransaction(transactionMatch.PurchaseTransactionId);
            }

            var brokerageAccountList = BrokerageAccountService.GetBrokerageAccountListForActiveUser();

            // Does the active user have any brokerage accounts setup?
            if (!brokerageAccountList.Any())
            {
                this.FlashError("Please ensure a brokerage account is setup and try again.", "Index", "BrokerageAccounts");
                return RedirectToAction("Index", "BrokerageAccounts", new { area = "" });
            }

            ViewBag.BrokerageAccountId = new SelectList(brokerageAccountList, "Id", "Title");

            var stockList = PurchaseTransactionService.GetStocksWithOpenPositionsForBrokerageAccount(addSellTransactionVm.BrokerageAccountId);
            ViewBag.SecurityId = new SelectList(stockList, "Id", "Title", addSellTransactionVm.SecurityId);

            return View(addSellTransactionVm);
        }
コード例 #2
0
        public int CreateSellTransaction(AddSellTransactionVm addSellTransactionVm)
        {
            var shareQuantitySold = addSellTransactionVm.ShareQuantity;
            var sellUnitPrice = addSellTransactionVm.UnitPrice;
            var sellCommission = addSellTransactionVm.Commission;
            var sellDate = addSellTransactionVm.TransactionDate;

            decimal totalNetProfit = 0;
            decimal longTermPositionsClosed = 0;
            decimal longTermPositionsNetProfit = 0;
            decimal shortTermPositionsClosed = 0;
            decimal shortTermPositionsNetProfit = 0;

            var closingTransactionMatches = new List<ClosingTransactionMatch>();

            foreach (var purchaseTransaction in addSellTransactionVm.MatchingPurchaseTransactions)
            {
                if (purchaseTransaction.ShareQuantity > 0)
                {
                    var purchaseTransactionDetails =
                        PurchaseTransactionRepository.GetPurchaseTransaction(purchaseTransaction.PurchaseTransactionId);

                    // Requesting to close out more shares than the position has remaining open?
                    if (purchaseTransaction.ShareQuantity > purchaseTransactionDetails.RemainingShares)
                    {
                        return -1;
                    }

                    var capitalGain = (purchaseTransaction.ShareQuantity*sellUnitPrice) // Individual Match Sell Value
                                      - (purchaseTransaction.ShareQuantity/shareQuantitySold)*sellCommission // Individual Match Sell Commission
                                      - (purchaseTransaction.ShareQuantity*purchaseTransactionDetails.UnitPrice) // Individual Match Purchase Value
                                      - (purchaseTransaction.ShareQuantity/purchaseTransactionDetails.ShareQuantity)* purchaseTransactionDetails.Commission; // Individual Match Purchase Commission

                    totalNetProfit += capitalGain;

                    if ((sellDate - purchaseTransactionDetails.TransactionDate).TotalDays > 365)
                    {
                        // Long Term Capital Gain - Greater than 1 year
                        longTermPositionsClosed += purchaseTransaction.ShareQuantity;
                        longTermPositionsNetProfit += capitalGain;
                    }
                    else
                    {
                        // Short Term Capital Gain - Less than 1 year
                        shortTermPositionsClosed += purchaseTransaction.ShareQuantity;
                        shortTermPositionsNetProfit += capitalGain;
                    }

                    purchaseTransactionDetails.ClosedShares += purchaseTransaction.ShareQuantity;
                    purchaseTransactionDetails.RemainingShares -= purchaseTransaction.ShareQuantity;
                    if (purchaseTransactionDetails.RemainingShares == 0)
                    {
                        purchaseTransactionDetails.PositionClosedStatus = true;
                    }

                    PurchaseTransactionRepository.UpdatePurchaseTransaction(purchaseTransactionDetails);

                    var closingTransactionMatch = new ClosingTransactionMatch
                                                      {
                                                          MatchingShareCount = purchaseTransaction.ShareQuantity,
                                                          PurchaseTransactionId = purchaseTransactionDetails.Id,
                                                          TotalNetProfit = capitalGain
                                                      };
                    closingTransactionMatches.Add(closingTransactionMatch);
                }
            }

            var sellTransaction = new SellTransaction
                                        {
                                            BrokerageAccountId = addSellTransactionVm.BrokerageAccountId,
                                            UnitPrice = sellUnitPrice,
                                            ShareQuantity = shareQuantitySold,
                                            SecurityId = addSellTransactionVm.SecurityId,
                                            Commission = sellCommission,
                                            TransactionDate = sellDate,
                                            TotalNetProfit = totalNetProfit,
                                            Profitable = (totalNetProfit >= 0),
                                            LongTermPositionsClosed = longTermPositionsClosed,
                                            LongTermPositionsNetProfit = longTermPositionsNetProfit,
                                            ShortTermPositionsClosed = shortTermPositionsClosed,
                                            ShortTermPositionsNetProfit = shortTermPositionsNetProfit,
                                            ClosingTransactionMatches = closingTransactionMatches
                                        };

            DbOperationStatus opStatus = SellTransactionRepository.InsertSellTransaction(sellTransaction);
            if (opStatus.OperationSuccessStatus)
            {
                return opStatus.AffectedIndices.First();
            }
            return -1;
        }