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; } } }