/// <summary> /// Close a position. If not all shares are used, return /// a closed position. Modify position so that it can still be used /// as an open position with the remaining shares. /// If all shares are used, return null; /// </summary> /// <param name="position"></param> /// <param name="stock"></param> /// <param name="sharesToSell"></param> /// <returns></returns> public static Position ClosePosition(Position position, Stock stock, double sharesToSell) { position.CurrentPrice = stock.AdjustedClose; if (Math.Abs(sharesToSell - position.Shares) < Portfolio.Epsilon) { // all shares used up, just close this position and returns null // some bookkeeping position.SoldDate = stock.Date; position.Close = true; return null; } double remainingShares = position.Shares - sharesToSell; // change the position shares position.Shares = remainingShares; // now return a closed position with the shares sold return new Position { // acquired date is the same AcquiredDate = position.AcquiredDate, Shares = sharesToSell, // acquired price is also the same AcquiredPrice = position.AcquiredPrice, CurrentPrice = stock.AdjustedClose, Close = true, SoldDate = stock.Date, Name = stock.Name, Ticker = stock.Ticker }; }
public void UpdatePortfolioAfterClosingPosition(Position position) { // pay TAXES if (position.Gain > 0) { double gain = position.Gain; // offset using capital loss if (CapitalLoss > Epsilon) { // too much losses! if (gain < CapitalLoss) { CapitalLoss -= gain; gain = 0; } else { gain -= CapitalLoss; CapitalLoss = 0; } } // time to pay our taxes :( Cash -= gain * TaxToPay(position); } else { CapitalLoss -= position.Gain; } }
public double TaxToPay(Position position) { if (NoTax) { return 0; } // let's find our income int year = position.SoldDate.Year; if (!IncomeAndTaxes.ContainsKey(year)) { // not created yet so put in a yearly income IncomeAndTaxes.Add(year, new IncomeAndTax(YearlyIncome, year)); } // get the income IncomeAndTax currentYear = IncomeAndTaxes[year]; // add the gain to the income if it's positive if (position.Gain > 0) { currentYear.Income += position.Gain; } return IncomeAndTax.GetTaxRate(currentYear.Income, position.LongTerm); }
/// <summary> /// Opens a position /// </summary> /// <param name="stock"></param> public static Position OpenPosition(Stock stock, double shares) { Position position = new Position { AcquiredDate = stock.Date, Shares = shares, AcquiredPrice = stock.AdjustedClose, CurrentPrice = stock.AdjustedClose, Name = stock.Name, Ticker = stock.Ticker }; return position; }