/// <summary> /// /// </summary> /// <param name="o"></param> /// <returns>Capital usage by this order.</returns> public decimal AddOrder(Order o) { Open = true; if (!Positions.ContainsKey(o.Instrument.ID)) { Positions.Add(o.Instrument.ID, new Position(o.Instrument)); } decimal orderCapUsage = Positions[o.Instrument.ID].AddOrder(o); _ordersRemaining--; if (o.CurrencyID > 1) { decimal quantity = -o.Quantity * o.Multiplier * o.Price; var ft = new FXTransaction { FXCurrency = o.Currency, FXCurrencyID = o.CurrencyID, Quantity = quantity, Proceeds = quantity * o.FXRateToBase, Cost = -quantity * o.FXRateToBase, DateTime = o.TradeDate }; AddFXTransaction(ft); } return(orderCapUsage); }
public void AddCashTransaction(CashTransaction ct) { if (!ct.InstrumentID.HasValue) { return; } if (Positions.ContainsKey(ct.Instrument.ID)) { Positions[ct.Instrument.ID].AddCashTransaction(ct); } if (ct.CurrencyID > 1) { var ft = new FXTransaction { FXCurrency = ct.Currency, FXCurrencyID = ct.CurrencyID, Quantity = ct.Amount, Proceeds = ct.Amount * ct.FXRateToBase, Cost = -ct.Amount * ct.FXRateToBase, DateTime = ct.TransactionDate }; AddFXTransaction(ft); } }
public void ProfitCorrectlyCalculatedAfterReversing() { var pos = new CurrencyPosition(_currency); decimal fxRate = 1.35m; int quantity = 1000; var transaction1 = new FXTransaction { Quantity = quantity, Proceeds = fxRate * quantity, Cost = -fxRate * quantity, FXCurrency = _currency }; pos.AddFXTransaction(transaction1); decimal newFxRate = 1.36m; int newQuantity = -2000; var transaction2 = new FXTransaction { Quantity = newQuantity, Proceeds = newFxRate * newQuantity, Cost = -newFxRate * newQuantity, FXCurrency = _currency }; pos.AddFXTransaction(transaction2); Assert.AreEqual(quantity * (newFxRate - fxRate), pos.RealizedPnL); pos.Update(newFxRate); Assert.AreEqual(quantity * (newFxRate - fxRate), pos.TotalPnL); }
public void AddCashTransaction(CashTransaction ct) { Open = true; if (ct.InstrumentID.HasValue) { if (Positions.ContainsKey(ct.Instrument.ID)) { Positions[ct.Instrument.ID].AddCashTransaction(ct); } } else { //InstrumentID is null. This happens frequently //as many cash transactions are not related to a particular instrument Positions[NullInstrumentId].AddCashTransaction(ct); } if (ct.CurrencyID > 1) { var ft = new FXTransaction { FXCurrency = ct.Currency, FXCurrencyID = ct.CurrencyID, Quantity = ct.Amount, Proceeds = ct.Amount * ct.FXRateToBase, Cost = -ct.Amount * ct.FXRateToBase, DateTime = ct.TransactionDate }; AddFXTransaction(ft); } _cashTransactionsRemaining--; }
public void AddFXTransaction(Trade trade, FXTransaction fxt) { if (trade == null) { throw new ArgumentNullException("trade"); } if (fxt == null) { throw new ArgumentNullException("fxt"); } var oldTrade = fxt.Trade; if (oldTrade != null && trade.ID == oldTrade.ID) { //no change return; } //remove the ct from its current trade RemoveFXTransaction(oldTrade, fxt); //and then add it to the new one if (trade.FXTransactions == null) { trade.FXTransactions = new List <FXTransaction>(); } trade.FXTransactions.Add(fxt); fxt.Trade = trade; fxt.TradeID = trade.ID; //finally update the stats of the new trade UpdateStats(fxt.Trade); }
public async Task AddFXTransaction(Trade trade, FXTransaction fxt) { if (trade == null) { throw new ArgumentNullException(nameof(trade)); } if (fxt == null) { throw new ArgumentNullException(nameof(fxt)); } var oldTrade = fxt.Trade; if (oldTrade != null && trade.ID == oldTrade.ID) { //no change return; } //remove the ct from its current trade await RemoveFXTransaction(oldTrade, fxt).ConfigureAwait(true); //and then add it to the new one if (trade.FXTransactions == null) { trade.FXTransactions = new List <FXTransaction>(); } trade.FXTransactions.Add(fxt); fxt.Trade = trade; fxt.TradeID = trade.ID; //finally update the stats of the new trade await UpdateStats(fxt.Trade).ConfigureAwait(true); }
public void AddFXTransaction(FXTransaction ft) { Open = true; if (!CurrencyPositions.ContainsKey(ft.FXCurrency.ID)) { CurrencyPositions.Add(ft.FXCurrency.ID, new CurrencyPosition(ft.FXCurrency)); } CurrencyPositions[ft.FXCurrency.ID].AddFXTransaction(ft); }
public void RemoveFXTransaction(Trade trade, FXTransaction fxt) { if (trade == null || trade.FXTransactions == null || !trade.FXTransactions.Contains(fxt)) { return; } trade.FXTransactions.Remove(fxt); fxt.Trade = null; fxt.TradeID = null; UpdateStats(trade); }
public async Task RemoveFXTransaction(Trade trade, FXTransaction fxt) { if (trade?.FXTransactions == null || !trade.FXTransactions.Contains(fxt)) { return; } trade.FXTransactions.Remove(fxt); fxt.Trade = null; fxt.TradeID = null; await UpdateStats(trade); }
public void AddFXTransaction(FXTransaction transaction) { if (transaction.FXCurrency.ID != Currency.ID) { throw new Exception("Incorrect currency used."); } Transactions.Add(transaction); decimal fxRate = transaction.Proceeds / transaction.Quantity; //profit/loss if ((transaction.Quantity < 0 && Quantity > 0) || (transaction.Quantity > 0 && Quantity < 0)) { decimal profit = -Math.Min(Math.Abs(transaction.Quantity), Math.Abs(Quantity)) * (fxRate - CostBasis) * Math.Sign(transaction.Quantity); RealizedPnL += profit; _unrecognizedPnL += profit; } //update cost basis if (Quantity == 0) { //new position CostBasis = fxRate; PriorPeriodCostBasis = fxRate; } else if (Math.Sign(transaction.Quantity) == Math.Sign(Quantity)) { //adding to existing position CostBasis = (Quantity * CostBasis + transaction.Quantity * fxRate) / (Quantity + transaction.Quantity); PriorPeriodCostBasis = (Quantity * PriorPeriodCostBasis + transaction.Quantity * fxRate) / (Quantity + transaction.Quantity); } else if (Math.Abs(transaction.Quantity) > Math.Abs(Quantity)) { //removing from position...if we're reversing it, it's as if it's a new position CostBasis = fxRate; PriorPeriodCostBasis = fxRate; } Quantity += transaction.Quantity; }
public void QuantityAndPriceReflectAddedTransactions() { var pos = new CurrencyPosition(_currency); decimal fxRate = 1.35m; int quantity = 1000; var transaction1 = new FXTransaction { Quantity = quantity, Proceeds = fxRate * quantity, Cost = -fxRate * quantity, FXCurrency = _currency }; pos.AddFXTransaction(transaction1); Assert.AreEqual(quantity, pos.Quantity); Assert.AreEqual(fxRate, pos.CostBasis); Assert.AreEqual(fxRate, pos.PriorPeriodCostBasis); }
public void RealizedProfitsWithUpdateBetweenTradesCalculatedCorrectly() { var pos = new CurrencyPosition(_currency); decimal fxRate = 1.35m; int quantity = 1000; var transaction1 = new FXTransaction { Quantity = quantity, Proceeds = fxRate * quantity, Cost = -fxRate * quantity, FXCurrency = _currency }; pos.AddFXTransaction(transaction1); decimal newFxRate = 1.36m; pos.Update(newFxRate); Assert.AreEqual(quantity * (newFxRate - fxRate), pos.TotalPnL); int newQuantity = -1000; decimal newFxRate2 = 1.37m; var transaction2 = new FXTransaction { Quantity = newQuantity, Proceeds = newFxRate2 * newQuantity, Cost = -newFxRate2 * newQuantity, FXCurrency = _currency }; pos.AddFXTransaction(transaction2); Assert.AreEqual(-newQuantity * (newFxRate2 - fxRate), pos.RealizedPnL); }
public async Task RemoveFxTransactionFromTrade(Trade trade, FXTransaction fxTransaction) { await TradesRepository.RemoveFXTransaction(trade, fxTransaction); }
public async Task AddFxTransactionToTrade(Trade trade, FXTransaction fxTransaction) { await TradesRepository.AddFXTransaction(trade, fxTransaction); }