using System;
using System.Collections.Generic;
using System.Linq;
using Telerik.Windows.Data;
using MarketData.Utils;
using MarketData.MarketDataModel;
using TradeBlotter.Model;
using TradeBlotter.ViewModels;
using System.Text;
using MarketData.DividendRiskParity;
using MarketData.MarketDataModel.GainLoss;

namespace TradeBlotter.UIUtils
{
// **********************************************************************************************************************************
// ********************************************************* G A I N  L O S S  V I E W   *****************************************
// **********************************************************************************************************************************
  public class GainLossViewSumFunctionSymbol : AggregateFunction<GainLossSummaryItem, String>
  {
    public GainLossViewSumFunctionSymbol()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<GainLossSummaryItem> source)
    {
      int itemCount=0;
      if(null!=source)itemCount=source.Count();
      return String.Format("{0} rows",itemCount);
    }
  }

// **********************************************************************************************************************************
// ********************************************************* D I V I D E N D  P A R I T Y   *****************************************
// **********************************************************************************************************************************
  public class DividendRiskParitySumFunctionGainLossPercent : AggregateFunction<DividendRiskParityPosition, String>
  {
    public DividendRiskParitySumFunctionGainLossPercent()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<DividendRiskParityPosition> source)
    {
      double totalMV=source.Sum(x=>x.CurrentPrice*x.Shares);
      double totalExposure = source.Sum(x => x.Exposure);
      return Utility.FormatPercent((totalMV-totalExposure)/totalExposure);
    }
  }
  public class DividendRiskParitySumFunctionPrice : AggregateFunction<DividendRiskParityPosition, String>
  {
    public DividendRiskParitySumFunctionPrice()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<DividendRiskParityPosition> source)
    {
      double totalExposure = source.Sum(x => x.Exposure);
      double totalShares = source.Sum(x => x.Shares);
      return Utility.FormatCurrency(totalExposure/totalShares, 2);
    }
  }
  public class DividendRiskParitySumFunctionShares : AggregateFunction<DividendRiskParityPosition, String>
  {
    public DividendRiskParitySumFunctionShares()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<DividendRiskParityPosition> source)
    {
      double totalShares = source.Sum(x => x.Shares);
      return Utility.FormatNumber(totalShares, 3,true);
    }
  }
  public class DividendRiskParitySumFunctionExposure : AggregateFunction<DividendRiskParityPosition, String>
  {
    public DividendRiskParitySumFunctionExposure()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<DividendRiskParityPosition> source)
    {
      double totalExposure = source.Sum(x => x.Exposure);
      return Utility.FormatCurrency(totalExposure, 2);
    }
  }
  public class DividendRiskParitySumFunctionWeightedDividend : AggregateFunction<DividendRiskParityPosition, String>
  {
    public DividendRiskParitySumFunctionWeightedDividend()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<DividendRiskParityPosition> source)
    {
      double totalWeightedDividendPercent = source.Sum(x => x.WeightedDividendPercent);
      return Utility.FormatNumber(totalWeightedDividendPercent,2,true);
    }
  }
  public class DividendRiskParitySumFunctionDividendPayment : AggregateFunction<DividendRiskParityPosition, String>
  {
    public DividendRiskParitySumFunctionDividendPayment()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<DividendRiskParityPosition> source)
    {
      double totalDividendPayment = source.Sum(x => x.DividendPayment);
      return Utility.FormatCurrency(totalDividendPayment,2);
    }
  }
  public class DividendRiskParitySumFunctionWeight : AggregateFunction<DividendRiskParityPosition, String>
  {
    public DividendRiskParitySumFunctionWeight()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<DividendRiskParityPosition> source)
    {
      double totalWeight = source.Sum(x => x.Weight);
      return Utility.FormatPercent(totalWeight);
    }
  }
  public class DividendRiskParitySumFunctionGainLoss : AggregateFunction<DividendRiskParityPosition, String>
  {
    public DividendRiskParitySumFunctionGainLoss()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<DividendRiskParityPosition> source)
    {
      double totalGainLoss = source.Sum(x => x.GainLoss);
      return Utility.FormatCurrency(totalGainLoss, 2);
    }
  }

