Example #1
0
        public void ProfitCorrectlyCalculatedAfterSimpleEntryAndExit()
        {
            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;
            quantity = -quantity;
            var transaction2 = new FXTransaction
            {
                Quantity = quantity,
                Proceeds = newFxRate * quantity,
                Cost = -newFxRate * quantity,
                FXCurrency = _currency
            };
            pos.AddFXTransaction(transaction2);

            Assert.AreEqual(-quantity * (newFxRate - fxRate), pos.RealizedPnL);

            pos.Update(newFxRate);

            Assert.AreEqual(-quantity * (newFxRate - fxRate), pos.TotalPnL);
        }
Example #2
0
        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;
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        /// <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, _optionsCapitalUsageMultiplier));

            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;
        }
Example #6
0
        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);
        }
Example #7
0
        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--;
        }