Pre loader

Android Trading Annotation Example

Android Chart - Examples

SciChart Android ships with ~90 Android Chart Examples which you can browse, play with, view the source-code and even export each SciChart Android Chart Example to a stand-alone Android Studio project. All of this is possible with the new and improved SciChart Android Examples Suite, which ships as part of our Android Charts SDK.

Download Scichart Android

A suite of trading annotations, freehand drawing tools, and corresponding creation modifiers has been introduced to support professional financial charting and allow users to dynamically draw technical analysis patterns or custom paths directly on the chart using touch gestures.

Included Annotations:

  1. XabcdAnnotation (XABCD Pattern): Represents harmonic patterns consisting of 5 control points (X, A, B, C, D). It automatically calculates and displays Fibonacci leg ratios.
  2. PitchforkAnnotation (Andrews’ Pitchfork): Draws Andrews’ Pitchfork technical indicator consisting of three parallel trend lines based on three control points.
  3. ExtendedLineAnnotation (Extended Line): A trend line defined by two control points that visually projects infinitely across the chart area. Features configurable isExtendStart and isExtendEnd properties.

Included Creation Modifiers:

  1. XabcdAnnotationCreationModifier: Allows users to dynamically place the 5 control points on the chart via touch gestures to draw the XABCD harmonic pattern.
  2. PitchforkAnnotationCreationModifier: Enables the interactive creation of Andrews’ Pitchfork annotations by placing three peak/trough anchor points on the chart surface.
  3. ExtendedLineAnnotationCreationModifier: Enables users to draw extended trend lines dynamically using a drag gesture, defaulting to extending the line in both directions.
// Example setup for trading and freehand annotations and modifiers
val surface = findViewById<SciChartSurface>(R.id.surface)

// Create XABCD Annotation
val xabcdAnnotation = XabcdAnnotation(this).apply {
initialBasePoints.add(ComparablePoint(10, 30.6))
initialBasePoints.add(ComparablePoint(30, 31.5))
initialBasePoints.add(ComparablePoint(50, 30.3))
initialBasePoints.add(ComparablePoint(70, 31.5))
initialBasePoints.add(ComparablePoint(90, 30.6))
setIsEditable(true)
}

// Create Andrews' Pitchfork Annotation
val pitchforkAnnotation = PitchforkAnnotation(this).apply {
initialBasePoints.add(ComparablePoint(100, 30.6))
initialBasePoints.add(ComparablePoint(110, 31.5))
initialBasePoints.add(ComparablePoint(130, 30.7))
setIsEditable(true)
}

// Create Extended Line Annotation
val extendedLineAnnotation = ExtendedLineAnnotation(this).apply {
isExtendStart = true
isExtendEnd = true
x1 = 70
y1 = 33.3
x2 = 90
y2 = 33.7
setIsEditable(true)
}

// Add annotations to surface
surface.annotations.add(xabcdAnnotation)
surface.annotations.add(pitchforkAnnotation)
surface.annotations.add(extendedLineAnnotation)

// Create modifiers
val xabcdModifier = XabcdAnnotationCreationModifier().apply {
setAnnotationCreationListener(listener)
}
val pitchforkModifier = PitchforkAnnotationCreationModifier().apply {
setAnnotationCreationListener(listener)
}
val extendedLineModifier = ExtendedLineAnnotationCreationModifier().apply {
setAnnotationCreationListener(listener)
}


// Add modifiers to surface
surface.chartModifiers.add(xabcdModifier)
surface.chartModifiers.add(pitchforkModifier)
surface.chartModifiers.add(extendedLineModifier)

The full source code for the Android Bubble Chart example is included below (Scroll down!).

Did you know you can also view the source code from one of the following sources as well?

  1. Clone the SciChart.Android.Examples from Github.
  2. Or, view source and export each example to an Android Studio project of the SciChart Android Examples app.
  3. Also the SciChart Android Trial contains the full source for the examples (link below).

DOWNLOAD THE ANDROID CHART EXAMPLES

TradingAnnotationsFragment.java
View source code
//******************************************************************************
// SCICHART® Copyright SciChart Ltd. 2011-2026. All rights reserved.
//
// Web: http://www.scichart.com
// Support: support@scichart.com
// Sales:   sales@scichart.com
//
// TradingAnnotationsFragment.java is part of SCICHART®, High Performance Scientific Charts
// For full terms and conditions of the license, see http://www.scichart.com/scichart-eula/
//
// This source code is protected by international copyright law. Unauthorized
// reproduction, reverse-engineering, or distribution of all or any portion of
// this source code is strictly prohibited.
//
// This source code contains confidential and proprietary trade secrets of
// SciChart Ltd., and should at no time be copied, transferred, sold,
// distributed or made available without express written permission.
//******************************************************************************

