Show / Hide Table of Contents

Creating Custom Indicators

This article needs to be rewritten for the v2 engine. In the meantime, check out our demo code below and the previous article for the v1 engine.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TuringTrader.SimulatorV2;
using TuringTrader.SimulatorV2.Indicators;
using TuringTrader.SimulatorV2.Assets;
#endregion

namespace Demos
{
    static class Demo09_Extensions
    {
        public static TimeSeriesFloat CustomEMA(this TimeSeriesFloat series, int period)
        {
            // indicator instances must have a unique name
            var name = string.Format("{0}.CustomEMA({1})", series.Name, period);

            // use a lambda to calculate the recursive EMA
            // note how we initialize the series on IsFirstBar
            // consequently, we pass a dummy initializer to Lambda
            var alpha = 2.0 / (1.0 + period);
            return series.Owner.Lambda(
                name,
                (prevEMA) => series.Owner.IsFirstBar
                    ? series[0]
                    : prevEMA + alpha * (series[0] - prevEMA),
                -999.99);
        }

        public static TimeSeriesFloat CustomSMA(this TimeSeriesFloat series, int period)
        {
            // indicator instances must have a unique name
            var name = string.Format("{0}.CustomSMA({1})", series.Name, period);

            // use a lambda to calculate the non-recursive SMA
            return series.Owner.Lambda(
                name,
                () => Enumerable.Range(0, period).Average(t => series[t]));
        }
    }

    public class Demo09_CustomIndicators : Algorithm
    {
        public override void Run()
        {
            //---------- initialization

            // set the simulation period
            StartDate = DateTime.Parse("2007-01-01T16:00-05:00");
            EndDate = DateTime.Parse("2022-12-31T16:00-05:00");

            //---------- simulation

            SimLoop(() =>
            {
                var input = Asset("$SPX").Close;

                // our custom indicators can be used exactly the same way
                // as any of TuringTrader's built-in indicators
                var custom1 = input.CustomEMA(200);
                var custom2 = input.CustomSMA(200);

                Plotter.SelectChart("custom indicators", "date");
                Plotter.SetX(SimDate);
                Plotter.Plot(input.Name, input[0]);
                Plotter.Plot(custom1.Name, custom1[0]);
                Plotter.Plot(custom2.Name, custom2[0]);
            });
        }

        // minimalistic chart
        public override void Report() => Plotter.OpenWith("SimpleChart");
    }
}
  • Improve this Doc
In This Article
Back to top Copyright © 2011-2023, Bertram Enterprises LLC dba TuringTrader.com