using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MarketData.Numerical;
using MarketData.MarketDataModel;
using MarketData.DataAccess;
using MarketData.Cache;
using MarketData.Utils;

namespace MarketData.Generator.Indicators
{
  // ***********************************************************************************
  public class MVPIndicator
  {
    private static readonly double DAY_COUNT=15.00;
    private static readonly double MOMENTUM_MIN_DAYS=12.00;
    private MVPIndicator()              // Marc Minervini "M"omentum, "V"olume, "P"rice
    {
    }
    public static bool IsTrue(String symbol,DateTime pricingDate)
    {
      Prices prices=GBPriceCache.GetInstance().GetPrices(symbol,pricingDate,(int)DAY_COUNT+1);
      if(null==prices||DAY_COUNT+1>prices.Count) return false;
      double daysUp=0;
      double daysDown=0;
      bool qualifiesOnPrice=false;
      bool qualifiesOnVolume=false;
      bool qualifiesOnMomentum=false;

// Momentum Check
      for(int index=prices.Count-2;index>=0;index--)
      {
        Price currentPrice=prices[index];
        Price prevPrice=prices[index+1];
        if(currentPrice.Close>prevPrice.Close)daysUp++;
        else daysDown++;
      }
      if(0.00==daysDown) qualifiesOnMomentum=true;
      else qualifiesOnMomentum=daysUp>=MOMENTUM_MIN_DAYS?true:false;
      if(!qualifiesOnMomentum) return false;

// Volume Check
      double baseVolume=prices[prices.Count-1].Volume;
      for(int index=prices.Count-2;index>=0 && !qualifiesOnVolume;index--)
      {
        Price currentPrice=prices[index];
        double percentChangeInVolume=((double)currentPrice.Volume-baseVolume)/baseVolume;
        if(percentChangeInVolume>=.25)qualifiesOnVolume=true;
      }
      if(!qualifiesOnVolume)return false;

// Price check
      double cumulativeReturn=prices.GetCumulativeReturn();
      if(cumulativeReturn>=.20) qualifiesOnPrice=true;
      if(!qualifiesOnPrice) return false;

      return true;
    }
  }
}
