/// <summary>
 /// Operation to open a position with the specified currency
 /// </summary>
 /// <param name="currencyInPosition"></param>
 /// <param name="baseCurrency"></param>
 /// <param name="executeDate">the date opening the position</param>
 public void OpenPosition(Currency currencyInPosition, Currency baseCurrency, DateTime executeDate)
 {
     if (Status == PositionRuntimeStatus.Active)
         throw new Exception("The position is already opened. Currency in the position: " + this._currencyInPosition.Name
             );
     Status = PositionRuntimeStatus.Active;
     _startTime = executeDate;
     this._currencyInPosition = currencyInPosition;
     this._baseCurrency = baseCurrency;
     _currentPositionRecord = new PositionRecord(executeDate, currencyInPosition, baseCurrency, PositionType, this);
     PositionRecords.Add(_currentPositionRecord);
 }
        /// <summary>
        /// Take profit re-entry operation
        /// A new position record is created with start date as executeDate
        /// </summary>
        /// <param name="executeDate">the date performing take profit re-entry</param>
        public void TakeProfitReEntry(DateTime executeDate)
        {
            if (Status != PositionRuntimeStatus.TakeProfit)
                throw new Exception("The status of a position must be at Take Profit when calling TakeProfitReEntry function.");

            Status = PositionRuntimeStatus.Active;
            // create a new trade record using the last traded record
            _currentPositionRecord = new PositionRecord(executeDate, this.CurrencyInPosition, BaseCurrency, PositionType, this);
            PositionRecords.Add(_currentPositionRecord);
        }
        /// <summary>
        /// Get the start date of the record which is within a valid date
        /// </summary>
        /// <param name="record"></param>
        /// <returns></returns>
        private DateTime GetEffectiveStartDate(PositionRecord record)
        {
            DateTime effectiveStartDate;

            if (_effectiveDates.Contains(record.StartDate))
                effectiveStartDate = record.StartDate;
            else
                effectiveStartDate = _effectiveDates.Where(d => d >= record.StartDate).Min();
            return effectiveStartDate;
        }
 /// <summary>
 /// Get the bid or ask exchange rate according to the type of the record.
 /// Long position -> Bid price
 /// Short position -> Ask price
 /// </summary>
 /// <param name="record"></param>
 /// <param name="currentDate"></param>
 /// <returns></returns>
 private decimal GetExchangeRate(PositionRecord record, DateTime currentDate)
 {
     decimal curExchangeRate;
     if (record.Type == PositionType.Long)
         curExchangeRate = GetBidExRate(record.BaseCurrency.Name,
                                                     record.CurrencyInPosition.Name,
                                                     currentDate);
     else
         curExchangeRate = GetAskExRate(record.BaseCurrency.Name,
                                                    record.CurrencyInPosition.Name,
                                                    currentDate);
     return curExchangeRate;
 }
 private static decimal CalculateProfitBaseOnPosType(PositionRecord record, decimal forwardRate, decimal curExchangeRate)
 {
     decimal curProfit;
     if (record.Type == PositionType.Long)
         curProfit = (forwardRate - curExchangeRate) / curExchangeRate;
     else
         curProfit = (curExchangeRate - forwardRate) / curExchangeRate;
     return curProfit;
 }
 /// <summary>
 /// Determine whether the exchange rate is ask or bid for forward rate calculation
 /// </summary>
 /// <param name="record"></param>
 /// <param name="effectiveStartDate"></param>
 /// <returns></returns>
 private decimal GetExchangeRateBaseOnPosType(PositionRecord record, DateTime effectiveStartDate)
 {
     decimal startExchangeRate;
     if (record.Type == PositionType.Long)
         startExchangeRate = GetAskExRate(record.BaseCurrency.Name,
                                                            record.CurrencyInPosition.Name,
                                                            effectiveStartDate);
     else
         startExchangeRate = GetBidExRate(record.BaseCurrency.Name,
                                                             record.CurrencyInPosition.Name,
                                                             effectiveStartDate);
     return startExchangeRate;
 }