package com.scichart.examples.fragments.examples2d.chartAnnotations;

import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;

import androidx.annotation.NonNull;

import com.scichart.charting.model.AnnotationCollection;
import com.scichart.charting.model.dataSeries.OhlcDataSeries;
import com.scichart.charting.modifiers.ExtendedLineAnnotationCreationModifier;
import com.scichart.charting.modifiers.FibonacciRetracementAnnotationCreationModifier;
import com.scichart.charting.modifiers.MeasureAnnotationCreationModifier;
import com.scichart.charting.modifiers.ModifierGroup;
import com.scichart.charting.modifiers.OnAnnotationCreatedListener;
import com.scichart.charting.modifiers.PitchforkAnnotationCreationModifier;
import com.scichart.charting.modifiers.StopLossTakeProfitAnnotationCreationModifier;
import com.scichart.charting.modifiers.XabcdAnnotationCreationModifier;
import com.scichart.charting.visuals.SciChartSurface;
import com.scichart.charting.visuals.annotations.ExtendedLineAnnotation;
import com.scichart.charting.visuals.annotations.IAnnotation;
import com.scichart.charting.visuals.annotations.tradingAnnotations.FibonacciRetracementAnnotation;
import com.scichart.charting.visuals.annotations.tradingAnnotations.MeasureAnnotation;
import com.scichart.charting.visuals.annotations.tradingAnnotations.PitchforkAnnotation;
import com.scichart.charting.visuals.annotations.tradingAnnotations.StopLossTakeProfitAnnotation;
import com.scichart.charting.visuals.annotations.tradingAnnotations.XabcdAnnotation;
import com.scichart.charting.visuals.renderableSeries.FastCandlestickRenderableSeries;
import com.scichart.examples.R;
import com.scichart.examples.components.SpinnerStringAdapter;
import com.scichart.examples.data.MarketDataService;
import com.scichart.examples.data.PriceSeries;
import com.scichart.examples.databinding.ExampleTradingAnnotationsFragmentBinding;
import com.scichart.examples.fragments.base.ExampleBaseFragment;
import com.scichart.examples.utils.ItemSelectedListenerBase;

import java.util.Calendar;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;

public class TradingAnnotationsFragment extends ExampleBaseFragment<ExampleTradingAnnotationsFragmentBinding> implements OnAnnotationCreatedListener {

    private final XabcdAnnotationCreationModifier xabcdModifier = new XabcdAnnotationCreationModifier();
    private final PitchforkAnnotationCreationModifier pitchforkModifier = new PitchforkAnnotationCreationModifier();
    private final ExtendedLineAnnotationCreationModifier extendedLineModifier = new ExtendedLineAnnotationCreationModifier();
    private final FibonacciRetracementAnnotationCreationModifier fibonacciModifier = new FibonacciRetracementAnnotationCreationModifier();
    private final MeasureAnnotationCreationModifier measureModifier = new MeasureAnnotationCreationModifier();
    private final StopLossTakeProfitAnnotationCreationModifier stopLossTakeProfitModifier = new StopLossTakeProfitAnnotationCreationModifier();

    @NonNull
    @Override
    protected ExampleTradingAnnotationsFragmentBinding inflateBinding(@NonNull LayoutInflater inflater) {
        return ExampleTradingAnnotationsFragmentBinding.inflate(inflater);
    }

