title: calculation of RSI(Relative Strength Index) Using ta4j java library is incorrect
body: <p>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 <a href="https://github.com/ta4j/ta4j" rel="nofollow noreferrer">ta4j</a> library for JAVA.</p>
  
  <pre><code>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&lt;?&gt; httpEntity = new HttpEntity&lt;&gt;(jsonObject.toString(), httpHeaders);
          //installing restTemplate
          RestTemplate restTemplate = new RestTemplate();
          restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
  
          ResponseEntity&lt;Find&gt; 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();
      }
  
  }
  </code></pre>
  
  <p>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;</p>
  
  <pre><code>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&lt;Tick&gt; ticks;
      List&lt;Tick&gt; 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&lt;Map&lt;Object, Object&gt;&gt; getIndicators(RequestForTechnicalCalculation requestForTechnicalCalculation) {
          System.out.println("service state");
          List&lt;Map&lt;Object, Object&gt;&gt; finalList = new ArrayList&lt;&gt;();
          try {
              apiData = new ApiTestData(requestForTechnicalCalculation);
              logger.info("----" + apiData.getDataSize());
              for (int i = 0; i &lt; 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&lt;&gt;();
          logger.info("----" + ticks.size());
          for (int i = 0; i &lt; 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 &lt; 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&lt;Object, Object&gt; makeIndicatorObject() {
          // Map for indicator values.
          try {
              logger.info("map state of make indicator");
              Map&lt;Object, Object&gt; indicators = new LinkedHashMap&lt;&gt;();
              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&lt;Object, Object&gt; makeEmptyObject() {
          logger.info("map state of empty object");
          Map&lt;Object, Object&gt; indicators = new LinkedHashMap&lt;&gt;();
          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;
      }
  }
  </code></pre>
  
  <p><a href="https://gist.github.com/s-kiips/a69a4e3a625a8d5cb00bf071c77f78ab" rel="nofollow noreferrer">This is the Json Output from the local API that is used in the first class (ApiTestData) </a></p>