Ejemplo n.º 1
0
        static public List<Term> GetTermFromPeriod(
            DateTime positionStartDate, DateTime positionEndDate,
            PeriodicTimeDefinition termLength
            )
        {

            List<Term> resultTerms = new List<Term>();

            var availableTermDates = termLength.AvailableDates;

            // the date of the first term
            var firstTermEndDate = availableTermDates.Where(d => d > positionStartDate).Min();

            var lastTermEndDate = availableTermDates.Where(d => d >= positionEndDate).Min();

            var effectiveDates =  availableTermDates
                .Where(d => d >= positionStartDate && d <= lastTermEndDate);

            for (int i = 0; i < effectiveDates.Count() ; i++)
            {
                if (i == 0)
                    resultTerms.Add(new Term(positionStartDate, firstTermEndDate));
                else if( effectiveDates.ElementAtOrDefault(i+1) != DateTime.MinValue)
                    resultTerms.Add(
                        new Term(effectiveDates.ElementAt(i), 
                            effectiveDates.ElementAt(i + 1)
                            ));
            }

            return resultTerms;
        }
        public void GetTransformedPositionRecordsTest()
        {
            FXEntities.FXEntities fxEntities = new FXEntities.FXEntities();
            CurrencyDataSource currencyDataSource = new CurrencyDataSource(fxEntities);
           
            var startDate = new DateTime(2000, 1, 4);
            var endDate = new DateTime(2003, 1, 4);
            var periodicTimeDef = new PeriodicTimeDefinition(3, PeriodicType.Month);
            periodicTimeDef.Initialize(startDate, endDate);
            ProfitCalculationEngine_Accessor target = new ProfitCalculationEngine_Accessor(currencyDataSource);

            PositionRuntime positionRuntime = new PositionRuntime(FXStrategy.Interpreter.PositionType.Long);
            positionRuntime.PositionRecords.Add(new PositionRecord(
                new DateTime(2000, 1, 4), new Currency("USD"), new Currency("EUR"),
                 FXStrategy.Interpreter.PositionType.Long, positionRuntime)
                 {
                     EndDate = new DateTime(2001,3,2)
                 });

            //var actual = target.GetTransformedPositionRecords(positionRuntime, periodicTimeDef);

            //Assert.AreEqual(actual.Count, 6);
            //Assert.IsTrue(actual.ElementAt(5).Type == FXStrategy.Interpreter.PositionType.Short);
            //Assert.IsTrue(actual.Take(5).All(t => t.Type == FXStrategy.Interpreter.PositionType.Long));
        }
 public void GetTermFromPeriodTest()
 {
     DateTime positionStartDate = new DateTime(2000,1,4);
     DateTime positionEndDate = new DateTime(2000,7,15); 
     PeriodicTimeDefinition termLength = new PeriodicTimeDefinition(3, PeriodicType.Month);
     termLength.Initialize(positionStartDate, new DateTime(2001,1,1));
     List<Term> actual;
     actual = TermManager.GetTermFromPeriod(positionStartDate, positionEndDate, termLength);
     Assert.AreEqual(3, actual.Count);
 }
 public void CanExecuteTest()
 {
     PeriodicTimeDefinition target = new PeriodicTimeDefinition( 3,
           PeriodicType.Month
     );
     DateTime startDate = new DateTime(2000,1,7); 
     DateTime currentDate = new DateTime(2000,4,7);
     bool expected = true; // TODO: Initialize to an appropriate value
     bool actual;
     target.Initialize(startDate, currentDate);
     actual = target.CanExecute(currentDate);
     Assert.AreEqual(expected, actual);
 }
        /// <summary>
        /// Calculate the total profit from all positions
        /// </summary>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <param name="termLength"></param>
        private void CalculateReturnIndex(DateTime startDate, DateTime endDate, PeriodicTimeDefinition termLength)
        {
            _returnOverTime = new List<TimeSeriesData>();
            _indexOverTime = new List<TimeSeriesData>();

            int numberOfPositions = _individualPositionIndex.Keys.Count;
            var returns = _individualPositionIndex.Values.SelectMany(d => d);
            // except first date
            var effectiveTermDates = termLength.AvailableDates.Where(d => d != startDate);

            decimal averageReturn;
            decimal currentIndex = 100;
            foreach (var date in _effectiveDates)
            {
                var targetRecords = returns.Where(r => r.Time == date);

                if (targetRecords == null || targetRecords.Count() == 0)
                    continue;

                averageReturn = returns.Where(r => r.Time == date).Average(r => r.Value);

                // if it is the maturity date, accumulate the profit
                if (effectiveTermDates.Contains(date))
                {
                    currentIndex = currentIndex * (1 + averageReturn);
                    _indexOverTime.Add(new TimeSeriesData()
                    {
                        Time = date,
                        Value = currentIndex
                    });
                }
                else
                {
                    _indexOverTime.Add(new TimeSeriesData()
                    {
                        Time = date,
                        Value = currentIndex * (1 + averageReturn)
                    });
                }

                _returnOverTime.Add(new TimeSeriesData()
                {
                    Time = date,
                    Value = averageReturn
                });
            }
        }
        /// <summary>
        /// Calculate returns from the position records in the position run time
        /// </summary>
        /// <param name="positionRunTimeList">list of positions (from the runtime)</param>
        /// <param name="startDate">start date of the back-testing analysis</param>
        /// <param name="endDate">end date of the back-testing analysis</param>
        /// <param name="termLength">Length of forward contract</param>
        public void Evaluate(List<PositionRuntime> positionRunTimeList, 
            DateTime startDate, DateTime endDate, PeriodicTimeDefinition termLength)
        {
             if (termLength.AvailableDates == null)
                termLength.Initialize(startDate, endDate);

             _effectiveDates = Util.DateTimeHelper.GetWeekdaysDate(startDate, endDate);

            _individualPositionIndex = new Dictionary<PositionRuntime, List<TimeSeriesData>>();

            // initialize data set
            _currencyDataSource.PreLoad();

            // Calculate profit for each position parallely
            positionRunTimeList.AsParallel().ForAll(position =>
                CalculateIndividualPositionProfitIndexes(startDate,endDate,termLength,position));

            CalculateReturnIndex(startDate,endDate,termLength);
        }
 public MovingAverage(TimeDataSetAccessor timeDataSetAccessor, PeriodicTimeDefinition length, Expression requestDate)
     :base(timeDataSetAccessor)
 {
     _length = length;
     _requestDate = requestDate;
 }
        /// <summary>
        /// Split position records into records in the length of termLength
        /// </summary>
        /// <param name="originalPositionRecords"></param>
        /// <param name="termLength"></param>
        /// <returns></returns>
        private List<PositionRecord> TransformPositionRecords(
            PositionRuntime positionRuntime,
            PeriodicTimeDefinition termLength)
        {
            List<DateTime> termEffectiveDates = termLength.AvailableDates;

            List<PositionRecord> transformedPositionRecords = new List<PositionRecord>();

            foreach (var positionRecord in positionRuntime.PositionRecords)
            {
                // list of terms that available for the position
                var effectiveTerms = TermManager.GetTermFromPeriod(positionRecord.StartDate, positionRecord.EndDate, termLength);

                // create terms for each position record
                effectiveTerms.ForEach(t => transformedPositionRecords.Add(new PositionRecord(
                    t.StartDate, 
                    t.EndDate,
                    positionRecord.CurrencyInPosition, positionRecord.BaseCurrency,
                    positionRecord.Type, positionRuntime)));

                if (positionRecord.EndDate != effectiveTerms.Last().EndDate)
                {
                    // for the case ending the record within a forward contract
                    // an opposite position will be opened
                    transformedPositionRecords.Add(new PositionRecord(
                      effectiveTerms.Last().StartDate,
                      effectiveTerms.Last().EndDate,
                      positionRecord.CurrencyInPosition,
                      positionRecord.BaseCurrency,
                      (positionRecord.Type == PositionType.Long) ? PositionType.Short : PositionType.Long,
                      positionRuntime));
                }
            }

            return transformedPositionRecords;
        }
        /// <summary>
        /// Calculate profit for an individual position over time
        /// </summary>
        /// <param name="startDate">start date of the back-testing analysis</param>
        /// <param name="endDate">end date of the back-testing analysis</param>
        /// <param name="termLength">Length of forward contract</param>
        /// <param name="position">the position for calculation</param>
        private void CalculateIndividualPositionProfitIndexes(DateTime startDate, 
            DateTime endDate, PeriodicTimeDefinition termLength, PositionRuntime position)
        {
            AssignEndDateToLastRecord(endDate, position);
            List<PositionRecord> transformedRecord = TransformPositionRecords(position, termLength);
            List<TimeSeriesData> positionIndexes = new List<TimeSeriesData>();
            foreach (var record in transformedRecord)
            {

                DateTime effectiveStartDate = GetEffectiveStartDate(record);
                DateTime effectiveEndDate = GetEffectiveEndDate(record);

                decimal startExchangeRate = GetExchangeRateBaseOnPosType(record, effectiveStartDate);

                decimal variableInRate = 
                    GetIntRate(record.CurrencyInPosition.Name, effectiveStartDate) / (decimal)100;
                decimal baseInRate = 
                    GetIntRate(record.BaseCurrency.Name, effectiveStartDate) / (decimal)100;

                decimal forwardRate =
                    CalculateForwardRate((effectiveEndDate - effectiveStartDate).Days, 
                    startExchangeRate, baseInRate, variableInRate);

                foreach (var currentDate in DateTimeHelper.GetWeekdaysDate(record.StartDate, record.EndDate))
                {
                    decimal curExchangeRate = GetExchangeRate(record, currentDate);

                    decimal curProfit = CalculateProfitBaseOnPosType(record, forwardRate, curExchangeRate);

                    var existingIndex = positionIndexes.Where(d => d.Time == currentDate).FirstOrDefault();

                    if (existingIndex == null)
                    {
                        positionIndexes.Add(new TimeSeriesData()
                        {
                            Time = currentDate,
                            Value = curProfit
                        });
                    }
                    else
                    {
                        existingIndex.Value += curProfit;
                    }
                }
            }
            _individualPositionIndex.Add(position, positionIndexes);
        }