    @Override
    protected void initExample(ExampleTradingAnnotationsFragmentBinding binding) {
        binding.annotationTypeSelector.setAdapter(new SpinnerStringAdapter(getActivity(), R.array.trading_annotation_type_list));
        binding.annotationTypeSelector.setOnItemSelectedListener(new ItemSelectedListenerBase() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                disableAllModifiers();
                switch (position) {
                    case 0: xabcdModifier.setIsEnabled(true); break;
                    case 1: pitchforkModifier.setIsEnabled(true); break;
                    case 2: extendedLineModifier.setIsEnabled(true); break;
                    case 3: fibonacciModifier.setIsEnabled(true); break;
                    case 4: measureModifier.setIsEnabled(true); break;
                    case 5: stopLossTakeProfitModifier.setIsEnabled(true); break;
                }
            }
        });

        final XabcdAnnotation xabcdAnnotation = sciChartBuilder.newXabcdAnnotation()
                .withBasePoint(10, 30.6)
                .withBasePoint(30, 31.5)
                .withBasePoint(50, 30.3)
                .withBasePoint(70, 31.5)
                .withBasePoint(90, 30.6)
                .withIsEditable(true)
                .build();

        final PitchforkAnnotation pitchforkAnnotation = sciChartBuilder.newPitchforkAnnotation()
                .withBasePoint(100, 30.6)
                .withBasePoint(110, 31.5)
                .withBasePoint(130, 30.7)
                .withIsEditable(true)
                .build();

        final ExtendedLineAnnotation extendedLineAnnotation = sciChartBuilder.newExtendedLineAnnotation()
                .withExtendStart(true)
                .withExtendEnd(true)
                .withX1(70).withY1(33.3)
                .withX2(90).withY2(33.7)
                .withIsEditable(true)
                .build();

        final ArrayList<Double> fibonacciLevels = new ArrayList<>();
        Collections.addAll(fibonacciLevels, 0.0, 0.236, 0.382, 0.5, 0.618, 0.764, 1.0);

        final FibonacciRetracementAnnotation fibonacciRetracementAnnotation = sciChartBuilder.newFibonacciRetracementAnnotation()
                .withBasePoint(140, 30.4)
                .withBasePoint(160, 32.2)
                .withLevels(fibonacciLevels)
                .withLabelPlacement(FibonacciRetracementAnnotation.LabelPlacement.CENTER)
                .withLabelVerticalPosition(FibonacciRetracementAnnotation.LabelVerticalPosition.ABOVE)
                .withLabelFormat(FibonacciRetracementAnnotation.LabelFormat.RATIO)
                .withIsEditable(true)
                .build();

        final OhlcDataSeries<Date, Double> dataSeries = sciChartBuilder.newOhlcDataSeries(Date.class, Double.class).build();
        final MarketDataService marketDataService = new MarketDataService(Calendar.getInstance().getTime(), 5, 5);
        final PriceSeries data = marketDataService.getHistoricalData(200);

        dataSeries.append(data.getDateData(), data.getOpenData(), data.getHighData(), data.getLowData(), data.getCloseData());

        final FastCandlestickRenderableSeries candlestickSeries = sciChartBuilder.newCandlestickSeries().withDataSeries(dataSeries).withOpacity(0.4f).build();

        final MeasureAnnotation measureAnnotation = sciChartBuilder.newMeasureAnnotation()
                .withBasePoint(180, 30.6)
                .withBasePoint(195, 32.1)
                .withSnapSeries(candlestickSeries)
                .withIsEditable(true)
                .build();

        final StopLossTakeProfitAnnotation takeProfitAnnotation = sciChartBuilder.newStopLossTakeProfitAnnotation()
                .withBasePoint(165, 33.0)
                .withBasePoint(175, 34.2)
                .withStrokeDashArray(new float[]{6f, 3f})
                .withIsEditable(true)
                .build();

        final StopLossTakeProfitAnnotation stopLossAnnotation = sciChartBuilder.newStopLossTakeProfitAnnotation()
                .withBasePoint(165, 36.5)
                .withBasePoint(175, 35.3)
                .withStrokeDashArray(new float[]{6f, 3f})
                .withIsEditable(true)
                .build();

        final SciChartSurface surface = binding.surface;
        Collections.addAll(surface.getRenderableSeries(), candlestickSeries);
        Collections.addAll(surface.getXAxes(), sciChartBuilder.newCategoryDateAxis().build());
        Collections.addAll(surface.getYAxes(), sciChartBuilder.newNumericAxis().withVisibleRange(30d, 37d).build());
        Collections.addAll(surface.getAnnotations(), xabcdAnnotation, pitchforkAnnotation, extendedLineAnnotation, fibonacciRetracementAnnotation, measureAnnotation, takeProfitAnnotation, stopLossAnnotation);

        xabcdModifier.setAnnotationCreationListener(this);
        pitchforkModifier.setAnnotationCreationListener(this);
        extendedLineModifier.setAnnotationCreationListener(this);
        fibonacciModifier.setAnnotationCreationListener(this);
        fibonacciModifier.setLabelPlacement(FibonacciRetracementAnnotation.LabelPlacement.CENTER);
        fibonacciModifier.setLabelVerticalPosition(FibonacciRetracementAnnotation.LabelVerticalPosition.ABOVE);
        fibonacciModifier.setLabelFormat(FibonacciRetracementAnnotation.LabelFormat.RATIO);
        measureModifier.setAnnotationCreationListener(this);
        measureModifier.setSnapSeries(candlestickSeries);
        stopLossTakeProfitModifier.setAnnotationCreationListener(this);

        disableAllModifiers();
        xabcdModifier.setIsEnabled(true);

        surface.getChartModifiers().add(new ModifierGroup(xabcdModifier, pitchforkModifier, extendedLineModifier, fibonacciModifier, measureModifier, stopLossTakeProfitModifier));

        binding.deleteAnnotation.setOnClickListener(v -> {
            final AnnotationCollection annotations = surface.getAnnotations();
            for (int i = annotations.size() - 1; i >= 0; i--) {
                final IAnnotation annotation = annotations.get(i);
                if (annotation.isSelected()) {
                    annotations.remove(i);
                }
            }
        });
    }

    private void disableAllModifiers() {
        xabcdModifier.setIsEnabled(false);
        pitchforkModifier.setIsEnabled(false);
        extendedLineModifier.setIsEnabled(false);
        fibonacciModifier.setIsEnabled(false);
        measureModifier.setIsEnabled(false);
        stopLossTakeProfitModifier.setIsEnabled(false);
    }

    @Override
    public void onAnnotationCreated(@NonNull IAnnotation newAnnotation) {
        newAnnotation.setIsEditable(true);
    }
}
TradingAnnotationsFragment.kt
View source code
//******************************************************************************
// SCICHART® Copyright SciChart Ltd. 2011-2026. All rights reserved.
//
// Web: http://www.scichart.com
// Support: support@scichart.com
// Sales:   sales@scichart.com
//
// TradingAnnotationsFragment.kt is part of SCICHART®, High Performance Scientific Charts
// For full terms and conditions of the license, see http://www.scichart.com/scichart-eula/
//
// This source code is protected by international copyright law. Unauthorized
// reproduction, reverse-engineering, or distribution of all or any portion of
// this source code is strictly prohibited.
//
// This source code contains confidential and proprietary trade secrets of
// SciChart Ltd., and should at no time be copied, transferred, sold,
// distributed or made available without express written permission.
//******************************************************************************

