?> QuantXpress – Deliver high performance automated trading and connectivity solutions



Technical Indicator


Introduction

In finance, technical analysis is a security analysis discipline for forecasting the direction of prices through the study of past market data, primarily price and volume. Technical analysts believe that prices trend directionally, i.e., up, down, or sideways (flat) or some combination. Many non-arbitrage algorithmic trading systems rely on the idea of trend-following, as do many hedge funds.
Technical analysis focuses on prices
Most mechanical trading system employs technical analysis based indicators to model a robust system with some consistent return following a proper risk and money management rules.

Writing your own custom Indicator

The BlitzTrader API provides more than 30 important standard technical indicator components that can be directly used within your strategy creation process. The standard technical Indicator list will keep growing based on common requirements of most of quants. You may decide to write your own custom Indicator to be reused in your various strategies. Following is standard template in C# for any custom Indicator under development and then we discussed in more details below on the implementation.
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QX.Base.Data.Indicators
{
    public class MyIndicatorX1 : IndicatorBase
    {
        private int _lengthPeriod;
    public MyIndicatorX1(BarDataSeries dataSeries, int lengthPeriod)
            : base(dataSeries)
        {
            if (lengthPeriod <= 0)
            {
                throw new ArgumentException("Invalid length parameter");
            }

            _lengthPeriod = lengthPeriod;
        }


        protected override void Initialize()
        {
        }
        /// 
        /// Calculates the Indicator Function value at the index.
        /// 
        /// The index at which Indicator Function value need to be calculated.
        /// 
        /// The calculated Indicator function value at the index.
        /// 
        protected override double Calculate(int index)
        {
            if (index < _lengthPeriod)
            {
                return double.NaN;
            }
            else
            {
                double return 1;
            }
        }
    }
}

Writing your custom Indicator.

Your Indicator class MyIndicatorX1 must derive from IndicatorBase class provided by BlitzTrader API. You need to provide a constructor that generally takes your BarDataSeries and any parameters used to evaluate your indicator value. For example we will be demonstrating an implementation of BollingerBand implementation that takes length and standardDeviation as input values to evaluate the Indicator values for upper, middle and lower band. Usually most indicator like SimpleMovingAverage evaluates a single value called a Main value which is initialized in the IndicatorBase class from a value returned from a Calculate method.
Methods provided to be overridden in your implementation class.

Initialize()

The Initialize method is optional and called once at the beginning of your Indicator evaluation process. This method is used to initialize any other embedded indicator.

Calculate

The Calculate method is mandatory to be overridden by Indicator implementation class. The logic of Indicator value calculation is described in Calculate method. This method is called sequentially for every bar completion and takes the current index of bar at which the indicator value has to evaluated.

A BollingerBand Indicator Implementation

BollingerBand Indicator contains three Indicator series, a simple moving average, upper and lower bands representing K times standard deviation away from moving average.
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QX.Base.Data.Indicators
{
    public class BollingerBand : IndicatorBase
    {
        private int _lengthPeriod;
        private double _standardDeviation;

        private DoubleSeries _doubleSeriesUpper = null;
        private DoubleSeries _doubleSeriesLower = null;

        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// The DataSeries.
        /// The length period.
        /// The standard deviation.
        public BollingerBand(BarDataSeries dataSeries, int lengthPeriod, double standardDeviation): base(dataSeries)
        {
            if (lengthPeriod <= 0)
            {
                throw new ArgumentException("Invalid Bollinger band length");
            }

            _lengthPeriod = lengthPeriod;
            _standardDeviation = Math.Abs(standardDeviation);

            _doubleSeriesUpper = new DoubleSeries();
            _doubleSeriesLower = new DoubleSeries();
        }

        public IDoubleSeries Upper
        {
            get { return _doubleSeriesUpper; }
        }

        public IDoubleSeries Lower
        {
            get { return _doubleSeriesLower; }
        }

        /// 
        /// Calculates the Indicator Function value at the index.
        /// 
        /// The index at which Indicator Function value need to be calculated.
        /// 
        /// The calculated Indicator function value at the index.
        /// 
        protected override double Calculate(int index)
        {
            if (index < _lengthPeriod)
            {
                _doubleSeriesUpper[index] = double.NaN;
                _doubleSeriesLower[index] = double.NaN;
                return double.NaN;
            }
            else
            {
                double avg = BarDataSeries.GetAverage(BarPriceType.Close, _lengthPeriod, index);
                double std = BarDataSeries.GetStandardDeviation(BarPriceType.Close, _lengthPeriod, index);
                _doubleSeriesUpper[index] = avg + (_standardDeviation * std);
                _doubleSeriesLower[index] = avg - (_standardDeviation * std);

                return avg;
            }
        }
    }
}

Using Bollinger Band Indicator in a Strategy

 
string errorString = string.Empty;
int BarSize = 1;
// Gets 1 minute bar data from historical Bid time series of last 25 days
// in sync with real-time data
IVMinuteBarDataSeries _ivMinuteBarSeries = GetMinuteBarDataSeries(_iv, 
                                                                  PriceType.Bid,
                                                                  BarSize,
                                                                  DateTime.Today.AddDays(-25),
                                                                  out errorString);

MinuteBarDataSeries minuteBarDataSeries = _ivMinuteBarSeries.BarDataSeries;
int lengthPeriod = 12;
double standardDeviation = 2;
QX.Base.Data.Indicators.BollingerBand _bollingerBand = new QX.Base.Data.Indicators.BollingerBand(minuteBarDataSeries,
                                                                                                 lengthPeriod,
                                                                                                 standardDeviation);

// Gets the latest bar data
IBarData barData = minuteBarDataSeries[minuteBarDataSeries.Count - 1];

// Bind to a callback method to receive a notification on every bar completion.
_ivMinuteBarSeries.OnBarCompleted += OnBarCompleted;
.......................
.......................
.......................
private void OnBarCompleted(string seriesID, IBarData barData)
{
    double bbValue = _bollingerBand[minuteBarDataSeries.Count - 1];

}