0

I want to actively calculate the moving average of stock data using the formula below:

 public class Average {

    private static double usdJpy;   
    private int counter = 1;

    private double movingAverageUsdJpy_ = 100.5;

    public void calculateAverage(){

        ReadData myData = new ReadData();

        usdGbp = myData.getUsdGbp();
        usdJpy = myData.getUsdJpy();

        System.out.println("Before: " + movingAverageUsdJpy_);

        movingAverageUsdJpy_ = (counter * movingAverageUsdJpy_ + usdJpy) / (counter + 1);

        counter++;

        System.out.println("Moving Average: " + movingAverageUsdJpy_);
    }

}

-> Counter is the number of elements in the array.

My question is since the stock data already has a moving average, I want to set my initial movingAverage value to that (e.g 97.883). However, every time I call my method, the latest value that my program calculated for the movingAverage will be overwritten by the initial value I have set earlier, hence giving me the wrong result. I can't really use final because the movingAverage needs to be updated each time I call the method so really stuck!

Is there a way to fix this problem??

Emir54
  • 21
  • 4
  • declare movingAverage as global, not inside the method – Anoop LL Sep 19 '16 at 13:50
  • 1
    Just for the record: you are aware of the fact that **double** might not be thing to use when making computations dealing with money? – GhostCat Sep 19 '16 at 13:56
  • I am a beginner so what is the best type to use when dealing with money? – Emir54 Sep 19 '16 at 13:59
  • When dealing with currency in Java, if you don't want to use any outside libraries you should use the `BigDecimal` class. – yitzih Sep 19 '16 at 14:52
  • Are you using the same instance of `Average` each time you calculate? Are the `getData()` methods working properly? – yitzih Sep 19 '16 at 14:57
  • Yep checked everything they're working fine, like I get the latest data rates with each call but it's just the moving average value that keeps getting reset to the original one I have set. – Emir54 Sep 19 '16 at 15:05
  • @Emir54, the formula appears to be working for me when I use my own values, the moving average changes. This would seem to indicate that the issue is not with the posted code. – yitzih Sep 19 '16 at 15:18
  • @yitzih Yes the code is working fine when I don't set an initial moving average value. But I think the problem was I didn't set it static as someone mentioned below – Emir54 Sep 19 '16 at 15:36
  • @Emir54 That makes sense. Be sure to set the counter variable to `static` as well. – yitzih Sep 19 '16 at 15:54
  • @yitzih Yep already done that thanks! – Emir54 Sep 19 '16 at 15:57

3 Answers3

2

Your formula is incorrect. If counter is the not-yet incremented value, then use

movingAverage = (counter * movingAverage + latestRate) / (counter + 1)

Then increment counter by 1. Note that if you want counter to be fixed in size (as is quite common when reporting financial data like this), then you need to keep that number of elements in memory.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • a more concise way would be `movingAverage = (counter * movingAverage + latestRate) / ++counter;`. This way you don't need to increment the counter separately – yitzih Sep 19 '16 at 14:54
  • That's true in Java, but note that in C and C++ the behaviour of that expression would be *undefined*. So I'd always write it my way. Do feel free to answer the question with that expression; let's see what Java folk think. – Bathsheba Sep 19 '16 at 15:06
0

You probably have something like:

class Something{
  public int calculateAverage(){
    int movingAverage = 98888;
    //more code to count average
  }
}

What you need to do is:

class Something{
  private int myAverage = 98888;

  public int calculateAverage(){
    //code to calculate using myAverage variable;
  }
}
Shadov
  • 5,421
  • 2
  • 19
  • 38
  • Paste your whole code in main post, whole method and where you calling all this. – Shadov Sep 19 '16 at 14:47
  • Even when I set myAverage as a global, each time calculateAverage() is called in my while loop (that is every minute), the latest movingAverage gets replaced with the initial myAverage. To put things into context, here is my terminal -> Before[1] calculation: 100.5, movingAverage: 101.15, USD/JPY rate is : 103.58, Before[2]: 100.5 -> The before value is set to movingAverage but it just takes the value I declared in the global initially. The value for before[2] is supposed to be 101.15 but isn't. – Emir54 Sep 19 '16 at 14:50
  • Show us where you call this method, that means where you do `calculateAverage();`. Are you sure you are not creating another instance of Average? Maybe do this: ignore all what I just wrote and add 'static' to `movingAverageUsdJpy_ ` that is `private double static movingAverageUsdJpy_`. – Shadov Sep 19 '16 at 15:20
  • Yess that seems to have fixed the problem thanks a lot! And this is how I call calculateAverage() -> `Average myAverage = new Average(); myAverage.calculateAverage();` Is this the correct way of creating the instance? – Emir54 Sep 19 '16 at 15:34
  • Yes, but if variable is not static then each instance has it's own value , when you do `new Average()` you create new average object and it has default value of the variable, you need to operate on the same instance at all times. Sometimes that is very hard, especially for beginners, so I suggested that you make a variable static, that means every time you do `new Average()` it doesn't matter, because value of this variable is tied to the class, not the specific instance. – Shadov Sep 19 '16 at 15:39
  • Now you should also add static to the calculate method and to counter variable, and do `Average.calculate()` instead of this `Average myAverage = new Average(); myAverage.calculateAverage();`. – Shadov Sep 19 '16 at 15:42
  • This seems bit high level for me but thanks a lot the program is working :) – Emir54 Sep 19 '16 at 16:19
-1

Create a new private field used for storing the previous average. I'm not very familiar with moving averages per say, but using the formula you've provided I've adjusted things a bit. Note, typically an underscore is used to indicate that a class level variable is private

private double movingAverage_;
private double prevAverage_ = 97.883;

public void calculateMovingAverage()
{
    movingAverage_ = prevAverage_ + (latestRate - prevAverage_)/counter;
    prevAverage_ = movingAverage_;

    // finish other logic
}
jseashell
  • 745
  • 9
  • 19