package com.scichart.examples.fragments.examples2d.chartAnnotations.kt

import android.view.LayoutInflater
import android.view.View
import android.widget.AdapterView
import com.scichart.charting.modifiers.*
import com.scichart.charting.visuals.annotations.IAnnotation
import com.scichart.charting.visuals.annotations.tradingAnnotations.FibonacciRetracementAnnotation
import com.scichart.charting.visuals.annotations.tradingAnnotations.models.ComparablePoint
import com.scichart.charting.visuals.renderableSeries.FastCandlestickRenderableSeries
import com.scichart.data.model.DoubleRange
import com.scichart.examples.R
import com.scichart.examples.components.SpinnerStringAdapter
import com.scichart.examples.data.MarketDataService
import com.scichart.examples.databinding.ExampleTradingAnnotationsFragmentBinding
import com.scichart.examples.fragments.base.ExampleBaseFragment
import com.scichart.examples.utils.ItemSelectedListenerBase
import com.scichart.examples.utils.scichartExtensions.*
import java.util.*

class TradingAnnotationsFragment : ExampleBaseFragment<ExampleTradingAnnotationsFragmentBinding>(), OnAnnotationCreatedListener {

    private val xabcdModifier = XabcdAnnotationCreationModifier()
    private val pitchforkModifier = PitchforkAnnotationCreationModifier()
    private val extendedLineModifier = ExtendedLineAnnotationCreationModifier()
    private val fibonacciModifier = FibonacciRetracementAnnotationCreationModifier().apply {
        setLabelPlacement(FibonacciRetracementAnnotation.LabelPlacement.CENTER)
        setLabelVerticalPosition(FibonacciRetracementAnnotation.LabelVerticalPosition.ABOVE)
        setLabelFormat(FibonacciRetracementAnnotation.LabelFormat.RATIO)
    }
    private val measureModifier = MeasureAnnotationCreationModifier()
    private val stopLossTakeProfitModifier = StopLossTakeProfitAnnotationCreationModifier()

    override fun inflateBinding(inflater: LayoutInflater): ExampleTradingAnnotationsFragmentBinding {
        return ExampleTradingAnnotationsFragmentBinding.inflate(inflater)
    }

    override fun initExample(binding: ExampleTradingAnnotationsFragmentBinding) {
        binding.annotationTypeSelector.run {
            adapter = SpinnerStringAdapter(activity, R.array.trading_annotation_type_list)
            onItemSelectedListener = object : ItemSelectedListenerBase() {
                override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
                    disableAllModifiers()
                    when (position) {
                        0 -> xabcdModifier.isEnabled = true
                        1 -> pitchforkModifier.isEnabled = true
                        2 -> extendedLineModifier.isEnabled = true
                        3 -> fibonacciModifier.isEnabled = true
                        4 -> measureModifier.isEnabled = true
                        5 -> stopLossTakeProfitModifier.isEnabled = true
                    }
                }
            }
        }

        xabcdModifier.setAnnotationCreationListener(this)
        pitchforkModifier.setAnnotationCreationListener(this)
        extendedLineModifier.setAnnotationCreationListener(this)
        fibonacciModifier.setAnnotationCreationListener(this)
        measureModifier.setAnnotationCreationListener(this)
        stopLossTakeProfitModifier.setAnnotationCreationListener(this)

        val surface = binding.surface
        lateinit var candlestickSeries: FastCandlestickRenderableSeries
        surface.suspendUpdates {
            xAxes { categoryDateAxis { } }
            yAxes { numericAxis { visibleRange = DoubleRange(30.0, 37.0) } }
            renderableSeries {
                fastCandlestickRenderableSeries {
                    ohlcDataSeries<Date, Double> {
                        val marketDataService = MarketDataService(Calendar.getInstance().time, 5, 5)
                        val data = marketDataService.getHistoricalData(200)

                        append(data.dateData, data.openData, data.highData, data.lowData, data.closeData)
                    }
                    opacity = 0.4f
                    candlestickSeries = this
                }
            }
            annotations {
                xabcdAnnotation {
                    initialBasePoints.add(ComparablePoint(10, 30.6))
                    initialBasePoints.add(ComparablePoint(30, 31.5))
                    initialBasePoints.add(ComparablePoint(50, 30.3))
                    initialBasePoints.add(ComparablePoint(70, 31.5))
                    initialBasePoints.add(ComparablePoint(90, 30.6))
                    setIsEditable(true)
                }
                pitchforkAnnotation {
                    initialBasePoints.add(ComparablePoint(100, 30.6))
                    initialBasePoints.add(ComparablePoint(110, 31.5))
                    initialBasePoints.add(ComparablePoint(130, 30.7))
                    setIsEditable(true)
                }
                extendedLineAnnotation {
                    isExtendStart = true
                    isExtendEnd = true
                    x1 = 70; y1 = 33.3
                    x2 = 90; y2 = 33.7
                    setIsEditable(true)
                }
                fibonacciRetracementAnnotation {
                    initialBasePoints.add(ComparablePoint(140, 30.4))
                    initialBasePoints.add(ComparablePoint(160, 32.2))
                    levels = listOf(0.0, 0.236, 0.382, 0.5, 0.618, 0.786, 1.0, 1.272, 1.618).reversed()
                    setIsEditable(true)
                }
                measureAnnotation {
                    initialBasePoints.add(ComparablePoint(180, 30.6))
                    initialBasePoints.add(ComparablePoint(195, 32.1))
                    setSnapSeries(candlestickSeries)
                    setIsEditable(true)
                }
                stopLossTakeProfitAnnotation {
                    initialBasePoints.add(ComparablePoint(165, 33.0))
                    initialBasePoints.add(ComparablePoint(175, 34.2))
                    strokeDashArray = floatArrayOf(6f, 3f)
                    setIsEditable(true)
                }
                stopLossTakeProfitAnnotation {
                    initialBasePoints.add(ComparablePoint(165, 36.5))
                    initialBasePoints.add(ComparablePoint(175, 35.3))
                    strokeDashArray = floatArrayOf(6f, 3f)
                    setIsEditable(true)
                }
            }
            chartModifiers {
                modifier(xabcdModifier)
                modifier(pitchforkModifier)
                modifier(extendedLineModifier)
                modifier(fibonacciModifier)
                modifier(measureModifier)
                modifier(stopLossTakeProfitModifier)
            }
        }

        measureModifier.setSnapSeries(candlestickSeries)

        disableAllModifiers()
        xabcdModifier.isEnabled = true

        binding.deleteAnnotation.setOnClickListener {
            val annotations = surface.annotations
            for (i in annotations.indices.reversed()) {
                val annotation = annotations[i]
                if (annotation.isSelected) {
                    annotations.removeAt(i)
                }
            }
        }
    }

    private fun disableAllModifiers() {
        xabcdModifier.isEnabled = false
        pitchforkModifier.isEnabled = false
        extendedLineModifier.isEnabled = false
        fibonacciModifier.isEnabled = false
        measureModifier.isEnabled = false
        stopLossTakeProfitModifier.isEnabled = false
    }

    override fun onAnnotationCreated(newAnnotation: IAnnotation) {
        newAnnotation.setIsEditable(true)
    }
}
Back to Android Chart Examples