public PositionRecord(DateTime startTradeTime, Currency currencyToTrade,
     Currency baseCurrency, PositionType type, PositionRuntime positionRuntime)
 {
     _currencyInPosition = currencyToTrade;
     _startDate = startTradeTime;
     _baseCurrency = baseCurrency;
     _type = type;
     _positionRuntime = positionRuntime;
 }
        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));
        }
 private static void AssignEndDateToLastRecord(DateTime endDate, PositionRuntime position)
 {
     var emptyEndTimeRecords = position.PositionRecords.SelectMany(r => r.PositionRuntime.PositionRecords).Where(p => p.EndDate == DateTime.MinValue);
     foreach(var emptyEndTimeRecord in emptyEndTimeRecords)
         emptyEndTimeRecord.EndDate = endDate;
 }
        /// <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);
        }
 public PositionRecord(DateTime startTradeTime, 
     DateTime endTradeTime, Currency currencyToTrade, 
     Currency baseCurrency, PositionType type, PositionRuntime positionRuntime):
     this(startTradeTime, currencyToTrade, baseCurrency,  type, positionRuntime){
         this.EndDate = endTradeTime;
 }