Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to create Real time Chart #4

Open
frared358 opened this issue Jun 25, 2018 · 1 comment
Open

How to create Real time Chart #4

frared358 opened this issue Jun 25, 2018 · 1 comment

Comments

@frared358
Copy link

frared358 commented Jun 25, 2018

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

@andyb1979
Copy link
Contributor

andyb1979 commented Jun 25, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants