calculation of RSI(Relative Strength Index) Using ta4j java library is incorrect

Viewed 4078

This is my Class to fetch the list of OHLC (open, high, low, close) also the volume and date. i have separated each one of the arraylist for each stocksymbol. i have used my local API to fetch the data. To perform all these calculation i have used ta4j library for 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();
    }

}

This one is my calculation part to get the values of RSI. I have calculated another indicators also which is exactly correct according to my manual calculation of indicators but the problem seems to be in the calculation of 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 Answers
Related