// **********************************************************************************************************************************
// ********************************************************* Q U A N T U M   M O M E N T U M  ******************************************************
// **********************************************************************************************************************************
  public class MomentumPositionSumFunctionShares : AggregateFunction<MGPositionModel,String>
  {
    public MomentumPositionSumFunctionShares()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<MGPositionModel> source)
    {
      double sum=(from MGPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.Shares).Sum();
      return Utility.FormatNumber(sum,3,false);
    }
  }
  public class MomentumPositionSumFunctionExposure : AggregateFunction<MGPositionModel,String>
  {
    public MomentumPositionSumFunctionExposure()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<MGPositionModel> source)
    {
      double exposure=(from MGPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.Exposure).Sum();
      return Utility.FormatCurrency(exposure);
    }
  }
  public class MomentumPositionSumFunctionMarketValue : AggregateFunction<MGPositionModel,String>
  {
    public MomentumPositionSumFunctionMarketValue()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<MGPositionModel> source)
    {
      double marketValue=(from MGPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.MarketValue).Sum();
      return Utility.FormatCurrency(marketValue);
    }
  }
  public class MomentumPositionSumFunctionGainLoss : AggregateFunction<MGPositionModel,String>
  {
    public MomentumPositionSumFunctionGainLoss()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<MGPositionModel> source)
    {
      StringBuilder sb=new StringBuilder();
      double sum=(from MGPositionModel positionModel in source select positionModel.GainLoss).Sum();
      sb.Append("Total:").Append(Utility.FormatCurrency(sum)).Append("\n");
      sum=(from MGPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.GainLoss).Sum();
      sb.Append("Active:").Append(Utility.FormatCurrency(sum));
      return sb.ToString();
    }
  }
  public class MomentumPositionSumFunctionGainLossPcnt : AggregateFunction<MGPositionModel,String>
  {
    public MomentumPositionSumFunctionGainLossPcnt()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<MGPositionModel> source)
    {
      StringBuilder sb=new StringBuilder();
      double marketValue=0.00;
      double exposure=0.00;
      double gainLossPcnt=0.00;

      double cumulativeReturn=ModelPerformanceAggregator.CalculateCumulativeReturn(source);
      sb.Append("Total:").Append(Utility.FormatPercent(cumulativeReturn,2)).Append("\n");

      marketValue=(from MGPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.MarketValue).Sum();
      exposure=(from MGPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.Exposure).Sum();
      if(0.00!=exposure)gainLossPcnt=(marketValue-exposure)/exposure;
      sb.Append("Active:").Append(Utility.FormatPercent(gainLossPcnt,2));
      return sb.ToString();
    }
  }

  // **********************************************************************************************************************************
  // ********************************************************* M G S H Q U A N T U M   M O M E N T U M  ******************************************************
  // **********************************************************************************************************************************

  public class MGSHMomentumPositionSumFunctionShares : AggregateFunction<MGSHPositionModel,String>
  {
    public MGSHMomentumPositionSumFunctionShares()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<MGSHPositionModel> source)
    {
      double sum=(from MGSHPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.Shares).Sum();
      return Utility.FormatNumber(sum,3,false);
    }
  }
  public class MGSHMomentumPositionSumFunctionExposure : AggregateFunction<MGSHPositionModel,String>
  {
    public MGSHMomentumPositionSumFunctionExposure()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<MGSHPositionModel> source)
    {
      double exposure=(from MGSHPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.Exposure).Sum();
      return Utility.FormatCurrency(exposure);
    }
  }
  public class MGSHMomentumPositionSumFunctionMarketValue : AggregateFunction<MGSHPositionModel,String>
  {
    public MGSHMomentumPositionSumFunctionMarketValue()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<MGSHPositionModel> source)
    {
      double marketValue=(from MGSHPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.MarketValue).Sum();
      return Utility.FormatCurrency(marketValue);
    }
  }
  public class MGSHMomentumPositionSumFunctionGainLoss : AggregateFunction<MGSHPositionModel,String>
  {
    public MGSHMomentumPositionSumFunctionGainLoss()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<MGSHPositionModel> source)
    {
      StringBuilder sb=new StringBuilder();
      double sum=(from MGSHPositionModel positionModel in source select positionModel.GainLoss).Sum();
      sb.Append("Total:").Append(Utility.FormatCurrency(sum)).Append("\n");
      sum=(from MGSHPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.GainLoss).Sum();
      sb.Append("Active:").Append(Utility.FormatCurrency(sum));
      return sb.ToString();
    }
  }
  public class MGSHMomentumPositionSumFunctionGainLossPcnt : AggregateFunction<MGSHPositionModel,String>
  {
    public MGSHMomentumPositionSumFunctionGainLossPcnt()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<MGSHPositionModel> source)
    {
      StringBuilder sb=new StringBuilder();
      double marketValue=0.00;
      double exposure=0.00;
      double gainLossPcnt=0.00;

      double cumulativeReturn=ModelPerformanceAggregator.CalculateCumulativeReturn(source);
      sb.Append("Total:").Append(Utility.FormatPercent(cumulativeReturn,2)).Append("\n");

      marketValue=(from MGSHPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.MarketValue).Sum();
      exposure=(from MGSHPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.Exposure).Sum();
      if(0.00!=exposure)gainLossPcnt=(marketValue-exposure)/exposure;
      sb.Append("Active:").Append(Utility.FormatPercent(gainLossPcnt,2));
      return sb.ToString();
    }
  }

  public class MGSHPositionSumFunctionRisk:AggregateFunction<MGSHPositionModel,String>
  {
    public MGSHPositionSumFunctionRisk()
    {
      this.AggregationExpression=items => Sum(items);
    }
    private String Sum(IEnumerable<MGSHPositionModel> source)
    {
      StringBuilder sb=new StringBuilder();
      List<MGSHPositionModel> activePositions=source.Where(x => x.IsActivePosition).ToList();
      double sum=activePositions.Sum(x => x.TotalRiskExposure);
      return Utility.FormatCurrency(sum);
    }
  }


  // **********************************************************************************************************************************
  // ********************************************************* C M M O M E N T U M  ******************************************************
  // **********************************************************************************************************************************
  public class CMMomentumPositionSumFunctionShares : AggregateFunction<CMPositionModel, String>
  {
    public CMMomentumPositionSumFunctionShares()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<CMPositionModel> source)
    {
      double sum = (from CMPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.Shares).Sum();
      return Utility.FormatNumber(sum, 3, false);
    }
  }
  public class CMMomentumPositionSumFunctionExposure : AggregateFunction<CMPositionModel, String>
  {
    public CMMomentumPositionSumFunctionExposure()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<CMPositionModel> source)
    {
      double exposure = (from CMPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.Exposure).Sum();
      return Utility.FormatCurrency(exposure);
    }
  }
  public class CMMomentumPositionSumFunctionMarketValue : AggregateFunction<CMPositionModel, String>
  {
    public CMMomentumPositionSumFunctionMarketValue()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<CMPositionModel> source)
    {
      double marketValue = (from CMPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.MarketValue).Sum();
      return Utility.FormatCurrency(marketValue);
    }
  }
  public class CMMomentumPositionSumFunctionGainLoss : AggregateFunction<CMPositionModel, String>
  {
    public CMMomentumPositionSumFunctionGainLoss()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<CMPositionModel> source)
    {
      StringBuilder sb = new StringBuilder();
      double sum = (from CMPositionModel positionModel in source select positionModel.GainLoss).Sum();
      sb.Append("Total:").Append(Utility.FormatCurrency(sum)).Append("\n");
      sum = (from CMPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.GainLoss).Sum();
      sb.Append("Active:").Append(Utility.FormatCurrency(sum));
      return sb.ToString();
    }
  }
  public class CMMomentumPositionSumFunctionGainLossPcnt : AggregateFunction<CMPositionModel, String>
  {
    public CMMomentumPositionSumFunctionGainLossPcnt()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<CMPositionModel> source)
    {
      StringBuilder sb = new StringBuilder();
      double marketValue=0.00;
      double exposure=0.00;
      double gainLossPcnt=0.00;

      double cumulativeReturn=ModelPerformanceAggregator.CalculateCumulativeReturn(source);
      sb.Append("Total:").Append(Utility.FormatPercent(cumulativeReturn,2)).Append("\n");

      marketValue = (from CMPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.MarketValue).Sum();
      exposure = (from CMPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.Exposure).Sum();
      if (0.00 != exposure) gainLossPcnt = (marketValue - exposure) / exposure;
      sb.Append("Active:").Append(Utility.FormatPercent(gainLossPcnt,2));
      return sb.ToString();
    }
  }
  public class CMMomentumPositionSumFunctionSharpeRatio : AggregateFunction<CMPositionModel, String>
  {
    public CMMomentumPositionSumFunctionSharpeRatio()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<CMPositionModel> source)
    {
      try
      {
        StringBuilder sb = new StringBuilder();
        List<double> weights = new List<double>();
        List<CMPositionModel> items = new List<CMPositionModel>(source.ToList());
        int itemCount = items.Count();

        double totalExposure = (from CMPositionModel positionModel in items select positionModel.Exposure).Sum();
        double totalSharpeRatio = 0.00;
        foreach (CMPositionModel cmPositionModel in items) weights.Add(cmPositionModel.Exposure / totalExposure);

        for (int index = 0; index < itemCount; index++)
        {
          CMPositionModel cmPositionModel = items[index];
          double weight = weights[index];
          totalSharpeRatio += cmPositionModel.SharpeRatio * weight;
        }
        return Utility.FormatNumber(totalSharpeRatio, 4);
      }
      catch (Exception)
      {
        return Constants.CONST_DASHES;
      }
    }
  }
  public class CMMomentumPositionSumFunctionBeta : AggregateFunction<CMPositionModel, String>
  {
    public CMMomentumPositionSumFunctionBeta()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<CMPositionModel> source)
    {
      try
      {
        StringBuilder sb = new StringBuilder();
        List<double> weights = new List<double>();
        List<CMPositionModel> items = new List<CMPositionModel>(source.ToList());
        int itemCount = items.Count();

        double totalExposure = (from CMPositionModel positionModel in items select positionModel.Exposure).Sum();
        double totalBeta = 0.00;
        foreach (CMPositionModel cmPositionModel in items) weights.Add(cmPositionModel.Exposure / totalExposure);

        for (int index = 0; index < itemCount; index++)
        {
          CMPositionModel cmPositionModel = items[index];
          double weight = weights[index];
          totalBeta += cmPositionModel.Beta * weight;
        }
        return Utility.FormatNumber(totalBeta, 4);
      }
      catch (Exception)
      {
        return Constants.CONST_DASHES;
      }
    }
  }
