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

namespace MarketData.MarketDataModel
{
  public class RSIDictionary : Dictionary<DateTime,RSIElement>
  {
  }
  public class RSICollection : List<RSIElement>
  {
    public RSICollection()
    {
    }
    public RSICollection(List<RSIElement> rsiElements)
    {
      foreach(RSIElement rsiElement in rsiElements)Add(rsiElement);
    }
    public RSICollection Top(int count,int offset=0)
    {
      if (count > Count) return null;
      RSICollection rsiCollection = new RSICollection();
      for (int index = 0+offset; index<Count&&rsiCollection.Count<count; index++)
      {
        rsiCollection.Add(this[index]);
      }
      return rsiCollection;
    }
    public RSICollection Bottom(int count,int offset=0)
    {
      if (count > Count) return null;
      RSICollection rsiCollection = new RSICollection();
      for (int index = Count-1-offset; index>=0 && rsiCollection.Count<count; index--)
      {
        rsiCollection.Add(this[index]);
      }
      return rsiCollection;
    }
    public RSIDictionary ToDictionary()
    {
      RSIDictionary dictionary=new RSIDictionary();
      foreach(RSIElement rsiElement in this)dictionary.Add(rsiElement.Date,rsiElement);
      return dictionary;
    }
    public double AverageGain()
    {
      double averageGain=(from RSIElement rsiElement in this select rsiElement.Gain).ToList().Sum()/(double)Count;
      return averageGain;
    }
    public double AverageLoss()
    {
      double averageLoss=(from RSIElement rsiElement in this select rsiElement.Loss).ToList().Sum()/(double)Count;
      return averageLoss;
    }
  }
  public class RSIElement
  {
    public String Symbol{get;set;}
    public DateTime Date{get;set;}
    public double Close{get;set;}
    public double Change{get;set;}
    public double Gain{get;set;}
    public double Loss{get;set;}
    public double AverageGain{get;set;}
    public double AverageLoss{get;set;}
    public double RS{get;set;}
    public double RSI{get;set;}
    public int RSIDays{get;set;}
    public static String Header()
    {
      return "Symbol,Date,Close,Change,Gain,Loss,AverageGain,AverageLoss,RS,RSI,RSIDays";
    }
    public override String ToString()
    {
      StringBuilder sb=new StringBuilder();
      sb.Append(Utility.AddQuotes(Symbol)).Append(",");
      sb.Append(Utility.AddQuotes(Utility.DateTimeToStringMMHDDHYYYY(Date))).Append(",");
      sb.Append(Utility.AddQuotes(Utility.FormatCurrency(Close))).Append(",");
      sb.Append(Utility.AddQuotes(Utility.FormatCurrency(Change))).Append(",");
      sb.Append(Utility.AddQuotes(Utility.FormatCurrency(Gain))).Append(",");
      sb.Append(Utility.AddQuotes(Utility.FormatCurrency(Loss))).Append(",");
      sb.Append(Utility.AddQuotes(Utility.FormatCurrency(AverageGain))).Append(",");
      sb.Append(Utility.AddQuotes(Utility.FormatCurrency(AverageLoss))).Append(",");
      sb.Append(Utility.AddQuotes(Utility.FormatNumber(RS,3))).Append(",");
      sb.Append(Utility.AddQuotes(Utility.FormatNumber(RSI,3))).Append(",");
      sb.Append(Utility.AddQuotes(Utility.FormatNumber(RSIDays)));
      return sb.ToString();
    }
  }
}
