我已经通过这个公式实现了超级:
BASIC UPPERBAND = (HIGH + LOW) / 2 + Multiplier * ATR
BASIC LOWERBAND = (HIGH + LOW) / 2 - Multiplier * ATR
FINAL UPPERBAND = IF( (Current BASICUPPERBAND < Previous FINAL UPPERBAND) and (Previous Close > Previous FINAL UPPERBAND)) THEN (Current BASIC UPPERBAND) ELSE Previous FINALUPPERBAND)
FINAL LOWERBAND = IF( (Current BASIC LOWERBAND > Previous FINAL LOWERBAND) and (Previous Close < Previous FINAL LOWERBAND)) THEN (Current BASIC LOWERBAND) ELSE Previous FINAL LOWERBAND)
SUPERTREND = IF(Current Close <= Current FINAL UPPERBAND ) THEN Current FINAL UPPERBAND ELSE Current FINAL LOWERBAND
我的代码是:
//returns supertrend value
public double get(int index) {
double finalUpperBand = finalUpperBand(index);
double finalLowerBand = finalLowerBand(index);
if (data.getBar(index).getClose() <= finalUpperBand){
return finalUpperBand;
}else {
return finalLowerBand;
}
}
//calculation upperband
private double finalUpperBand(int index){
double atr = new ATRIndicator(data).get(index);
double multiplier = 3 ;
double max = data.getBar(index).getMax();
double min = data.getBar(index).getMin();
double upperBand = ((max+min)/2) + (multiplier*atr) ;
if (upperBand < finalUpperBand(index-1) && data.getBar(index-1).getClose() > finalUpperBand(index-1) ){
return upperBand;
}else {
return finalUpperBand(index-1);
}
}
//calculation lowerband
private double finalLowerBand(int index){
double atr = new ATRIndicator(data).get(index);
double multiplier = 3 ;
double max = data.getBar(index).getMax();
double min = data.getBar(index).getMin();
double lowerBand = (max+min)/2 - (multiplier*atr) ;
if ( lowerBand > finalLowerBand(index-1) && data.getBar(index-1).getClose() < finalLowerBand(index-1) ){
return lowerBand;
}else {
return finalLowerBand(index-1);
}
}
但它不起作用,我知道问题出在递归方法上,但我无法根据公式找到出路!
我添加了基本操作的代码,但我不确定这是否就是超级趋势指标!
if (index == 0) {
return upperBand;
}
在 Ta4j 的帮助下;我开发了这个类并针对 SuperTrend 进行了测试,你可以尝试这个;
package sp.supertrend;
import java.util.Vector;
import java.util.stream.IntStream;
import org.ta4j.core.BarSeries;
import org.ta4j.core.indicators.ATRIndicator;
public class SuperTrendIndicator {
private BarSeries series;
private double multiplier;
private int length;
private ATRIndicator atri;
private Vector<Double> values; // Vector for possibility to use parallel stream
private Vector<Double> upperBands;
private Vector<Double> lowerBands;
private Vector<Boolean> isGreen;
public SuperTrendIndicator(BarSeries series, Double multiplier, int length) {
this.multiplier = multiplier;
this.length = length;
this.series = series;
calculate();
}
public SuperTrendIndicator(BarSeries series) {
this(series, 3.0, 10);
}
public SuperTrendIndicator(BarSeries series, Double multiplier) {
this(series, multiplier, 10);
}
private void calculate() {
setAtri(new ATRIndicator(getSeries(), getLength()));
values = new Vector<>(series.getBarCount());
upperBands = new Vector<>(series.getBarCount());
lowerBands = new Vector<>(series.getBarCount());
isGreen = new Vector<>(series.getBarCount());
IntStream.range(0, series.getBarCount()).forEach(i -> {
values.add(null);
upperBands.add(null);
lowerBands.add(null);
isGreen.add(true);
});
IntStream.range(length, series.getBarCount()).forEach(i -> values.set(i, get(i)));
}
public Double getValue(int index) {
return values.get(index);
}
private double get(int index) {
double finalBand;
isGreen.set(index, new Boolean(isGreen.get(index - 1)));
if (isGreen.get(index - 1)) {
finalBand = finalLowerBand(index);
if (getSeries().getBar(index).getClosePrice().doubleValue() <= finalBand) {
isGreen.set(index, false);
return finalUpperBand(index);
}
} else {
finalBand = finalUpperBand(index);
if (getSeries().getBar(index).getClosePrice().doubleValue() >= finalBand) {
isGreen.set(index, true);
return finalLowerBand(index);
}
}
return finalBand;
}
// calculation upperBand
public double finalUpperBand(int index) {
double band;
if (index < length)
return -1;
if (upperBands.get(index) != null)
return upperBands.get(index);
double atrVal = getAtri().getValue(index).doubleValue();
double max = getSeries().getBarData().get(index).getHighPrice().doubleValue();
double min = getSeries().getBarData().get(index).getLowPrice().doubleValue();
double upperBand = ((max + min) / 2) + (getMultiplier() * atrVal);
double fubPrev = finalUpperBand(index - 1);
if (fubPrev == -1 || upperBand < fubPrev || getSeries().getBar(index - 1).getClosePrice().doubleValue() > fubPrev) {
band = upperBand;
} else {
band = fubPrev;
}
upperBands.set(index, band); // for not to calculate again and again
return band;
}
// calculation lowerBand
public double finalLowerBand(int index) {
double band;
if (lowerBands.get(index) != null)
return lowerBands.get(index);
if (index < length)
return -1;
double atrVal = getAtri().getValue(index).doubleValue();
double max = getSeries().getBarData().get(index).getHighPrice().doubleValue();
double min = getSeries().getBarData().get(index).getLowPrice().doubleValue();
double lowerBand = (max + min) / 2 - (multiplier * atrVal);
double flbPrev = finalLowerBand(index - 1);
if (flbPrev == -1 || lowerBand > flbPrev || getSeries().getBar(index - 1).getClosePrice().doubleValue() < flbPrev) {
band = lowerBand;
} else {
band = flbPrev;
}
lowerBands.set(index, band); // for not to calculate again and again
return band;
}
public BarSeries getSeries() {
return series;
}
public double getMultiplier() {
return multiplier;
}
public int getLength() {
return length;
}
public void setSeries(BarSeries series) {
this.series = series;
}
public void setMultiplier(double multiplier) {
this.multiplier = multiplier;
}
public void setLength(int length) {
this.length = length;
}
private ATRIndicator getAtri() {
return atri;
}
private void setAtri(ATRIndicator atri) {
this.atri = atri;
}
public boolean getIsGreen(int index) {
return isGreen.get(index);
}
public String getSignal(int index) {
if (getIsGreen(index) == getIsGreen(index - 1))
return "";
if (getIsGreen(index))
return "Buy";
return "Sell";
}
}
您可以添加使用示例代码吗?