/*
* Copyright (c) 2004-2011 Marco Maccaferri and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marco Maccaferri - initial API and implementation
*/
package org.eclipsetrader.core.ats.engines;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipsetrader.core.charts.IDataSeries;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
public abstract class IndicatorFunction extends ScriptableObject {
private static final long serialVersionUID = -9191442400382251716L;
public static final String PROP_SERIES = "SERIES";
protected IDataSeries source;
protected IDataSeries series;
protected final PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
private final PropertyChangeListener changeListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
calculate();
}
};
public IndicatorFunction() {
}
public IndicatorFunction(BarsDataSeriesFunction bars) {
this.source = bars.getSeries();
bars.addPropertyChangeListener(BarsDataSeriesFunction.PROP_BARS, changeListener);
}
public IndicatorFunction(IndicatorFunction indicator) {
this.source = indicator.getSeries();
indicator.addPropertyChangeListener(IndicatorFunction.PROP_SERIES, changeListener);
}
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
changeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
changeSupport.removePropertyChangeListener(propertyName, listener);
}
protected abstract void calculate();
/* (non-Javadoc)
* @see org.mozilla.javascript.ScriptableObject#getClassName()
*/
@Override
public String getClassName() {
return getClass().getSimpleName();
}
/* (non-Javadoc)
* @see org.mozilla.javascript.ScriptableObject#get(java.lang.String, org.mozilla.javascript.Scriptable)
*/
@Override
public Object get(String name, Scriptable start) {
if (name.equals("length")) { //$NON-NLS-1$
return series != null ? series.size() : 0;
}
return super.get(name, start);
}
/* (non-Javadoc)
* @see org.mozilla.javascript.ScriptableObject#get(int, org.mozilla.javascript.Scriptable)
*/
@Override
public Object get(int index, Scriptable start) {
if (series == null) {
return Context.getUndefinedValue();
}
try {
int s = series.size();
if (index >= 0 && index < s) {
return series.getValues()[index];
}
else {
return Context.getUndefinedValue();
}
} catch (RuntimeException e) {
throw Context.throwAsScriptRuntimeEx(e);
}
}
/* (non-Javadoc)
* @see org.mozilla.javascript.ScriptableObject#getIds()
*/
@Override
public Object[] getIds() {
int size = series.size();
Integer[] ids = new Integer[size];
for (int i = 0; i < size; ++i) {
ids[i] = i;
}
return ids;
}
/* (non-Javadoc)
* @see org.mozilla.javascript.ScriptableObject#has(int, org.mozilla.javascript.Scriptable)
*/
@Override
public boolean has(int index, Scriptable start) {
return index >= 0 && index < series.size();
}
public Object jsFunction_crosses(IndicatorFunction other, Object bar) {
return series.cross(other.series, (IAdaptable) bar);
}
public Object jsFunction_first() {
return series.getFirst();
}
public Object jsFunction_last() {
return series.getLast();
}
public Object jsFunction_highest() {
return series.getHighest();
}
public Object jsFunction_lowest() {
return series.getLowest();
}
public IDataSeries getSeries() {
return series;
}
}