Skip to content

How to create Real time Chart #4

@frared358

Description

@frared358

I want to show real time data in chart, the real time data will come from api.
present I have made a chart which shows static data, there are 2 line graph in one chart
I have implemented TA-Lib library for more Indicators in Sci-chart

I've tried many ways to display realtime data in chart it is not working, So I just want to know how to update chart every time when I get a data from api

So please help me how to implement the real time data in Sci-Chart

CODE

public class CreateMultiPaneStockChartsFragment extends ExampleBaseFragment {
    private static final String RSI = "RSI";
    @BindView(R.id.rsiChart)
    SciChartSurface rsiChart;
    private final SciChartVerticalGroup verticalGroup = new SciChartVerticalGroup();
    private final DoubleRange sharedXRange = new DoubleRange();
    
    @Override
    protected int getLayoutId() {
        return R.layout.example_multipane_stock_charts_fragment;
    }

    @Override
    public boolean showDefaultModifiersInToolbar() {
        return false;
    }

    @Override
    protected void initExample() {
        final PriceSeries priceData = DataManager.getInstance().getPriceDataEurUsd(getActivity());  //get data form .csv file
        final RsiPaneModel rsiPaneModel = new RsiPaneModel(sciChartBuilder, priceData);
        initChart(rsiChart, rsiPaneModel, false);
    }

    private static class RsiPaneModel extends BasePaneModel {
        public RsiPaneModel(SciChartBuilder builder, PriceSeries prices) {
            super(builder, RSI, "0.00", false);

            final MovingAverage.MacdPoints macdPoints = MovingAverage.macd(prices.getCloseData(), 12, 25, 9);  //From Moving Average Class

            final XyDataSeries<Date, Double> smaSeries = builder.newXyDataSeries(Date.class, Double.class).withSeriesName("SMA").build();   //ArrayList<String> al=new ArrayList<String>();  ..Java List Interface
            final XyDataSeries<Date, Double> macdSeries = builder.newXyDataSeries(Date.class, Double.class).withSeriesName("MACD").build();   //ArrayList<String> al=new ArrayList<String>();  ..Java List Interface

            appendSmaData(prices, smaSeries,builder);
            appendMacdData(prices, macdSeries,builder, macdPoints);

            Collections.addAll(annotations,
                    builder.newAxisMarkerAnnotation().withY1(macdSeries.getYValues().get(macdSeries.getCount() - 1)).withYAxisId("MACD").build(),
                    builder.newAxisMarkerAnnotation().withY1(smaSeries.getYValues().get(smaSeries.getCount() - 1)).withYAxisId("sma").build());
        }

        private void appendSmaData(PriceSeries prices, XyDataSeries<Date, Double> smaSeries,SciChartBuilder builder) {
            final Core core = new Core();
            final MInteger begin = new MInteger();
            final MInteger length = new MInteger();
            final List<Double> closeData = prices.getCloseData();

            // copy data from List<Double> to double[] array because it's required by TA-Lib
            final int size = closeData.size();
            final double[] closeDataArray = new double[size];
            final double[] rsiData = new double[size];
            for (int i = 0; i < size; i++) {
                closeDataArray[i] = closeData.get(i);
            }

            // calculate RSI
            final int period = 14;
            final RetCode retCode = core.sma(0, closeDataArray.length - 1, closeDataArray, period, begin, length, rsiData);
            if(retCode == RetCode.Success) {
                final List<Date> dateData = prices.getDateData();
                final int beginIndex = begin.value;
                final int endIndex = beginIndex + length.value;

                // append NaN values for points which we can't calculate RSI
                for (int i = 0; i < beginIndex; i++) {
                    smaSeries.append(dateData.get(i), Double.NaN);
                }

                // append calculated RSI data
                for (int i = beginIndex; i < endIndex; i++) {
                    smaSeries.append(dateData.get(i), rsiData[i - beginIndex]);
                }
            }
            addRenderableSeries(builder.newLineSeries().withDataSeries(smaSeries).withStrokeStyle(Color.GREEN, 5f).withYAxisId(RSI).build());       // color rsi
        }

