/*
* 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.ui.internal.providers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.graphics.Image;
import org.eclipsetrader.core.feed.ITrade;
import org.eclipsetrader.core.views.IDataProvider;
import org.eclipsetrader.core.views.IDataProviderFactory;
import org.eclipsetrader.ui.UIConstants;
import org.eclipsetrader.ui.internal.UIActivator;
public class TrendFactory extends AbstractProviderFactory {
private Image stable;
private Image up;
private Image down;
public class DataProvider implements IDataProvider {
private Map<IAdaptable, List<Double>> values = new HashMap<IAdaptable, List<Double>>();
public DataProvider() {
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.views.IDataProvider#init(org.eclipse.core.runtime.IAdaptable)
*/
@Override
public void init(IAdaptable adaptable) {
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.views.IDataProvider#getFactory()
*/
@Override
public IDataProviderFactory getFactory() {
return TrendFactory.this;
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.views.IDataProvider#getValue(org.eclipse.core.runtime.IAdaptable)
*/
@Override
public IAdaptable getValue(IAdaptable adaptable) {
ITrade trade = (ITrade) adaptable.getAdapter(ITrade.class);
if (trade != null && trade.getPrice() != null && trade.getTime() != null) {
List<Double> oldTrades = values.get(adaptable);
if (oldTrades == null) {
oldTrades = new ArrayList<Double>();
values.put(adaptable, oldTrades);
}
Double oldTrade = oldTrades.size() != 0 ? oldTrades.get(oldTrades.size() - 1) : null;
if (oldTrade == null || !oldTrade.equals(trade.getPrice())) {
oldTrades.add(trade.getPrice());
if (oldTrades.size() > 5) {
oldTrades.remove(0);
}
}
double direction = oldTrades.size() > 1 ? getSlope(oldTrades.toArray(new Double[oldTrades.size()])) : 0.0;
Image value = direction == 0 ? stable : direction < 0 ? down : up;
return new ImageValue(value);
}
return null;
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.views.IDataProvider#dispose()
*/
@Override
public void dispose() {
}
}
public static class ImageValue implements IAdaptable {
private final Image value;
public ImageValue(Image value) {
this.value = value;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof IAdaptable)) {
return false;
}
Image s = (Image) ((IAdaptable) obj).getAdapter(Image.class);
return s == value;
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
*/
@Override
@SuppressWarnings({
"unchecked", "rawtypes"
})
public Object getAdapter(Class adapter) {
if (adapter.isAssignableFrom(Image.class)) {
return value;
}
return null;
}
}
public TrendFactory() {
ImageRegistry registry = UIActivator.getDefault().getImageRegistry();
stable = registry.get(UIConstants.TREND_STABLE_ICON);
up = registry.get(UIConstants.TREND_UP_ICON);
down = registry.get(UIConstants.TREND_DOWN_ICON);
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.views.IDataProviderFactory#createProvider()
*/
@Override
public IDataProvider createProvider() {
return new DataProvider();
}
/* (non-Javadoc)
* @see org.eclipsetrader.core.views.IDataProviderFactory#getType()
*/
@Override
@SuppressWarnings("rawtypes")
public Class[] getType() {
return new Class[] {
Image.class,
};
}
protected int compareValues(Number o1, Number o2) {
if (o1 != null && o2 != null) {
if (o1.doubleValue() < o2.doubleValue()) {
return -1;
}
if (o1.doubleValue() > o2.doubleValue()) {
return 1;
}
return 0;
}
return 0;
}
protected double getSlope(Double[] values) {
int numberPlotPoints = 0;
double sumxx = 0;
double sumxy = 0;
double sumx = 0;
double sumy = 0;
for (int i = 0; i < values.length; i++, numberPlotPoints++) {
double x = numberPlotPoints;
double y = values[i];
sumx += x;
sumy += y;
sumxx += x * x;
sumxy += x * y;
}
double n = numberPlotPoints;
double Sxx = sumxx - sumx * sumx / n;
double Sxy = sumxy - sumx * sumy / n;
double b = Sxy / Sxx;
return b;
}
}