package jtrade.indicator;
import jtrade.util.DoubleBuffer;
import jtrade.util.DoubleSkipList;
/**
* Fast running median with O(log n) updates where n is the window size
* http://code
* .activestate.com/recipes/576930-efficient-running-median-using-an-indexable
* -skipli/
*
* @author jonkle
*/
public class Median extends AbstractIndicator {
int period;
double percentile;
DoubleBuffer buf;
DoubleSkipList skip;
double value;
public Median() {
this(100, 0.5);
}
public Median(int period) {
this(period, 0.5);
}
public Median(int period, double percentile) {
this.period = period;
this.percentile = percentile;
buf = new DoubleBuffer(period);
skip = new DoubleSkipList(period);
value = Double.NaN;
}
@Override
public void reset() {
buf.clear();
skip.clear();
value = Double.NaN;
}
@Override
public double update(long t, double v) {
buf.push(v);
skip.add(v);
value = skip.get((int) (skip.size() * percentile));
if (skip.size() >= period) {
skip.remove(buf.first());
}
return value;
}
@Override
public double get() {
return value;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Median [value=");
sb.append(get());
sb.append(", period=");
sb.append(period);
sb.append("]");
return sb.toString();
}
}