计算RSI(相对强弱指数)使用ta4j java库是不正确的

时间:2017-08-10 07:54:07

标签: java json hibernate libs technical-indicator

这是我的类,用于获取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)

0 个答案:

没有答案