这是我的类,用于获取OHLC列表(开放,高,低,关闭)以及音量和日期。我为每个stocksymbol分隔了每个arraylist。我已经使用我的本地API来获取数据。为了执行所有这些计算,我使用了ta4j库用于JAVA。
package com.infodev.util;
import com.google.gson.Gson;
import com.infodev.Model.Data;
import com.infodev.Model.Find;
import com.infodev.Pojo.RequestForTechnicalCalculation;
import org.apache.log4j.Logger;
import org.json.simple.JSONObject;
import org.springframework.http.*;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.math.BigDecimal;
public class ApiTestData {
static Logger logger = Logger.getLogger(ApiTestData.class);
private static Data[] a;
public ApiTestData(RequestForTechnicalCalculation requestForTechnicalCalculation) throws Exception {
//setting request body
JSONObject jsonObject = new JSONObject();
jsonObject.put("sectorId", requestForTechnicalCalculation.getSectorId());
//setting request headers
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
//setting httpEntity as the request for server post request
HttpEntity<?> httpEntity = new HttpEntity<>(jsonObject.toString(), httpHeaders);
//installing restTemplate
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
ResponseEntity<Find> returnedObject = restTemplate.exchange("http://localhost:8081/pull365", HttpMethod.POST, httpEntity, Find.class);
a = returnedObject.getBody().getData();
logger.info("ApiData " + new Gson().toJson(a));
}
public int getDataSize() {
return a.length;
}
public BigDecimal[] getOpen(int index) {
return a[index].getOpen();
}
public BigDecimal[] getHigh(int index) {
return a[index].getHigh();
}
public BigDecimal[] getLow(int index) {
return a[index].getLow();
}
public BigDecimal[] getClose(int index) {
return a[index].getClose();
}
public BigDecimal[] getVolume(int index) {
return a[index].getVolume();
}
public String[] getDates(int index) {
return a[index].getDates();
}
public String getSymbols(int index) {
logger.info("stock name " +new Gson().toJson(a[index].getStockName()));
return a[index].getStockName();
}
}
这是获取RSI值的计算部分。根据我的指标手动计算,我已经计算了另一个指标也是完全正确的,但问题似乎在于RSI的计算。 package com.infodev.Services.Indicators;
import com.infodev.Pojo.RequestForTechnicalCalculation;
import com.infodev.util.ApiTestData;
import eu.verdelhan.ta4j.Decimal;
import eu.verdelhan.ta4j.Tick;
import eu.verdelhan.ta4j.TimeSeries;
import eu.verdelhan.ta4j.indicators.candles.LowerShadowIndicator;
import eu.verdelhan.ta4j.indicators.helpers.*;
import eu.verdelhan.ta4j.indicators.oscillators.CMOIndicator;
import eu.verdelhan.ta4j.indicators.oscillators.PPOIndicator;
import eu.verdelhan.ta4j.indicators.oscillators.StochasticOscillatorDIndicator;
import eu.verdelhan.ta4j.indicators.oscillators.StochasticOscillatorKIndicator;
import eu.verdelhan.ta4j.indicators.simple.*;
import eu.verdelhan.ta4j.indicators.statistics.*;
import eu.verdelhan.ta4j.indicators.trackers.*;
import eu.verdelhan.ta4j.indicators.trackers.bollinger.BollingerBandWidthIndicator;
import eu.verdelhan.ta4j.indicators.trackers.bollinger.BollingerBandsLowerIndicator;
import eu.verdelhan.ta4j.indicators.trackers.bollinger.BollingerBandsMiddleIndicator;
import eu.verdelhan.ta4j.indicators.trackers.bollinger.BollingerBandsUpperIndicator;
import eu.verdelhan.ta4j.indicators.volatility.MassIndexIndicator;
import eu.verdelhan.ta4j.indicators.volume.ChaikinMoneyFlowIndicator;
import eu.verdelhan.ta4j.indicators.volume.OnBalanceVolumeIndicator;
import org.apache.log4j.Logger;
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.springframework.stereotype.Service;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Service
public class IndicatorServiceImpl implements IndicatorService {
static Logger logger = Logger.getLogger(IndicatorServiceImpl.class);
private static DecimalFormat df = new DecimalFormat("###,###.##");
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
List<Tick> ticks;
List<Tick> tickList;
TimeSeries series;
ClosePriceIndicator closePrice;
SMAIndicator shortSma;
SMAIndicator longSma;
EMAIndicator shortEma;
RSIIndicator rsi;
MACDIndicator macd;
BollingerBandsMiddleIndicator bbm;
BollingerBandsLowerIndicator bbl;
BollingerBandsUpperIndicator bbh;
BollingerBandWidthIndicator bbw;
ApiTestData apiData;
String symbol;
String[] date;
BigDecimal[] volume;
BigDecimal[] close;
BigDecimal[] low;
BigDecimal[] high;
BigDecimal[] open;
@Override
public List<Map<Object, Object>> getIndicators(RequestForTechnicalCalculation requestForTechnicalCalculation) {
System.out.println("service state");
List<Map<Object, Object>> finalList = new ArrayList<>();
try {
apiData = new ApiTestData(requestForTechnicalCalculation);
logger.info("----" + apiData.getDataSize());
for (int i = 0; i < apiData.getDataSize(); i++) {
logger.info("----" + i);
// getting the symbol from the api
symbol = apiData.getSymbols(i);
date = apiData.getDates(i);
volume = apiData.getVolume(i);
close = apiData.getClose(i);
low = apiData.getLow(i);
high = apiData.getHigh(i);
open = apiData.getOpen(i);
if (date.length == 0 || volume.length == 0 || close.length == 0 ||
low.length == 0 || high.length == 0 || open.length == 0) {
finalList.add(makeEmptyObject());
} else {
makeCalculation(i);
finalList.add(makeIndicatorObject());
}
}
//return finalList;
} catch (Exception e) {
e.printStackTrace();
finalList.add(makeEmptyObject());
}
return finalList;
}
private void makeCalculation(int ii) throws ParseException {
//instating tick to change the ohlc to Tick class array
ticks = new ArrayList<>();
logger.info("----" + ticks.size());
for (int i = 0; i < close.length; i++) {
this.ticks.add(new Tick(new DateTime(DATE_FORMAT.parse(date[i])), open[i].doubleValue(), high[i].doubleValue()
, low[i].doubleValue(), close[i].doubleValue(), volume[i].doubleValue()));
}
//converting the array to the list of tick
//generating the time Series of the sample data
series = new TimeSeries(apiData.getSymbols(ii), ticks);
if (series == null) {
throw new IllegalArgumentException("Series cannot be null");
} else {
//close price indicator
closePrice = new ClosePriceIndicator(this.series);
logger.info("ClosePrice: " + closePrice.getValue(series.getEnd()));
// Simple moving averages
shortSma = new SMAIndicator(closePrice, 5);
logger.info("shortSMA: " + shortSma.getValue(series.getEnd()));
longSma = new SMAIndicator(closePrice, 20);
logger.info("longSMA: " + longSma.getValue(series.getEnd()));
// Exponential moving averages
shortEma = new EMAIndicator(closePrice, 5);
logger.info("shortEMA: " + shortEma.getValue(series.getEnd()));
longEma = new EMAIndicator(closePrice, 20);
logger.info("longEMA: " + longEma.getValue(series.getEnd()));
rsi = new RSIIndicator(closePrice, 14);
series.getLastTick().addTrade(100, rsi.getValue(series.getEnd()).toDouble());
//newTick.addTrade(100, rsi.getValue(series.getEnd()).toDouble());
logger.info("RsiIndicator: " + rsi.getValue(series.getEnd()));
// Standard deviation
sd = new StandardDeviationIndicator(closePrice, 20);
logger.info("StandardDeviationIndicator: " + sd.getValue(series.getEnd()));
//macd indicator
macd = new MACDIndicator(closePrice, 12, 26);
logger.info("MACD indicator: " + macd.getValue(series.getEnd()));
//bollingerbandsmiddle indicator
bbm = new BollingerBandsMiddleIndicator(longSma);
logger.info("Bollinger Bands Middle Indicator :" + bbm.getValue(series.getEnd()));
bbl = new BollingerBandsLowerIndicator(bbm, sd);
logger.info("Bollinger bands lower indicator :" + bbl.getValue(series.getEnd()));
bbh = new BollingerBandsUpperIndicator(bbm, sd);
logger.info("Bollinger bands upper indicator :" + bbh.getValue(series.getEnd()));
bbw = new BollingerBandWidthIndicator(bbh, bbm, bbl);
logger.info("Bollinger band width :" + bbw.getValue(series.getEnd()));
StringBuilder sb = new StringBuilder("timestamp,close,typical,variation,sma8,sma20,ema8,ema20,ppo,roc,rsi,williamsr,atr,sd\n");
/**
* Adding indicators values
*/
final int nbTick = series.getTickCount();
for (int i = 0; i < nbTick; i++) {
sb.append(series.getTick(i).getEndTime()).append(',')
.append(closePrice.getValue(i)).append(',')
.append(typicalPrice.getValue(i)).append(',')
.append(priceVariation.getValue(i)).append(',')
.append(shortSma.getValue(i)).append(',')
.append(longSma.getValue(i)).append(',')
.append(shortEma.getValue(i)).append(',')
.append(longEma.getValue(i)).append(',')
.append(ppo.getValue(i)).append(',')
.append(roc.getValue(i)).append(',')
.append(rsi.getValue(i)).append(',')
.append(williamsR.getValue(i)).append(',')
.append(atr.getValue(i)).append(',')
.append(sd.getValue(i)).append('\n');
}
/**
* Writing CSV file
*/
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter("C:\\Users\\Administrator\\Desktop\\fafa\\indicators.csv"));
writer.write(sb.toString());
} catch (IOException ioe) {
System.out.println(ioe);
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException ioe) {
}
}
}
}
private Map<Object, Object> makeIndicatorObject() {
// Map for indicator values.
try {
logger.info("map state of make indicator");
Map<Object, Object> indicators = new LinkedHashMap<>();
indicators.put("symbol", symbol);
indicators.put("ClosePrice", formatBigDecimal(closePrice.getValue(series.getEnd()).toDouble()));
indicators.put("ShortSMA", formatBigDecimal(shortSma.getValue(series.getEnd()).toDouble()));
indicators.put("LongSMA", formatBigDecimal(longSma.getValue(series.getEnd()).toDouble()));
indicators.put("ShortEMA", formatBigDecimal(shortEma.getValue(series.getEnd()).toDouble()));
indicators.put("LongEMA", formatBigDecimal(longEma.getValue(series.getEnd()).toDouble()));
indicators.put("RSI", formatBigDecimal(rsi.getValue(series.getEnd()).toDouble()));
indicators.put("SD", formatBigDecimal(sd.getValue(series.getEnd()).toDouble()));
indicators.put("MACD", formatBigDecimal(macd.getValue(series.getEnd()).toDouble()));
indicators.put("BBM", formatBigDecimal(bbm.getValue(series.getEnd()).toDouble()));
indicators.put("BBL", formatBigDecimal(bbl.getValue(series.getEnd()).toDouble()));
indicators.put("BBH", formatBigDecimal(bbh.getValue(series.getEnd()).toDouble()));
indicators.put("BBW", formatBigDecimal(bbw.getValue(series.getEnd()).toDouble()));
return indicators;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private BigDecimal formatBigDecimal(double value) {
try {
return new BigDecimal(df.format(value));
} catch (Exception e) {
return new BigDecimal(0);
}
}
private Map<Object, Object> makeEmptyObject() {
logger.info("map state of empty object");
Map<Object, Object> indicators = new LinkedHashMap<>();
indicators.put("symbol", symbol);
indicators.put("ClosePrice", new BigDecimal(0));
indicators.put("ShortSMA", new BigDecimal(0));
indicators.put("LongSMA", new BigDecimal(0));
indicators.put("ShortEMA", new BigDecimal(0));
indicators.put("LongEMA", new BigDecimal(0));
indicators.put("RSI", new BigDecimal(0));
indicators.put("SD", new BigDecimal(0));
indicators.put("MACD", new BigDecimal(0));
indicators.put("BBM", new BigDecimal(0));
indicators.put("BBL", new BigDecimal(0));
indicators.put("BBH", new BigDecimal(0));
indicators.put("BBW", new BigDecimal(0));
return indicators;
}
}
This is the Json Output from the local API that is used in the first class (ApiTestData)