// **********************************************************************************************************************************
// ********************************* C M T T R E N D  (M A R C  M I N E R V I N I / V A N  T H A R P E  *******************************
// **********************************************************************************************************************************
  public class CMTTrendPositionSumFunctionShares:AggregateFunction<CMTPositionModel,String>
  {
    public CMTTrendPositionSumFunctionShares()
    {
      this.AggregationExpression=items => Sum(items);
    }
    private String Sum(IEnumerable<CMTPositionModel> source)
    {
      double sum=(from CMTPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.Shares).Sum();
      return Utility.FormatNumber(sum,3,false);
    }
  }
  public class CMTTrendPositionSumFunctionExposure:AggregateFunction<CMTPositionModel,String>
  {
    public CMTTrendPositionSumFunctionExposure()
    {
      this.AggregationExpression=items => Sum(items);
    }
    private String Sum(IEnumerable<CMTPositionModel> source)
    {
      double exposure=(from CMTPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.Exposure).Sum();
      return Utility.FormatCurrency(exposure);
    }
  }

  public class CMTTrendPositionSumFunctionEdgeRatio:AggregateFunction<CMTPositionModel,String>
  {
    public CMTTrendPositionSumFunctionEdgeRatio()
    {
      this.AggregationExpression=items => Sum(items);
    }
    private String Sum(IEnumerable<CMTPositionModel> source)
    {
      double sumERatio=0.00;

      List<CMTPositionModel> openItems=(from CMTPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel).ToList();
      if(null==openItems || 0==openItems.Count)return Utility.FormatNumber(sumERatio,2);
      double totalExposure=(from CMTPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.Exposure).Sum();
      double[] weightedRatios=new double[openItems.Count];
      for(int index=0;index<weightedRatios.Length;index++)
      {
        CMTPositionModel positionModel=openItems[index];
        weightedRatios[index]=positionModel.EdgeRatio*(positionModel.Exposure/totalExposure);
      }
      sumERatio=weightedRatios.Sum();
      return Utility.FormatNumber(sumERatio,2);
    }
  }

  public class CMTTrendPositionSumFunctionMarketValue:AggregateFunction<CMTPositionModel,String>
  {
    public CMTTrendPositionSumFunctionMarketValue()
    {
      this.AggregationExpression=items => Sum(items);
    }
    private String Sum(IEnumerable<CMTPositionModel> source)
    {
      double marketValue=(from CMTPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.MarketValue).Sum();
      return Utility.FormatCurrency(marketValue);
    }
  }
  public class CMTTrendPositionSumFunctionGainLoss:AggregateFunction<CMTPositionModel,String>
  {
    public CMTTrendPositionSumFunctionGainLoss()
    {
      this.AggregationExpression=items => Sum(items);
    }
    private String Sum(IEnumerable<CMTPositionModel> source)
    {
      StringBuilder sb=new StringBuilder();
      double sum=(from CMTPositionModel positionModel in source select positionModel.GainLoss).Sum();
      sb.Append("Total:").Append(Utility.FormatCurrency(sum)).Append("\n");

      sum=(from CMTPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.GainLoss).Sum();
      sb.Append("Active:").Append(Utility.FormatCurrency(sum));
      return sb.ToString();
    }
  }
  public class CMTTrendPositionSumFunctionGainLossPcnt:AggregateFunction<CMTPositionModel,String>
  {
    public CMTTrendPositionSumFunctionGainLossPcnt()
    {
      this.AggregationExpression=items => Sum(items);
    }
    private String Sum(IEnumerable<CMTPositionModel> source)
    {
      StringBuilder sb=new StringBuilder();
      double marketValue=0.00;
      double exposure=0.00;
      double gainLossPcnt=0.00;

      double cumulativeReturn=ModelPerformanceAggregator.CalculateCumulativeReturn(source);
      sb.Append("Total:").Append(Utility.FormatPercent(cumulativeReturn,2)).Append("\n");


      marketValue=(from CMTPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.MarketValue).Sum();
      exposure=(from CMTPositionModel positionModel in source where Utility.IsEpoch(positionModel.SellDate) select positionModel.Exposure).Sum();
      if(0.00!=exposure) gainLossPcnt=(marketValue-exposure)/exposure;
      sb.Append("Active:").Append(Utility.FormatPercent(gainLossPcnt));
      return sb.ToString();
    }
  }
  public class CMTTrendPositionSumFunctionRisk:AggregateFunction<CMTPositionModel,String>
  {
    public CMTTrendPositionSumFunctionRisk()
    {
      this.AggregationExpression=items => Sum(items);
    }
    private String Sum(IEnumerable<CMTPositionModel> source)
    {
      StringBuilder sb=new StringBuilder();
      List<CMTPositionModel> activePositions=source.Where(x => x.IsActivePosition).ToList();
      double sum=activePositions.Sum(x => x.TotalRiskExposure);
      return Utility.FormatCurrency(sum);
    }
  }
