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; }