Microsoft.NET based stock market charting library for all your stock data visualization need in your trading application

WHY XFinChart ?

WHY XFinChart ?

Chart is one of the most important component of any trading system development process. XFinChart is a lightweight, flexible, interactive, feature rich and developer-friendly stock market data visualization charting and technical analysis library for .NET . The chart library also provides inbuilt framework for technical indicator and real-time data rendering. The technical analysis library provides a number of technical indicators that can be used to build trading strategies for stock markets, futures, forex etc.

XFinChart Key Features

Illustrate the periodic price movement using popular stock chart types like , candle, bar, line etc
Supports 50+ technical indicators and provides a framework to write yourown technical indicators
Periodic price data can be imported to XFinChart from any source or real-time feed.
Supports abstract built-in studies like Gann Fan, Fibonacci Retracement, Fibonacci Extension, Fibonacci Timezone, Pitchfork etc.
Built using native .NET framework for Windows keeping usability, resources & performance in mind
Tools including TrendLine tools, Annotation tools (text etc), Geometric Shapes, Patterns (XABCD etc), Prediction Tools are built-in
Chart windows are fully customizable i.e. width, color, style etc can be changed by writing your own code
General features: trendline, crosshair, tooltip, scrollbar, View resizing, rendering APIs
Unlimited number of Series can be displayed in one chart including the Main Series and Indicators
Zoom-in, Zoom-out, scroll left and scroll right controlled via keyboard and mouse wheel

XTALib Technical Indicator Library

XTALib is a flexible and powerful Technical Analysis Indicator framework library implemented in C#. It is indeed a library for programmers to develop custom indicators for financial market analysis, charting and developing a full featured trading application in .NET compatible with XFinChart. XTALib currently implements 50+ most frequently used indicators as an open source for your reference and provides an open framework to easily develop a proprietary indicator.

Platform For everyone

@Quant Developers and Data Scientists can use pre-built standard indicators or use their knowledge to develop their proprietary indicators using XTALib framework and combine them to build their proprietary trading strategies. Additionally, leveraging Symphony XTS API, users can retrieve historical and real-time market data and route orders connecting to a broker from their application.


Custom Indicator using XTALib

Regardless of hundreds of standard indicators, traders want to make their own custom indicators or create a graphical display for making a better trading decision. Creating your own custom indicator is very simple. Following example provides a sample code to develop a Relative Strength Index (RSI) Indicator.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Threading.Tasks;

namespace XTS.Base.Data.TI
    [IndicatorScaleAttribute(IndicatorScale.Custom, 0, 100)]
    [IndicatorAttribute("{95C1C6DA-9495-45DD-8266-33A1D9400107}", "RSI", "Relative Streangth Index", "SYMPH", IndicatorCategory = IndicatorCategoryType.Custom)]
    public class RSI : IndicatorBase
        [Parameter("LengthPeriod", Description = "The length of the RSI", DefaultValue = 12)]
        private int _lengthPeriod = 12;
        [Parameter("UpperLimit", Description = "Over Bought Value", DefaultValue = 70)]
        private int _upperLimit = 70;
        [Parameter("LowerLimit", Description = "Over Sold Value", DefaultValue = 30)]
        private int _lowerLimit = 30;
        private double _lastUpwardPriceChangeSmooth = 0;
        private double _lastDownwardPriceChangeSmooth = 0;
        [Output("RSIValue", DefaultValue = double.NaN, LineColor = "Red")] 
        private DoubleSeries _rsiDoubleValueSeries = new DoubleSeries();
        [Output("UpperLimit", DefaultValue = double.NaN, LineColor = "Gray", LineStyle = DashStyle.DashDot)]
        private DoubleSeries _rsiUpperLimitDoubleValueSeries = new DoubleSeries();
        [Output("LowerLimit", DefaultValue = double.NaN, LineColor = "Gray", LineStyle = DashStyle.DashDot)]
        private DoubleSeries _rsiLowerLimitDoubleValueSeries = new DoubleSeries();
        public RSI(TimeDataSeries timeDataSeries, int lengthPeriod) : base(timeDataSeries){
            if (lengthPeriod <= 0)
                throw new ArgumentException("Invalid RSI length");
            _lengthPeriod = lengthPeriod;
        public RSI() : base(null){}
        public RSI(TimeDataSeries timeDataSeries): base(timeDataSeries){}
        /// <summary>
        /// Calculates the Indicator Function value at the index.
        /// </summary>
        /// <param name="index">The index at which Indicator Function value need to be calculated.</param>
        /// <returns>
        /// The calculated Indicator function value at the index.
        /// </returns>
        protected override double Calculate(int index){
            double priceUpward = 0;
            double priceDownward = 0;
            int checkValue = _lengthPeriod;
            _rsiUpperLimitDoubleValueSeries[index] = _upperLimit;
            _rsiLowerLimitDoubleValueSeries[index] = _lowerLimit;
            if (index < checkValue)
                _rsiDoubleValueSeries[index] = double.NaN;
            else if (index == checkValue){
                int startIndex = Math.Max(index - _lengthPeriod, 1);
                double barPricePrevious = this.TimeDataSeries[startIndex].Close;
                for (int counter = startIndex + 1; counter <= index; counter++){
                    double barPriceCurrent = this.TimeDataSeries[counter].Close;
                    if (barPriceCurrent > barPricePrevious)  // Upward price movement
                        priceUpward += (barPriceCurrent - barPricePrevious);
                    else if (barPriceCurrent < barPricePrevious)  // Downward price movement
                        priceDownward += (barPricePrevious - barPriceCurrent);
                    barPricePrevious = barPriceCurrent;
                _lastUpwardPriceChangeSmooth = priceUpward / _lengthPeriod;
                _lastDownwardPriceChangeSmooth = priceDownward / _lengthPeriod;
                double rsiValue = 100 - (100 / (1 + (_lastUpwardPriceChangeSmooth / _lastDownwardPriceChangeSmooth)));
                _rsiDoubleValueSeries[index] = Math.Round(rsiValue, 2);
                double currentDownwardPriceChange;
                double currentUpwardPriceChange;
                double rsiValue = 0.0;
                currentUpwardPriceChange = this.TimeDataSeries[index].Close - this.TimeDataSeries[index - 1].Close;
                if (currentUpwardPriceChange >= 0)
                    currentDownwardPriceChange = 0;
                    currentDownwardPriceChange = -currentUpwardPriceChange;
                    currentUpwardPriceChange = 0;
                _lastUpwardPriceChangeSmooth = ((_lengthPeriod - 1) * _lastUpwardPriceChangeSmooth + currentUpwardPriceChange) / _lengthPeriod;
                _lastDownwardPriceChangeSmooth = ((_lengthPeriod - 1) * _lastDownwardPriceChangeSmooth + currentDownwardPriceChange) / _lengthPeriod;
                if (_lastUpwardPriceChangeSmooth + _lastDownwardPriceChangeSmooth != 0)
                    rsiValue = 100 * _lastUpwardPriceChangeSmooth / (_lastUpwardPriceChangeSmooth + _lastDownwardPriceChangeSmooth);
                _rsiDoubleValueSeries[index] = Math.Round(rsiValue, 2);
            return _rsiDoubleValueSeries[index];

Contact US

Let us help you to achieve your goals!

By providing Symphony with your contact information Symphony will process your personal data for the purpose of providing you with the information you have requested. For more information regarding Symphony's processing of your personal data, please read Symphony's Privacy Notice here.

  • Get latest updates from Us