using MarketData.Numerical;
using MarketData.ValueAtRisk;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MarketData.MarketDataModel
{
  public class PortfolioHoldingsWithSharpeRatio : List<PortfolioHoldingWithSharpeRatio>
  {
    private PortfolioHoldingsWithSharpeRatio()
    {
    }
    public PortfolioHoldingsWithSharpeRatio(List<PortfolioHoldingWithSharpeRatio> portfolioHoldingsWithSharpeRatio)
    {
      TotalSharpeRatio = 0.00;
      if (null == portfolioHoldingsWithSharpeRatio) return;
      foreach (PortfolioHoldingWithSharpeRatio portfolioHoldingWithSharpeRatio in portfolioHoldingsWithSharpeRatio) Add(portfolioHoldingWithSharpeRatio);
      Exposure = (from PortfolioHoldingWithSharpeRatio portfolioHoldingWithSharpeRatio in this select portfolioHoldingWithSharpeRatio.Exposure).Sum();
      TotalSharpeRatio = (from PortfolioHoldingWithSharpeRatio portfolioHoldingWithSharpeRatio in this select portfolioHoldingWithSharpeRatio.WeightAdjustedSharpeRatio).Sum();
    }
    public PortfolioHoldingsWithSharpeRatio(PortfolioHoldings portfolioHoldings,DateTime analysisDate)
    {
      TotalSharpeRatio = 0.00;
      if (null == portfolioHoldings) return;
      foreach (PortfolioHolding portfolioHolding in portfolioHoldings) Add(new PortfolioHoldingWithSharpeRatio(portfolioHolding));
      Exposure = (from PortfolioHoldingWithSharpeRatio portfolioHoldingWithSharpeRatio in this select portfolioHoldingWithSharpeRatio.Exposure).Sum();
      foreach (PortfolioHoldingWithSharpeRatio portfolioHoldingWithSharpeRatio in this)
      {
        SharpeRatioGenerator.GenerateSharpeRatio(portfolioHoldingWithSharpeRatio, analysisDate, 12);
      }
      foreach (PortfolioHoldingWithSharpeRatio portfolioHoldingWithSharpeRatio in this)
      {
        portfolioHoldingWithSharpeRatio.WeightExp = portfolioHoldingWithSharpeRatio.Exposure / Exposure;
        portfolioHoldingWithSharpeRatio.WeightAdjustedSharpeRatio = portfolioHoldingWithSharpeRatio.WeightExp * portfolioHoldingWithSharpeRatio.SharpeRatio;
      }
      TotalSharpeRatio = (from PortfolioHoldingWithSharpeRatio portfolioHoldingWithSharpeRatio in this select portfolioHoldingWithSharpeRatio.WeightAdjustedSharpeRatio).Sum();
      foreach (PortfolioHoldingWithSharpeRatio portfolioHoldingWithSharpeRatio in this)
      {
        portfolioHoldingWithSharpeRatio.SharpeRatioContribution = portfolioHoldingWithSharpeRatio.WeightAdjustedSharpeRatio / TotalSharpeRatio;
      }
    }
    //public PortfolioHoldingsWithSharpeRatio(PortfolioTrades portfolioTrades, DateTime? analysisDate = null)
    //{
    //  TotalSharpeRatio = 0.00;

    //  if (null == analysisDate) analysisDate = DateTime.Now;
    //  List<MarketDataModel.Position> positions = portfolioTrades.GetPositions(analysisDate.Value);
    //  foreach (MarketDataModel.Position position in positions) Add(new PortfolioHoldingWithSharpeRatio(position));

    //  Exposure = (from PortfolioHoldingWithSharpeRatio portfolioHoldingWithSharpeRatio in this select portfolioHoldingWithSharpeRatio.Exposure).Sum();
    //  foreach (PortfolioHoldingWithSharpeRatio portfolioHoldingWithSharpeRatio in this)
    //  {
    //    SharpeRatioGenerator.GenerateSharpeRatio(portfolioHoldingWithSharpeRatio, analysisDate.Value, 12);
    //  }
    //  foreach (PortfolioHoldingWithSharpeRatio portfolioHoldingWithSharpeRatio in this)
    //  {
    //    portfolioHoldingWithSharpeRatio.WeightExp = portfolioHoldingWithSharpeRatio.Exposure / Exposure;
    //    portfolioHoldingWithSharpeRatio.WeightAdjustedSharpeRatio = portfolioHoldingWithSharpeRatio.WeightExp * portfolioHoldingWithSharpeRatio.SharpeRatio;
    //  }
    //  TotalSharpeRatio = (from PortfolioHoldingWithSharpeRatio portfolioHoldingWithSharpeRatio in this select portfolioHoldingWithSharpeRatio.WeightAdjustedSharpeRatio).Sum();
    //  foreach (PortfolioHoldingWithSharpeRatio portfolioHoldingWithSharpeRatio in this)
    //  {
    //    portfolioHoldingWithSharpeRatio.SharpeRatioContribution = portfolioHoldingWithSharpeRatio.WeightAdjustedSharpeRatio / TotalSharpeRatio;
    //  }
    //}
    public double TotalSharpeRatio { get; set; }  // This is the total Sharpe Ration for all positions
    public double Exposure { get; set; }
  }
  public class PortfolioHoldingWithSharpeRatio
  {
    private PortfolioHoldingWithSharpeRatio()
    {
    }
    public PortfolioHoldingWithSharpeRatio(MarketDataModel.Position position)
    {
      Symbol = position.Symbol;
      Exposure = position.Exposure;
    }
    public PortfolioHoldingWithSharpeRatio(PortfolioHolding portfolioHolding)
    {
      Symbol = portfolioHolding.Symbol;
      Exposure = portfolioHolding.Exposure;
    }
    public String Symbol { get; set; }
    public double Exposure { get; set; }
    public double WeightExp { get; set; }
    public double AverageReturn { get; set; }
    public double RiskPremium { get; set; }
    public double Volatility { get; set; }
    public double SharpeRatio { get; set; }
    public double WeightAdjustedSharpeRatio { get; set; }
    public double SharpeRatioContribution { get; set; }
  }
}