// **********************************************************************************************************************************
// ******************************************************** V A L U E  A T  R I S K  ************************************************
// **********************************************************************************************************************************
  public class ValueAtRiskModelMarketValueFunction : AggregateFunction<PortfolioHoldingViewModel,String>
  {
    public ValueAtRiskModelMarketValueFunction()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<PortfolioHoldingViewModel> source)
    {
      return Utility.FormatCurrency((from portfolioHoldingViewModel in source select portfolioHoldingViewModel.MarketValue).Sum());
    }
  }
  public class ValueAtRiskModelWeightFunction : AggregateFunction<PortfolioHoldingViewModel, String>
  {
    public ValueAtRiskModelWeightFunction()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<PortfolioHoldingViewModel> source)
    {
      return Utility.FormatPercent((from portfolioHoldingViewModel in source select portfolioHoldingViewModel.Weight).Sum());
    }
  }
  public class ValueAtRiskModelWeightExpFunction : AggregateFunction<PortfolioHoldingViewModel, String>
  {
    public ValueAtRiskModelWeightExpFunction()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<PortfolioHoldingViewModel> source)
    {
      return Utility.FormatPercent((from portfolioHoldingViewModel in source select portfolioHoldingViewModel.WeightExp).Sum());
    }
  }
  public class ValueAtRiskModelVaRContributionFunction : AggregateFunction<PortfolioHoldingViewModel, String>
  {
    public ValueAtRiskModelVaRContributionFunction()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<PortfolioHoldingViewModel> source)
    {
      return Utility.FormatPercent((from portfolioHoldingViewModel in source select portfolioHoldingViewModel.Contribution).Sum());
    }
  }
  public class ValueAtRiskModelExposureFunction : AggregateFunction<PortfolioHoldingViewModel, String>
  {
    public ValueAtRiskModelExposureFunction()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<PortfolioHoldingViewModel> source)
    {
      return Utility.FormatCurrency((from portfolioHoldingViewModel in source select portfolioHoldingViewModel.Exposure).Sum());
    }
  }
