private void AddTradeEvent(TransactionsBO transaction) { // I need to ignore/prevent trades where quantity = 0 decimal quantityRef = transaction.Quantity; // a reference to the transaction quantity so it doesn't get manipulated TaxLotsOpen lot = new TaxLotsOpen(transaction.TradeDate, quantityRef, transaction.Price); if (_netQuantity == 0) { _isLong = (quantityRef >= 0); } // this means the trade is not in the same direction as the quantity else if (quantityRef * _netQuantity < 0) { while (_openLots.Count > 0 && quantityRef != 0) { decimal pnl; int multiplier = (_isLong) ? 1 : -1; // this is important because it allows me to calculate pnl taking direction into account. if (Math.Abs(quantityRef) >= Math.Abs(_openLots.Peek().quantity)) { pnl = Math.Abs(_openLots.Peek().quantity) * (transaction.Price - _openLots.Peek().price) * multiplier; quantityRef += _openLots.Peek().quantity; _openLots.Dequeue(); } else { pnl = Math.Abs(quantityRef) * (transaction.Price - _openLots.Peek().price) * multiplier; _openLots.Peek().quantity += quantityRef; quantityRef = 0; } _realisedPnL += pnl; } if (quantityRef != 0) { lot.quantity = quantityRef; } } if (quantityRef != 0) { _openLots.Enqueue(lot); } UpdatePosition(transaction); Debug.Assert(_netQuantity == _openLots.Sum(s => s.quantity)); }
private void AddTradeEvent(TransactionsBO transaction) { // I need to ignore/prevent trades where quantity = 0 decimal quantityRef = transaction.Quantity; // a reference to the transaction quantity so it doesn't get manipulated TaxLotsOpen lot = new TaxLotsOpen(transaction.TradeDate, quantityRef, transaction.Price); if (_netQuantity == 0) { _isLong = (quantityRef >= 0); } // this means the trade is not in the same direction as the quantity else if (quantityRef * _netQuantity < 0) { while (_openLots.Count > 0 && quantityRef != 0) { if (Math.Abs(quantityRef) >= Math.Abs(_openLots.Peek().quantity)) { quantityRef += _openLots.Peek().quantity; _openLots.Dequeue(); } else { _openLots.Peek().quantity += quantityRef; quantityRef = 0; } } if (quantityRef != 0) { lot.quantity = quantityRef; } } if (quantityRef != 0) { _openLots.Enqueue(lot); } UpdatePosition(transaction); Debug.Assert(_netQuantity == _openLots.Sum(s => s.quantity)); }
private void AddCorporateActionEvent(TransactionsBO transaction) { if (transaction.TransactionType.TypeName == "Dividends") { if (transaction.Quantity == 0) { // cash dividend _realisedPnL += transaction.TradeAmount; } else { // stock dividend TaxLotsOpen dividendLot = new TaxLotsOpen(transaction.TradeDate, transaction.Quantity, transaction.Price); _openLots.Enqueue(dividendLot); UpdatePosition(transaction); } } else { throw new NotImplementedException(); } Debug.Assert(_netQuantity == _openLots.Sum(s => s.quantity)); }