using MarketData.DataAccess;
using MarketData.MarketDataModel;
using MarketData.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace MarketData.Generator.MGSHMomentum
{
  public class CandidateSelector
  {
    private static int DAY_COUNT=252;
    private CandidateSelector()
    {
    }
    public static String SelectBestCandidateSymbol(MGSHQualityIndicator qualityIndicator,List<String> candidates,String defaultCandidate,DateTime analysisDate)
    {
      String bestCandidate=defaultCandidate;
      try
      {
        if(null==candidates||0==candidates.Count||Utility.IsEpoch(analysisDate)||null==defaultCandidate)return bestCandidate;
        List<QualityIndicatorCandidate> qualityIndicatorCandidates=new List<QualityIndicatorCandidate>();
        foreach(String candidate in candidates)
        {
          Prices prices=PricingDA.GetPrices(candidate,analysisDate,DAY_COUNT);
          if(null==prices||0==prices.Count)continue;
          QualityIndicatorCandidate qualityIndicatorCandidate=new QualityIndicatorCandidate();
          qualityIndicatorCandidate.Symbol=candidate;
          qualityIndicatorCandidate.IDIndicator=IDIndicator.Calculate(prices);
          qualityIndicatorCandidate.Score=ScoreIndicator.Calculate(prices);
          qualityIndicatorCandidates.Add(qualityIndicatorCandidate);
        }
        if(0==qualityIndicatorCandidates.Count)return bestCandidate;
        if(qualityIndicator.Quality.Equals(MGSHQualityIndicator.QualityType.IDIndicator))
        {
          qualityIndicatorCandidates=(from QualityIndicatorCandidate qualityIndicatorCandidate in qualityIndicatorCandidates orderby qualityIndicatorCandidate.IDIndicator ascending select qualityIndicatorCandidate).ToList();
        }
        else
        {
          qualityIndicatorCandidates=(from QualityIndicatorCandidate qualityIndicatorCandidate in qualityIndicatorCandidates orderby qualityIndicatorCandidate.Score descending select qualityIndicatorCandidate).ToList();
        }
        return qualityIndicatorCandidates.Take(1).FirstOrDefault().Symbol;
      }                                                                                                     
      catch(Exception exception)
      {
        MDTrace.WriteLine(String.Format("{0}",exception.ToString()));
        return bestCandidate;
      }
    }
    public static QualityIndicatorCandidate SelectBestCandidate(MGSHQualityIndicator qualityIndicator,List<String> candidates,String defaultCandidate,DateTime analysisDate)
    {
      QualityIndicatorCandidate bestCandidate=new QualityIndicatorCandidate();
      try
      {
        if(null==candidates||0==candidates.Count||Utility.IsEpoch(analysisDate)||null==defaultCandidate)return null;
        List<QualityIndicatorCandidate> qualityIndicatorCandidates=new List<QualityIndicatorCandidate>();
        foreach(String candidate in candidates)
        {
          Prices prices=PricingDA.GetPrices(candidate,analysisDate,DAY_COUNT);
          Fundamental fundamental=FundamentalDA.GetFundamentalMaxDate(candidate,analysisDate);
          if(null==prices||0==prices.Count)continue;
          QualityIndicatorCandidate qualityIndicatorCandidate=new QualityIndicatorCandidate();
          qualityIndicatorCandidate.Symbol=candidate;
          qualityIndicatorCandidate.IDIndicator=IDIndicator.Calculate(prices);
          qualityIndicatorCandidate.Score=ScoreIndicator.Calculate(prices);
          qualityIndicatorCandidate.CumReturn252=prices.GetCumulativeReturn();
          qualityIndicatorCandidate.DayCount=DAY_COUNT;
          qualityIndicatorCandidate.Return1D=prices.GetReturn1D();
          if(null!=fundamental)
          {
            qualityIndicatorCandidate.PE=fundamental.PE;
            qualityIndicatorCandidate.Beta=fundamental.Beta;
          }
          qualityIndicatorCandidates.Add(qualityIndicatorCandidate);
        }
        if(0==qualityIndicatorCandidates.Count)return bestCandidate;

        if(qualityIndicator.Quality.Equals(MGSHQualityIndicator.QualityType.IDIndicator))
        {
          qualityIndicatorCandidates=(from QualityIndicatorCandidate qualityIndicatorCandidate in qualityIndicatorCandidates orderby qualityIndicatorCandidate.IDIndicator ascending select qualityIndicatorCandidate).ToList();
        }
        else
        {
          qualityIndicatorCandidates=(from QualityIndicatorCandidate qualityIndicatorCandidate in qualityIndicatorCandidates orderby qualityIndicatorCandidate.Score descending select qualityIndicatorCandidate).ToList();
        }
        return qualityIndicatorCandidates.Take(1).FirstOrDefault();
      }                                                                                                 
      catch(Exception exception)
      {
        MDTrace.WriteLine(String.Format("{0}",exception.ToString()));
        return bestCandidate;
      }
    }                                                                                                        
  }
}
