diff --git a/Model/ModelPerformanceAggregator.cs b/Model/ModelPerformanceAggregator.cs index 2c066c8..f3da0fc 100644 --- a/Model/ModelPerformanceAggregator.cs +++ b/Model/ModelPerformanceAggregator.cs @@ -137,120 +137,8 @@ namespace TradeBlotter.Model return performanceSeries; } } - //public static double CalculateCumulativeReturn(IEnumerable positions) - //{ - // ModelPerformanceSeries performanceSeries=GetModelPerformance(positions); - // if(null==performanceSeries) return double.NaN; - // return performanceSeries[performanceSeries.Count-1].CumProdMinusOne; - //} - //public static ModelPerformanceSeries GetModelPerformance(IEnumerable positions) - //{ - // ModelPerformanceSeries performanceSeries=new ModelPerformanceSeries(); - // try - // { - // DateTime minDate=positions.Min(x => x.PurchaseDate); - // DateTime maxDate=PricingDA.GetLatestDate(); - // DateGenerator dateGenerator=new DateGenerator(); - // double cumulativeReturn=double.NaN; - // double prevGainLoss=double.NaN; - - // LocalPriceCache.GetInstance().RemoveDate(maxDate); - // List historicalDates=dateGenerator.GenerateHistoricalDates(minDate,maxDate); - - // foreach(MMPositionModel position in positions) - // { - // if(dateGenerator.IsWeekend(position.PurchaseDate)) - // { - // while(true) - // { - // position.PurchaseDate=dateGenerator.GetNextBusinessDay(position.PurchaseDate); - // if(!HolidayDA.IsMarketHoliday(position.PurchaseDate)) break; - // } - // } - // if(dateGenerator.IsWeekend(position.SellDate)) - // { - // while(true) - // { - // position.SellDate=dateGenerator.GetNextBusinessDay(position.SellDate); - // if(!HolidayDA.IsMarketHoliday(position.SellDate)) break; - // } - // } - // } - // foreach(DateTime currentDate in historicalDates) - // { - // IEnumerable openPositions=positions.Where(x => (x.PurchaseDate<=currentDate&&(!Utility.IsEpoch(x.SellDate)&&x.SellDate>currentDate))||(x.PurchaseDate<=currentDate&&Utility.IsEpoch(x.SellDate))).ToList(); - // IEnumerable closedPositions=positions.Where(x => (!Utility.IsEpoch(x.SellDate)&&x.SellDate.Equals(currentDate))).ToList(); - // if(0==openPositions.Count()&&0==closedPositions.Count()) continue; - // double gainLoss=0.00; - // double gainLossClosedPositions=0.00; - // double exposure=0.00; - // double marketValue=0.00; - // if(HolidayDA.IsMarketHoliday(currentDate)) continue; - // ModelPerformanceItem performanceItem=new ModelPerformanceItem(); - // foreach(MMPositionModel openPosition in openPositions) - // { - // exposure+=openPosition.Shares*openPosition.PurchasePrice; - // if(!LocalPriceCache.GetInstance().ContainsPrice(openPosition.Symbol,currentDate)) - // { - // Prices prices=PricingDA.GetPricesForward(openPosition.Symbol,currentDate,90); - // LocalPriceCache.GetInstance().Add(prices); - // } - // Price price=LocalPriceCache.GetInstance().GetPrice(openPosition.Symbol,currentDate); - // gainLoss+=((price.Close*openPosition.Shares)-(openPosition.PurchasePrice*openPosition.Shares)); - // marketValue+=(price.Close*openPosition.Shares); - // } - // foreach(MMPositionModel closedPosition in closedPositions) - // { - // double gainLossPosition=(closedPosition.CurrentPrice*closedPosition.Shares)-(closedPosition.PurchasePrice*closedPosition.Shares); - // gainLossClosedPositions+=gainLossPosition; - // } - // double dailyReturn=0.00; - // if(double.IsNaN(prevGainLoss)) dailyReturn=(marketValue-exposure)/Math.Abs(exposure); - // else dailyReturn=((gainLoss-prevGainLoss)/Math.Abs(prevGainLoss))/100.00; - // if(double.IsNaN(cumulativeReturn)) cumulativeReturn=1.00*(1.00+dailyReturn); - // else cumulativeReturn=cumulativeReturn*(1.00+dailyReturn); - - // performanceItem.Date=currentDate; - // performanceItem.Exposure=exposure; - // performanceItem.MarketValue=marketValue; - // performanceItem.GainLossDOD=double.IsNaN(prevGainLoss)?gainLoss:(gainLoss-prevGainLoss)+gainLossClosedPositions; - // performanceItem.GainLoss=gainLoss+gainLossClosedPositions; - // performanceItem.ClosedPositions=closedPositions.Count()>0?true:false; - // performanceSeries.Add(performanceItem); - // prevGainLoss=gainLoss; - // } - - - // for(int index=0;index positions) { @@ -258,12 +146,21 @@ namespace TradeBlotter.Model if(null==performanceSeries)return double.NaN; return performanceSeries[performanceSeries.Count-1].CumProdMinusOne; } + public static double CalculateCumulativeReturn(IEnumerable positions) { ModelPerformanceSeries performanceSeries=GetModelPerformance(positions); if(null==performanceSeries) return double.NaN; return performanceSeries[performanceSeries.Count-1].CumProdMinusOne; } + + public static double CalculateCumulativeReturn(IEnumerable positions) + { + ModelPerformanceSeries performanceSeries=GetModelPerformance(positions); + if(null==performanceSeries) return double.NaN; + return performanceSeries[performanceSeries.Count-1].CumProdMinusOne; + } + public static ModelPerformanceSeries GetModelPerformance(IEnumerable positions) { ModelPerformanceSeries performanceSeries=new ModelPerformanceSeries(); @@ -486,5 +383,117 @@ namespace TradeBlotter.Model return null; } } + +// *********************************************************************************************************************************************************************************************************** +// *********************************************************************************** M G S H Q U A N T U M M O M E N T U M ************************************************************************************** +// *********************************************************************************************************************************************************************************************************** + public static ModelPerformanceSeries GetModelPerformance(IEnumerable positions) + { + ModelPerformanceSeries performanceSeries=new ModelPerformanceSeries(); + try + { + DateTime minDate=positions.Min(x => x.PurchaseDate); + DateTime maxDate=PricingDA.GetLatestDate(); + DateGenerator dateGenerator=new DateGenerator(); + double cumulativeReturn=double.NaN; + double prevGainLoss=double.NaN; + + LocalPriceCache.GetInstance().RemoveDate(maxDate); + List historicalDates=dateGenerator.GenerateHistoricalDates(minDate,maxDate); + + foreach(MGSHPositionModel position in positions) + { + if(dateGenerator.IsWeekend(position.PurchaseDate)) + { + while(true) + { + position.PurchaseDate=dateGenerator.GetNextBusinessDay(position.PurchaseDate); + if(!HolidayDA.IsMarketHoliday(position.PurchaseDate)) break; + } + } + if(dateGenerator.IsWeekend(position.SellDate)) + { + while(true) + { + position.SellDate=dateGenerator.GetNextBusinessDay(position.SellDate); + if(!HolidayDA.IsMarketHoliday(position.SellDate)) break; + } + } + } + foreach(DateTime currentDate in historicalDates) + { + IEnumerable openPositions=positions.Where(x => (x.PurchaseDate<=currentDate&&(!Utility.IsEpoch(x.SellDate)&&x.SellDate>currentDate))||(x.PurchaseDate<=currentDate&&Utility.IsEpoch(x.SellDate))).ToList(); + IEnumerable closedPositions=positions.Where(x => (!Utility.IsEpoch(x.SellDate)&&x.SellDate.Equals(currentDate))).ToList(); + if(0==openPositions.Count()&&0==closedPositions.Count()) continue; + double gainLoss=0.00; + double gainLossClosedPositions=0.00; + double exposure=0.00; + double marketValue=0.00; + if(HolidayDA.IsMarketHoliday(currentDate)) continue; + ModelPerformanceItem performanceItem=new ModelPerformanceItem(); + foreach(MGSHPositionModel openPosition in openPositions) + { + exposure+=openPosition.Shares*openPosition.PurchasePrice; + if(!LocalPriceCache.GetInstance().ContainsPrice(openPosition.Symbol,currentDate)) + { + Prices prices=PricingDA.GetPricesForward(openPosition.Symbol,currentDate,90); + LocalPriceCache.GetInstance().Add(prices); + } + Price price=LocalPriceCache.GetInstance().GetPrice(openPosition.Symbol,currentDate); + if(null==price) + { + MDTrace.WriteLine(LogLevel.DEBUG,String.Format("GetModelPerformance: No price for {0} on {1}",openPosition.Symbol,currentDate.ToShortDateString())); + continue; + } + gainLoss+=((price.Close*openPosition.Shares)-(openPosition.PurchasePrice*openPosition.Shares)); + marketValue+=(price.Close*openPosition.Shares); + } + foreach(MGSHPositionModel closedPosition in closedPositions) + { + double gainLossPosition=(closedPosition.CurrentPrice*closedPosition.Shares)-(closedPosition.PurchasePrice*closedPosition.Shares); + gainLossClosedPositions+=gainLossPosition; + } + double dailyReturn=0.00; + if(double.IsNaN(prevGainLoss)) dailyReturn=(marketValue-exposure)/Math.Abs(exposure); + else dailyReturn=((gainLoss-prevGainLoss)/Math.Abs(prevGainLoss))/100.00; + if(double.IsNaN(cumulativeReturn)) cumulativeReturn=1.00*(1.00+dailyReturn); + else cumulativeReturn=cumulativeReturn*(1.00+dailyReturn); + performanceItem.Date=currentDate; + performanceItem.Exposure=exposure; + performanceItem.MarketValue=marketValue; + performanceItem.GainLossDOD=double.IsNaN(prevGainLoss)?gainLoss:(gainLoss-prevGainLoss)+gainLossClosedPositions; + performanceItem.GainLoss=gainLoss+gainLossClosedPositions; + performanceItem.ClosedPositions=closedPositions.Count()>0?true:false; + performanceSeries.Add(performanceItem); + prevGainLoss=gainLoss; + } + for(int index=0;index