// ****************************************************************
  public class SumFunctionWeight : AggregateFunction<TradeViewModel, String>
  {
    public SumFunctionWeight()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<TradeViewModel> source)
    {
      double totalWeight = 0.00;
      foreach (TradeViewModel model in source)
      {
        if (!model.IsOpen) continue;
        totalWeight += Utility.ParsePercent(model.Weight);
      }
      return Utility.FormatPercent(totalWeight);
    }
  }
  // ******************************
  public class SumFunctionTodaysChange : AggregateFunction<TradeViewModel, String>
  {
    public SumFunctionTodaysChange()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<TradeViewModel> source)
    {
      double totalTodaysChange = 0.00;
      foreach (TradeViewModel model in source)
      {
        if (!model.IsOpen || model.TodaysChange.Equals(Constants.CONST_DASHES)) continue;
        totalTodaysChange += Utility.ParseCurrency(model.TodaysChange);
      }
      return Utility.FormatCurrency(totalTodaysChange);
    }
  }
  // ******************************

  public class SumFunctionShares : AggregateFunction<TradeViewModel, String>
  {
    public SumFunctionShares()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<TradeViewModel> source)
    {
      double totalShares = 0.00;
      foreach (TradeViewModel model in source)
      {
        if (!model.IsOpen) continue;
        totalShares += model.Shares;
      }
      return Utility.FormatNumber(totalShares);
    }
  }
  // ******************************
  public class SumFunctionMarketValue : AggregateFunction<TradeViewModel, String>
  {
    public SumFunctionMarketValue()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<TradeViewModel> source)
    {
      double totalMarketValue = 0.00;
      foreach (TradeViewModel model in source)
      {
        if (model.MarketValue.Equals(Constants.CONST_DASHES) || model.MarketValue.Equals("N.A.")) continue;
        totalMarketValue += Utility.ParseCurrency(model.MarketValue);
      }
      return Utility.FormatCurrency(totalMarketValue);
    }
  }
  // ******************************
  public class SumFunctionExposure : AggregateFunction<TradeViewModel, String>
  {
    public SumFunctionExposure()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<TradeViewModel> source)
    {
      double totalExposure = 0.00;
      foreach (TradeViewModel model in source)
      {
        if (!model.IsOpen) continue; 
        totalExposure += Utility.ParseCurrency(model.Exposure);
      }
      return Utility.FormatCurrency(totalExposure);
    }
  }
