using MarketData.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MarketData.Generator.CMTrend
{
  public class CMTCandidates : List<CMTCandidate>
  {
    public CMTCandidates()
    {
    }
    public CMTCandidates(List<CMTCandidate> cmtCandidates)
    {
      foreach(CMTCandidate cmtCandidate in cmtCandidates) Add(cmtCandidate);
    }
    public NVPCollections ToNVPCollections()
    {
      NVPCollections nvpCollections=new NVPCollections();
      foreach(CMTCandidate candidate in this)
      {
        nvpCollections.Add(candidate.ToNVPCollection());
      }
      return nvpCollections;
    }
    public static CMTCandidates FromNVPCollections(NVPCollections nvpCollections)
    {
      CMTCandidates candidates=new CMTCandidates();
      foreach(NVPCollection nvpCollection in nvpCollections)
      {
        candidates.Add(CMTCandidate.FromNVPCollection(nvpCollection));
      }
      return candidates;
    }
    public void AddFromNVPCollection(NVPCollection nvpCollection)
    {
      Add(CMTCandidate.FromNVPCollection(nvpCollection));
    }
    public new void Sort()
    {
      List<CMTCandidate> candidates=new CMTCandidates((from CMTCandidate mmCandidate in this select mmCandidate).OrderByDescending(x => x.Score).ToList());
      this.Clear();
      this.AddRange(candidates);
    }
  }
  public class CMTCandidate
  {
    public CMTCandidate()
    {
      Violation=false;
    }
    public String Symbol { get; set; }
    public DateTime AnalysisDate { get; set; }
    public double EPSSlope { get; set; }
    public double ProfitMarginSlope { get; set; }
    public double PriceSlope { get; set; }
    public double Volatility { get; set; }
    public long Volume { get; set; }
    public double RSquared{get;set;}
    public double Beta{get;set;}
    public int BetaMonths{get;set;}
    public bool Violation { get; set; }
    public double Slope { get; set; }
    public double Score { get; set; }
    public double AnnualizedReturn { get; set; }
    public double SharpeRatio { get; set; }
    public String Reason { get; set; }

    public virtual NVPCollection ToNVPCollection()
    {
      NVPCollection nvpCollection=new NVPCollection();
      nvpCollection.Add(new NVP("Symbol",Symbol.ToString()));
      nvpCollection.Add(new NVP("AnalysisDate",AnalysisDate.ToString()));
      if(!double.IsNaN(EPSSlope)) nvpCollection.Add(new NVP("EPSSlope",EPSSlope.ToString()));
      if(!double.IsNaN(ProfitMarginSlope)) nvpCollection.Add(new NVP("ProfitMarginSlope",ProfitMarginSlope.ToString()));
      if(!double.IsNaN(PriceSlope)) nvpCollection.Add(new NVP("PriceSlope",PriceSlope.ToString()));
      if(!double.IsNaN(Volatility)) nvpCollection.Add(new NVP("Volatility",Volatility.ToString()));
      nvpCollection.Add(new NVP("Volume",Volume.ToString()));
      nvpCollection.Add(new NVP("Violation",Violation.ToString()));
      if(!double.IsNaN(Slope)) nvpCollection.Add(new NVP("Slope",Slope.ToString()));
      if(!double.IsNaN(Score)) nvpCollection.Add(new NVP("Score",Score.ToString()));
      if(!double.IsNaN(AnnualizedReturn)) nvpCollection.Add(new NVP("AnnualizedReturn",AnnualizedReturn.ToString()));
      if(!double.IsNaN(SharpeRatio)) nvpCollection.Add(new NVP("SharpeRatio",SharpeRatio.ToString()));
      if(!double.IsNaN(RSquared)) nvpCollection.Add(new NVP("RSquared",RSquared.ToString()));
      nvpCollection.Add(new NVP("BetaMonths",BetaMonths.ToString()));
      nvpCollection.Add(new NVP("Beta",Beta.ToString()));
      if(null!=Reason) nvpCollection.Add(new NVP("Reason",Reason.ToString()));
      return nvpCollection;
    }
    public static CMTCandidate FromNVPCollection(NVPCollection nvpCollection)
    {
      CMTCandidate candidate=new CMTCandidate();
      NVPDictionary nvpDictionary=nvpCollection.ToDictionary();
      if(nvpDictionary.ContainsKey("Symbol")) candidate.Symbol=nvpDictionary["Symbol"].Get<String>();
      if(nvpDictionary.ContainsKey("AnalysisDate")) candidate.AnalysisDate=nvpDictionary["AnalysisDate"].Get<DateTime>();
      if(nvpDictionary.ContainsKey("EPSSlope")) candidate.EPSSlope=nvpDictionary["EPSSlope"].Get<double>();
      if(nvpDictionary.ContainsKey("ProfitMarginSlope")) candidate.ProfitMarginSlope=nvpDictionary["ProfitMarginSlope"].Get<double>();
      if(nvpDictionary.ContainsKey("PriceSlope")) candidate.PriceSlope=nvpDictionary["PriceSlope"].Get<double>();
      if(nvpDictionary.ContainsKey("Volatility")) candidate.Volatility=nvpDictionary["Volatility"].Get<double>();
      if(nvpDictionary.ContainsKey("Volume")) candidate.Volume=nvpDictionary["Volume"].Get<long>();
      if(nvpDictionary.ContainsKey("Violation")) candidate.Violation=nvpDictionary["Violation"].Get<bool>();
      if(nvpDictionary.ContainsKey("Slope")) candidate.Slope=nvpDictionary["Slope"].Get<double>();
      if(nvpDictionary.ContainsKey("Score")) candidate.Score=nvpDictionary["Score"].Get<double>();
      if(nvpDictionary.ContainsKey("AnnualizedReturn")) candidate.AnnualizedReturn=nvpDictionary["AnnualizedReturn"].Get<double>();
      if(nvpDictionary.ContainsKey("SharpeRatio")) candidate.SharpeRatio=nvpDictionary["SharpeRatio"].Get<double>();
      if(nvpDictionary.ContainsKey("RSquared")) candidate.RSquared=nvpDictionary["RSquared"].Get<double>();
      if(nvpDictionary.ContainsKey("BetaMonths")) candidate.BetaMonths=nvpDictionary["BetaMonths"].Get<int>();
      if(nvpDictionary.ContainsKey("Beta")) candidate.Beta=nvpDictionary["Beta"].Get<double>();
      if(nvpDictionary.ContainsKey("Reason")) candidate.Reason=nvpDictionary["Reason"].Get<String>();
      return candidate;
    }
    public static String Header()
    {
      StringBuilder sb=new StringBuilder();
      sb.Append("Symbol,AnalysisDate,PriceSlope,ProfitMarginSlope,EPSSlope,Volatility,Volume,Slope,Score,AnnualizedReturn,SharpeRatio,RSquared,Beta,BetaMonths");
      return sb.ToString();
    }
    public override String ToString()
    {
      StringBuilder sb=new StringBuilder();
      sb.Append(Symbol).Append(",").Append(AnalysisDate.ToShortDateString()).Append(",").Append(PriceSlope).Append(",").Append(ProfitMarginSlope).Append(",").Append(EPSSlope).Append(",").Append(Volatility).Append(",").Append(Volume).Append(",").Append(Slope).Append(",").Append(Score).Append(",").Append(AnnualizedReturn).Append(",").Append(SharpeRatio).Append(",");
      sb.Append(RSquared).Append(",").Append(Beta).Append(",").Append(BetaMonths);
      return sb.ToString();
    }
  }
}

