package jtrade.marketfeed;
import jtrade.indicator.AbstractIndicator;
import jtrade.indicator.Median;
public class MedianCleaner extends AbstractIndicator implements Cleaner {
private double multiple;
private Median median;
private long t0;
private double v0;
public MedianCleaner(int period, double multiple) {
this.multiple = multiple;
median = new Median(period);
}
@Override
public void reset() {
median.reset();
t0 = 0;
v0 = 0;
}
@Override
public double update(long t, double v) {
if (t < 0 || (t0 >= 0 && t < t0) || v != v || v <= 0) {
return Double.NaN;
}
if (v0 <= 0) {
t0 = t;
v0 = v;
return v;
}
double logReturn = Math.log(v / v0);
double tDiff = Math.sqrt(t - t0) / 86400.0;
double adjReturn = Math.abs(logReturn / tDiff);
double adjReturnMedian = adjReturn > 0 ? median.update(t, adjReturn) : median.get();
if (adjReturn != adjReturn) {
return Double.NaN;
}
if (adjReturnMedian > 0.0 && adjReturn > adjReturnMedian * multiple) {
return Double.NaN;
}
t0 = t;
v0 = v;
return v;
}
@Override
public double get() {
return v0;
}
}