public void populateChartAnalysis(final PriceAnalysisData currentPrice) {
    if (currentPrice == null
        || currentPrice.getPrice() == null
        || currentPrice.getPrice().getDateType() != TradeDateType.TRADING_DATE
        || currentPrice.getPrice().getVolume() == null
        || currentPrice.getPrice().getVolume() == 0) {
      return;
    }

    if (currentPrice.getPrice().getPriceDate().after(cal.getTime())) {
      System.err.print("");
    }

    final BigDecimal atr = atrHelper.processTick(currentPrice.getPrice());

    if (prevPrice == null) {
      prevPrice = currentPrice;
      return;
    }

    try {
      if (currentPrice.getPrice().getLow().doubleValue()
          <= prevPrice.getPrice().getHigh().doubleValue()) {
        return;
      }

      double threshold = 0.01;
      if (atr != null) {
        threshold = atr.doubleValue();
      } else {
        threshold = atrHelper.getRollingATR();
      }

      PriceAnalysisElementData pae = null;
      if (currentPrice.getPrice().getLow().doubleValue()
          >= prevPrice.getPrice().getHigh().doubleValue() + threshold) {
        pae = new PriceAnalysisElementData();
        pae.setAnalysisType(ChartAnalysisType.GAP_UP);
        pae.setElementType(ChartElementType.PRICE);
      } else if (currentPrice.getPrice().getHigh().doubleValue()
          <= prevPrice.getPrice().getLow().doubleValue() - threshold) {
        pae = new PriceAnalysisElementData();
        pae.setAnalysisType(ChartAnalysisType.GAP_DOWN);
        pae.setElementType(ChartElementType.PRICE);
      }

      if (pae != null) {
        currentPrice.getPriceAnalysisElements().add(pae);
      }
    } finally {
      prevPrice = currentPrice;
    }
  }
  public static List<PriceAnalysisData> analyzeDailyPrices(final List<InstrumentPriceModel> pvList)
      throws ApplicationException {
    if (pvList == null || pvList.size() <= 2) {
      return null;
    }

    if (pvList.get(0).getPriceDate().after(pvList.get(1).getPriceDate())) {
      Collections.reverse(pvList);
    }

    final List<PriceAnalysisData> analyzedPrices = new ArrayList<PriceAnalysisData>();

    final PriceMovingAverageHelper pMAHelper10dEma =
        new PriceMovingAverageHelper(10, false); // 10 EMA
    final PriceMovingAverageHelper pMAHelper20dEma =
        new PriceMovingAverageHelper(20, false); // 20 EMA
    final PriceMovingAverageHelper pMAHelper50dSma =
        new PriceMovingAverageHelper(50, true); // 50 SMA
    final PriceMovingAverageHelper pMAHelper200dSma =
        new PriceMovingAverageHelper(200, true); // 200 SMA

    final VolumeMovingAverageHelper vMAHelper = new VolumeMovingAverageHelper(50, true); // 50 SMA

    final MAAnalysisHelper ma10AnalysisHelper = new MAAnalysisHelper(ChartElementType.PRICE_MA_10);
    final MAAnalysisHelper ma20AnalysisHelper = new MAAnalysisHelper(ChartElementType.PRICE_MA_20);
    final MAAnalysisHelper ma50AnalysisHelper = new MAAnalysisHelper(ChartElementType.PRICE_MA_50);
    final MAAnalysisHelper ma200AnalysisHelper =
        new MAAnalysisHelper(ChartElementType.PRICE_MA_200);
    final GapAnalysisHelper gapAnalysisHelper = new GapAnalysisHelper();

    final ATRHelper atr14Helper = new ATRHelper(14);

    final HighAnalysisHelper highAnalysisHelper = new HighAnalysisHelper();

    BigDecimal lastPriceMA10 = null;
    BigDecimal lastPriceMA20 = null;
    BigDecimal lastPriceMA50 = null;
    BigDecimal lastPriceMA200 = null;
    BigDecimal lastVolMA = null;

    for (final InstrumentPriceModel aPrice : pvList) {
      if (aPrice == null
          || aPrice.getDateType() == null
          || TradeDateType.TRADING_DATE != aPrice.getDateType()
          || aPrice.getVolume() == null
          || aPrice.getClose() == null
          || aPrice.getVolume() <= 0) {
        continue;
      }

      final PriceAnalysisData analyzedPrice = new PriceAnalysisData();
      analyzedPrice.setPrice(aPrice);

      // first calculate moving averages because we would need it in checking the signals
      final BigDecimal priceMA10 = pMAHelper10dEma.processTick(aPrice, lastPriceMA10);

      final BigDecimal priceMA20 = pMAHelper20dEma.processTick(aPrice, lastPriceMA20);
      final BigDecimal priceMA50 = pMAHelper50dSma.processTick(aPrice, lastPriceMA50);
      final BigDecimal priceMA200 = pMAHelper200dSma.processTick(aPrice, lastPriceMA200);
      final BigDecimal volMA = vMAHelper.processTick(aPrice, lastVolMA);

      final BigDecimal atr14 = atr14Helper.processTick(aPrice);

      // set the MA and other analyzed data now..
      analyzedPrice.setPrice10dEma(priceMA10);
      analyzedPrice.setPrice20dEma(priceMA20);
      analyzedPrice.setPrice50dSma(priceMA50);
      analyzedPrice.setPrice200dSma(priceMA200);
      analyzedPrice.setVol50dSma(volMA);
      analyzedPrice.setAtr14d(atr14);

      lastPriceMA10 = priceMA10;
      lastPriceMA20 = priceMA20;
      lastPriceMA50 = priceMA50;
      lastPriceMA200 = priceMA200;
      lastVolMA = volMA;

      // analyze for signals now..
      ma200AnalysisHelper.populateChartAnalysis(analyzedPrice);
      ma50AnalysisHelper.populateChartAnalysis(analyzedPrice);
      ma20AnalysisHelper.populateChartAnalysis(analyzedPrice);
      ma10AnalysisHelper.populateChartAnalysis(analyzedPrice);
      gapAnalysisHelper.populateChartAnalysis(analyzedPrice);

      // analyze new-highs
      highAnalysisHelper.populateChartAnalysis(analyzedPrice);

      analyzedPrices.add(analyzedPrice);

      if (analyzedPrice.getPriceAnalysisElements().size() > 0) {
        StringBuffer buffy = new StringBuffer(analyzedPrice.getPrice().getPriceDate() + " : ");
        for (PriceAnalysisElementData pae : analyzedPrice.getPriceAnalysisElements()) {
          buffy.append(pae.getElementType() + " " + pae.getAnalysisType() + ",");
        }
        // System.err.println(buffy.toString());
      }
    }

    return analyzedPrices;
  }