0

I wrote a method that counts average of sell currency exchange-course(ASK) and standard deviation of it , but i think that it isn't the easiest way to define such behavior so i need a help .

  1. In my opinion there is too much creating Bigdecimal values .

  2. I have also doubts about use Arraylist to getting values in order to count standard deviation , maybe it is better data structure to achieve that goal .

The method contains also counting average of buy currency exchange-course(BID in parsed file) but don't focus on it please.

package pl.parser.nbp;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Counting {
public void countAverageAndStandartDeviaton(String address){
    try
    {
        DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = df.newDocumentBuilder();
        Document doc = db.parse(address);
        doc.getDocumentElement().normalize();

        NodeList nList = doc.getElementsByTagName("Rate");

        List<BigDecimal> listForStandartDeviation = new ArrayList<>();
        BigDecimal averageOfBid = new BigDecimal("0");
        BigDecimal averageOfAsk = new BigDecimal("0");
        BigDecimal divisor = new BigDecimal(nList.getLength());

        for (int temp = 0; temp < nList.getLength(); temp++) {

            Node nNode = nList.item(temp);
            if (nNode.getNodeType() == Node.ELEMENT_NODE) {

                Element eElement = (Element) nNode;

                BigDecimal valueForBidAverage = new BigDecimal(eElement.getElementsByTagName("Bid").item(0).getTextContent());
                BigDecimal valueForStandartDeviation = new BigDecimal(eElement.getElementsByTagName("Ask").item(0).getTextContent());
                averageOfBid = averageOfBid.add(valueForBidAverage);
                averageOfAsk = averageOfAsk.add(valueForStandartDeviation);
                listForStandartDeviation.add(valueForStandartDeviation);


            }
        }
        averageOfBid = new BigDecimal(averageOfBid.divide(divisor).toString()).setScale(4, RoundingMode.HALF_UP);
        averageOfAsk = new BigDecimal(averageOfAsk.divide(divisor).toString());
        System.out.println(averageOfBid + " - BID Average");

        BigDecimal sumStandartDeviation = new BigDecimal("0");
        for(int i = 0 ; i<listForStandartDeviation.size(); i++){
            BigDecimal valueFromList = new BigDecimal(listForStandartDeviation.get(i).toString());
            sumStandartDeviation = sumStandartDeviation.add((valueFromList.subtract(averageOfAsk)).pow(2));
        }
        sumStandartDeviation = sumStandartDeviation.divide(divisor);
        sumStandartDeviation = new BigDecimal(Math.sqrt(sumStandartDeviation.doubleValue()))
                .setScale(4, RoundingMode.HALF_UP);
        System.out.println(sumStandartDeviation +  " - ASK Standart Deviation");

    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373

1 Answers1

0

It's not clear to me why you want to do so much of the calculation using BigDecimal rather than double arithmetic, when you end up reverting to double arithmetic to compute the square root anyway.

Here's an XPath 3.1 solution (which can of course be invoked easily from Java):

let $rates := //Rate
return (avg($rates/Bid), math:sqrt(sum($rates/(Ask*Ask))))
Michael Kay
  • 156,231
  • 11
  • 92
  • 164