// ******************************
  public class SumFunctionGainLoss : AggregateFunction<TradeViewModel, String>
  {
    public SumFunctionGainLoss()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<TradeViewModel> source)
    {
      double totalGainLoss = 0.00;
      foreach (TradeViewModel model in source)
      {
        if(model.IsOpen)totalGainLoss += Utility.ParseCurrency(model.GainLoss);
      }
      return Utility.FormatCurrency(totalGainLoss);
    }
  }
  // ******************************
  public class TotalReturnFunction : AggregateFunction<TradeViewModel, String>
  {
    public TotalReturnFunction()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<TradeViewModel> source)
    {
      double totalExposure = 0.00;
      double totalMarketValue = 0.00;
      foreach (TradeViewModel model in source)
      {
        if (model.IsOpen)
        {
          totalExposure += Utility.ParseCurrency(model.Exposure);
          totalMarketValue += Utility.ParseCurrency(model.MarketValue);        
        }
      }
      String totalReturn = Utility.FormatPercent(((totalMarketValue - totalExposure) / totalExposure));
      return totalReturn;
    }
  }
// ****************************************************************
  public class ETFHoldingsSumFunctionPercentOfAssets : AggregateFunction<ETFHoldingModel, String>
  {
    public ETFHoldingsSumFunctionPercentOfAssets()
    {
      this.AggregationExpression = items => Sum(items);
    }
    private String Sum(IEnumerable<ETFHoldingModel> source)
    {
      double totalWeight = 0.00;
      foreach (ETFHoldingModel model in source)
      {
        totalWeight += model.PercentOfAssets;
      }
      return Utility.FormatNumber(totalWeight,2);
    }
  }
}
