Esempio n. 1
0
        public void OnDayClose(DateTime todaysDate, decimal totalCapitalToday)
        {
            //update the status of each trade
            foreach (TradeTracker t in TradeTrackers.Values)
            {
                t.Update(todaysDate, _data, _fxData);
            }

            //update position stats
            foreach (var kvp in Positions)
            {
                int id = kvp.Key;

                Position p         = kvp.Value;
                decimal  fxRate    = p.Currency == null || p.Currency.ID == 1 ? 1 : _fxData[p.Currency.ID][0].Close;
                decimal? lastPrice = !_data.ContainsKey(id) || _data[id].CurrentBar < 0 ? (decimal?)null : _data[id][0].Close;
                p.GetPnL(lastPrice, fxRate);
            }

            //Capital usage and profit/loss for the day
            Capital.AddLong(Positions.Sum(x => x.Value.Capital.Long.Last()));
            Capital.AddShort(Positions.Sum(x => x.Value.Capital.Short.Last()));
            decimal todaysPnl = TradeTrackers.Sum(x => x.Value.TodaysPnL);

            _logger.Log(LogLevel.Trace, string.Format("Portfolio {0} @ {1}: Capital used: {2:0.00} P/L: {3:0.00}",
                                                      Name,
                                                      todaysDate,
                                                      Capital.TodaysCapitalGross,
                                                      todaysPnl));

            //P/L curves
            ProfitLossEquityCurve.AddChange((double)todaysPnl, todaysDate);
            ProfitLossLongEquityCurve.AddValue((double)TradeTrackers.Sum(x => x.Value.TotalPnlLong), todaysDate);
            ProfitLossShortEquityCurve.AddValue((double)TradeTrackers.Sum(x => x.Value.TotalPnlShort), todaysDate);

            //ROAC
            if (Capital.TodaysCapitalGross == 0)
            {
                _deferredPnL += todaysPnl;
                RoacEquityCurve.AddReturn(0, todaysDate);
            }
            else
            {
                RoacEquityCurve.AddReturn((double)((_deferredPnL + todaysPnl) / Capital.TodaysCapitalGross), todaysDate);
                _deferredPnL = 0;
            }

            //ROTC
            if (totalCapitalToday == 0)
            {
                RotcEquityCurve.AddReturn(0, todaysDate);
            }
            else
            {
                RotcEquityCurve.AddReturn((double)(todaysPnl / totalCapitalToday), todaysDate);
            }

            Capital.EndOfDay();
        }
Esempio n. 2
0
        public void Update(DateTime currentDate, Dictionary <int, TimeSeries> data, Dictionary <int, TimeSeries> fxData)
        {
            TodaysPnL = 0;
            if (!Open)
            {
                return;
            }

            //Update positions
            foreach (var kvp in Positions)
            {
                int id = kvp.Key;

                Position p      = kvp.Value;
                decimal  fxRate = p.Currency == null || p.Currency.ID <= 1 ? 1 : fxData[p.Currency.ID][0].Close;
                TodaysPnL += p.GetPnL(data[id].CurrentBar < 0 ? (decimal?)null : data[id][0].Close, fxRate);
            }

            //Update currency positions
            foreach (var kvp in CurrencyPositions)
            {
                int id = kvp.Key;
                if (fxData[id].CurrentBar < 0)
                {
                    continue;
                }

                CurrencyPosition p      = kvp.Value;
                decimal          fxRate = fxData[id][0].Close;
                TodaysPnL += p.Update(fxRate);
            }

            if (Positions.Any(x => x.Value.Capital.Gross.Count > 0))
            {
                Capital.AddLong(Positions.Sum(x => x.Value.Capital.Long.Last()));
                Capital.AddShort(Positions.Sum(x => x.Value.Capital.Short.Last()));
            }

            if (Capital.TodaysCapitalGross != 0)
            {
                _currentEquity *= (double)(1 + TodaysPnL / Capital.TodaysCapitalGross);
            }
#if DEBUG
            _logger.Log(LogLevel.Trace, string.Format("Trade tracker ID {0} @ {1}, todays capital usage {2:0.00}, P/L: {3:0.00}",
                                                      Trade.ID,
                                                      currentDate,
                                                      Capital.TodaysCapitalGross,
                                                      TodaysPnL));
#endif

            Capital.EndOfDay();

            _totalPnL += TodaysPnL;

            CumulativeReturns.Add(currentDate, _currentEquity);
            CumulativePnL.Add(currentDate, _totalPnL);

            Open = Positions.Values.Sum(x => x.Quantity) != 0 ||
                   CurrencyPositions.Values.Sum(x => x.Quantity) != 0 ||
                   (_ordersRemaining > 0 && _ordersRemaining < Trade.Orders.Count);
        }
Esempio n. 3
0
        /// <summary>
        /// Calculates profit/loss given a new price and FX rate. Also updates ROAC.
        /// </summary>
        /// <returns>The profit/loss since the last GetPnL() call.</returns>
        public decimal GetPnL(decimal?newPrice, decimal newFXRate)
        {
            //Null: this happens if there is no data on this anywhere.
            //Can happen when there is no prior position on an instrument.
            decimal updatePrice = newPrice ?? PriorPeriodCostBasis;

            var capitalUsage = GetCapitalUsage(_priorPeriodQuantity, PriorPeriodCostBasis, PriorPeriodFXRateBasis);

            if (_priorPeriodQuantity > 0)
            {
                Capital.AddLong(capitalUsage);
            }
            else
            {
                Capital.AddShort(capitalUsage);
            }

            //the change in value from the previous day
            if (Quantity > 0)
            {
                _unrecognizedPnLLong += Instrument.Multiplier * Quantity * (updatePrice * newFXRate - PriorPeriodCostBasis * PriorPeriodFXRateBasis);
            }
            else
            {
                _unrecognizedPnLShort += Instrument.Multiplier * Quantity * (updatePrice * newFXRate - PriorPeriodCostBasis * PriorPeriodFXRateBasis);
            }

            //calculate ROAC
            if (Capital.TodaysCapitalGross > 0)
            {
                ROAC         = ROAC * (double)(1 + (_unrecognizedPnLLong + _unrecognizedPnLShort + _deferredPnL) / Capital.TodaysCapitalGross);
                _deferredPnL = 0;
            }
            else
            {
                //if no capital is deployed, ROAC calculation is impossible
                //so we just defer the profit/loss until some capital usage exists to calculate ROAC on
                //This happens when position is zero, but we get a cash transaction for example.
                _deferredPnL += _unrecognizedPnLLong + _unrecognizedPnLShort;
            }

            LastPrice = updatePrice;

            _priorPeriodQuantity = Quantity;

            //prior period cost basis is updated to reflect the latest prices
            PriorPeriodCostBasis   = updatePrice;
            PriorPeriodFXRateBasis = newFXRate;

            //Total p/l is updated with today's profit/loss
            PnLLong  += _unrecognizedPnLLong;
            PnLShort += _unrecognizedPnLShort;

            decimal toReturn = _unrecognizedPnLLong + _unrecognizedPnLShort;

            _unrecognizedPnLLong           = 0;
            _unrecognizedPnLShort          = 0;
            _quantityEnteredAfterEodCutoff = 0;
            _avgPriceEnteredAfterEodCutoff = 0;

            Capital.EndOfDay();

            return(toReturn);
        }