        private void appendMacdData(PriceSeries prices, XyDataSeries<Date, Double> macdSeries,SciChartBuilder builder, MovingAverage.MacdPoints macdPoints) {
            final Core core = new Core();
            final MInteger begin = new MInteger();
            final MInteger length = new MInteger();

            final List<Double> closeData = prices.getCloseData();

            // copy data from List<Double> to double[] array because it's required by TA-Lib
            final int size = closeData.size();
            final double[] closeDataArray = new double[size];
            final double[] rsiData = new double[size];
            for (int i = 0; i < size; i++) {
                closeDataArray[i] = closeData.get(i);
            }

            // calculate RSI
            Double [] macdValues = macdPoints.macdValues.toArray(new Double[macdPoints.macdValues.size()]);
            Double [] signalValues = macdPoints.signalValues.toArray(new Double[macdPoints.signalValues.size()]);
            double[] dSignalValues = new double[signalValues.length];
            double[] dMacdValues = new double[macdValues.length];
            for (int i=0;i<signalValues.length;i++){
                dSignalValues[i]=Double.valueOf(signalValues[i]);
            }
            for (int i=0;i<macdValues.length;i++){
                dMacdValues[i]=Double.valueOf(macdValues[i]);
            }
            final RetCode retCode = core.macd(0, closeDataArray.length - 1, closeDataArray, 12, 25, 9,  begin, length, rsiData,dMacdValues, dMacdValues);
            if(retCode == RetCode.Success) {
                final List<Date> dateData = prices.getDateData();
                final int beginIndex = begin.value;
                final int endIndex = beginIndex + length.value;

                // append NaN values for points which we can't calculate RSI
                for (int i = 0; i < beginIndex; i++) {
                    macdSeries.append(dateData.get(i), Double.NaN);
                }

                // append calculated RSI data
                for (int i = beginIndex; i < endIndex; i++) {
                    macdSeries.append(dateData.get(i), rsiData[i - beginIndex]);
                }

                addRenderableSeries(builder.newLineSeries().withDataSeries(macdSeries).withStrokeStyle(R.color.dashboard_chart_red_series_0, 1.5f).withYAxisId(RSI).build());       // color rsi

            }
        }
    }

    private void initChart(SciChartSurface surface, BasePaneModel model, boolean isMainPane) {
        final CategoryDateAxis xAxis = sciChartBuilder.newCategoryDateAxis()     //set x-axis Date data with properties
                .withVisibility(isMainPane ? View.VISIBLE : View.GONE)
                .withVisibleRange(sharedXRange)
                .withGrowBy(0, 0.05)
                .build();

        surface.getXAxes().add(xAxis);
        surface.getYAxes().add(model.yAxis);        //Take from BasePaneModel
        surface.setBackgroundColor (Color.WHITE);   //Background color
        surface.getRenderableSeries().addAll(model.renderableSeries);

        surface.getChartModifiers().add(sciChartBuilder     //ChartModifiers are the classes which can be added to a chart to give it a certain behaviour. For instance, all zooming, panning operations, tooltips, legends and even selection of points or lines are handled by ChartModifierBase derived classes in the SciChart codebase.
                .newModifierGroup()
                    .withXAxisDragModifier().withReceiveHandledEvents(true).withDragMode(AxisDragModifierBase.AxisDragMode.Pan).withClipModex(ClipMode.StretchAtExtents).build()
                    .withPinchZoomModifier().withReceiveHandledEvents(true).withXyDirection(Direction2D.XDirection).build()
                    .withZoomPanModifier().withReceiveHandledEvents(true).build()
                    .withZoomExtentsModifier().withReceiveHandledEvents(true).build()
                    .withLegendModifier().withShowCheckBoxes(false).build()
                .build());

        xAxis.setDrawMajorGridLines(true);
        xAxis.setDrawMinorGridLines(false);
        xAxis.setDrawMajorBands(false);

        model.yAxis.setDrawMajorGridLines(true);
        model.yAxis.setDrawMinorGridLines(false);
        model.yAxis.setDrawMajorBands(false);
        model.yAxis.setGrowBy(new DoubleRange(0.5d, 0.5d));

        surface.setAnnotations(model.annotations);

        verticalGroup.addSurfaceToGroup(surface);
    }

    private abstract static class BasePaneModel {
        public final RenderableSeriesCollection renderableSeries;
        public final AnnotationCollection annotations;
        public final NumericAxis yAxis;
        public final String title;

        protected BasePaneModel(SciChartBuilder builder, String title, String yAxisTextFormatting, boolean isFirstPane) {
            this.title = title;
            this.renderableSeries = new RenderableSeriesCollection();
            this.annotations = new AnnotationCollection();

            this.yAxis = builder.newNumericAxis ()           //Set Y Axis Numeric Axis
                    .withAxisId(title)
                    .withTextFormatting(yAxisTextFormatting)
                    .withAutoRangeMode(AutoRange.Always)      //Adjust screen size horizontally
                    .withDrawMinorGridLines(false)
                    .withMinorsPerMajor(isFirstPane ? 4 : 2)
                    .withMaxAutoTicks(isFirstPane ? 8 : 4)
                    .withGrowBy(isFirstPane ? new DoubleRange(0.5d, 0.5d) : new DoubleRange(0.1d, 0.1d))
                    .build();
        }

        final void addRenderableSeries(BaseRenderableSeries renderableSeries) {
            renderableSeries.setClipToBounds(true);
            this.renderableSeries.add(renderableSeries);
        }
    }
}

Static Output
https://i.imgur.com/wXjBtDD.jpg

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions