How to: Plot data with a Candlestick Chart

This how-to guide will lead you through the steps required to render a candlestick chart - this is one of a class of series types that have multiple X or Y values.

NOTE: Candlestick series are a premium charts feature.

In order to render a candlestick series you need to do the following:

  1. Create a chart with a numeric Y axis and a numeric or date / time X axis.
  2. Create a CandlestickSeries, give it your data and add it to the chart.

shinobicharts has a number of series that expect multiple values, this includes BandSeries, CandlestickSeries and OHLCSeries. When rendering a chart using one of these series types your data points must provide multiple X or Y values (depending on the chart orientation). The ‘MultiValueDataPoint’ class is designed to allow this.

Here is the method used to load the JSON data, illustrating the use of the MultiValueDataPoint class:

Java

private List<Data<Date, Double>> LoadStockPriceData(String assetName)
{
    List<Data<Date, Double>> dataPoints = new ArrayList<Data<Date, Double>> ();
    AssetManager assetManager = this.getAssets();
    InputStream stream = null;
    SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", Locale.US);
    try {
        stream = assetManager.open(assetName);
        BufferedReader streamReader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));

        StringBuilder responseStrBuilder = new StringBuilder();
        String inputStr;
        while ((inputStr = streamReader.readLine()) != null) {
            responseStrBuilder.append(inputStr);
        }
        JSONArray jsonArray = new JSONArray(responseStrBuilder.toString());

        for (int i=0 ; i<jsonArray.length() ; i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            MultiValueDataPoint<Date, Double> dataPoint = new MultiValueDataPoint<Date, Double>(
                    formatter.parse(jsonObject.getString("date")),
                    jsonObject.getDouble("low"),
                    jsonObject.getDouble("high"),
                    jsonObject.getDouble("open"),
                    jsonObject.getDouble("close"));
            dataPoints.add(dataPoint);
        }
    } catch (IOException exc) {
        Log.e("CandlestickChart", "Unable to load asset");
    } catch (JSONException exc) {
        Log.e("CandlestickChart", "Unable to parse JSON data");
    } catch (ParseException exc) {
        Log.e("CandlestickChart", "Unable to parse JSON data");
    } finally {
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException exc) {
                Log.e("CandlestickChart", "Unable to close input stream.");
            }
        }
    }
    return dataPoints;
}

C#

private List<IData> LoadStockPriceData(string assetName)
{
    List<IData> dataPoints = new List<IData> ();
    using (StreamReader reader = new StreamReader (Assets.Open (assetName))) {
        JsonValue stocks = JsonObject.Load (reader);
        foreach (JsonValue stock in stocks) {
            IData dataPoint = new MultiValueDataPoint (
                DateUtils.ConvertToJavaDate (DateTime.ParseExact (stock ["date"], "dd-MM-yyyy", CultureInfo.InvariantCulture)),
                (double)stock ["low"],
                (double)stock ["high"],
                (double)stock ["open"],
                (double)stock ["close"]);
            dataPoints.Add (dataPoint);
        }
    }
    return dataPoints;
}

And the data points are simply added into the data adapter of a candlestick series:

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Only set the chart up the first time the Activity is created
    if (savedInstanceState == null) {

        // Get the a reference to the ShinobiChart from the ChartFragment
        ChartFragment chartFragment =
                (ChartFragment) getFragmentManager().findFragmentById(R.id.chart);

        ShinobiChart shinobiChart = chartFragment.getShinobiChart();

        // TODO: replace <trial_key_here> with your trial key
        shinobiChart.setTrialKey("<trial_key_here>");

        DateTimeAxis xAxis = new DateTimeAxis ();
        xAxis.setTitle("Date");
        xAxis.enableGesturePanning(true);
        xAxis.enableGestureZooming(true);
        shinobiChart.addXAxis(xAxis);

        NumberAxis yAxis = new NumberAxis ();
        yAxis.setTitle("Price (USD)");
        yAxis.enableGesturePanning(true);
        yAxis.enableGestureZooming(true);
        shinobiChart.addYAxis(yAxis);

        CandlestickSeries series = new CandlestickSeries ();
        DataAdapter<Date, Double> dataAdapter = new SimpleDataAdapter<Date, Double> ();
        dataAdapter.addAll (LoadStockPriceData ("AppleStockPrices.json"));
        series.setDataAdapter(dataAdapter);
        shinobiChart.addSeries(series);

    }

C#

protected override void OnCreate (Bundle bundle)
{
    base.OnCreate (bundle);

    // Set our view from the "main" layout resource
    SetContentView (Resource.Layout.Main);

    if (bundle == null) {

        // Get the a reference to the ShinobiChart from the ChartFragment
        ChartFragment chartFragment =
                (ChartFragment)FragmentManager.FindFragmentById (Resource.Id.chart);

        IShinobiChart shinobiChart = chartFragment.ShinobiChart;

        // TODO: replace <trial_key_here> with your trial key
        shinobiChart.setTrialKey("<trial_key_here>");

        shinobiChart.AddXAxis(new DateTimeAxis () {
            Title = "Date",
            GesturePanningEnabled = true,
            GestureZoomingEnabled = true
        });

        shinobiChart.AddYAxis(new NumberAxis () {
            Title = "Price (USD)",
            GesturePanningEnabled = true,
            GestureZoomingEnabled = true
        });

        Series series = new OHLCSeries () { DataAdapter = new SimpleDataAdapter () };
        series.DataAdapter.AddAll (LoadStockPriceData ("AppleStockPrices.json"));
        shinobiChart.AddSeries(series);
    }
}

This will result in a candlestick series which looks like this (after some zooming in):

Candlestick chart

See related code sample: Candlestick Chart Sample, in the samples/candlestick-chart folder of your product download (Xamarin.Android/samples/CandlestickChart if you’re using Xamarin.Android).