Overall Statistics
```using System;
using QuantConnect.Data.Market;

namespace QuantConnect.Indicators
{
/// <summary>

/// SumTrueRange is defined as the maximum of the following:
///   High - Low
///   ABS(High - PreviousClose)
///   ABS(Low  - PreviousClose)
///  Summed over a N peridos window
/// VMplus:
///
/// SUM(ABS(High - previous.Low), N periods)
/// VMminus:
///
///  SUM(ABS(High - previous.High), N periods)
///  Vortex Indicator:
///  VMplus / SumTrueRange - VMminus / SumTrueRange
///
///
/// </summary>

{

private int _period;

public IndicatorBase<TradeBar> TrueRange { get; private set; }

public IndicatorBase<TradeBar> HI { get; private set; }
public IndicatorBase<TradeBar> LO { get; private set; }

public IndicatorBase<IndicatorDataPoint> RollingSumTR { get; private set; }
public IndicatorBase<IndicatorDataPoint> VMplus { get; private set; }
public IndicatorBase<IndicatorDataPoint> VMminus { get; private set; }

public IndicatorBase<TradeBar> VIplus { get; private set; }
public IndicatorBase<TradeBar> VIminus { get; private set; }

{
get { return Samples > _period; }
}

public Vortex(string name, int period)
: base(name)
{

_period = period;
RollingSumTR = new Sum(name + "_SumTR", period);

VMplus = new Sum(name + "_Plus", period);
VMminus = new Sum(name + "_Minus", period);

HI = new FunctionalIndicator<TradeBar>(name + period, currentBar =>
{
// in our ComputeNextValue function we'll just call the ComputeTrueRange
var nextValue = ComputeHI(previous, currentBar);
previous = currentBar;
return nextValue;
}   // in our IsReady function we just need at least two sample
, trueRangeIndicator => trueRangeIndicator.Samples >= _period
);

LO = new FunctionalIndicator<TradeBar>(name + period, currentBar =>
{
// in our ComputeNextValue function we'll just call the ComputeTrueRange
var nextValue = ComputeLO(previous, currentBar);
previous = currentBar;
return nextValue;
}   // in our IsReady function we just need at least two sample
, trueRangeIndicator => trueRangeIndicator.Samples >= _period
);

VIminus = new FunctionalIndicator<TradeBar>(name + period +"minus", currentBar=>
ComputeVIminus(currentBar) , trueRangeIndicator => trueRangeIndicator.Samples >= _period
);

VIplus = new FunctionalIndicator<TradeBar>(name + period +"plus", currentBar=>
ComputeVIplus(currentBar) , trueRangeIndicator => trueRangeIndicator.Samples >= _period
);

TrueRange = new FunctionalIndicator<TradeBar>(name + "_TrueRange", currentBar =>
{
// in our ComputeNextValue function we'll just call the ComputeTrueRange
var nextValue = ComputeSumTrueRange(previous, currentBar);
previous = currentBar;
return nextValue;
}   // in our IsReady function we just need at least two sample
, trueRangeIndicator => trueRangeIndicator.Samples >= _period
);

}

public Vortex(int period)
: this("Vortex" + period, period)
{
}

{

if (previous == null)
{
return 0;
}

var range1 = current.High - current.Low;
var range2 = Math.Abs(current.High - previous.Close);
var range3 = Math.Abs(current.Low - previous.Close);

return Math.Max(range1, Math.Max(range2, range3));
}

{

if (previous == null)
{
return 0;
}

var _HI = Math.Abs(current.High - previous.Low);

return _HI;
}

{

if (previous == null)
{
return 0;
}

var _LO = Math.Abs(current.Low - previous.High) ;

return _LO;
}

{
if(RollingSumTR.Current.Value == 0) return 0;

return VMplus.Current.Value / RollingSumTR.Current.Value;
}

{
if(RollingSumTR.Current.Value == 0) return 0;

return VMminus.Current.Value / RollingSumTR.Current.Value;
}

{
// update the true range and then sum it
TrueRange.Update(input);

RollingSumTR.Update(input.Time, TrueRange.Current.Value);

HI.Update(input);
LO.Update(input);

VMplus.Update(input.Time, HI.Current.Value);
VMminus.Update(input.Time, LO.Current.Value);

VIplus.Update(input);
VIminus.Update(input);

return 0;

}

public override void Reset()
{
HI.Reset();
LO.Reset();
TrueRange.Reset();
VMplus.Reset();
VMminus.Reset();
RollingSumTR.Reset();
VIplus.Reset();
VIminus.Reset();
base.Reset();
}
}
}```
```namespace QuantConnect
{
/*
*   QuantConnect University: Full Basic Template:
*
*   The underlying QCAlgorithm class is full of helper methods which enable you to use QuantConnect.
*   We have explained some of these here, but the full algorithm can be found at:
*   https://github.com/QuantConnect/QCAlgorithm/blob/master/QuantConnect.Algorithm/QCAlgorithm.cs
*/
public class BasicTemplateAlgorithm : QCAlgorithm
{
private Vortex vtx;

//Initialize the data and resolution you require for your strategy:
public override void Initialize()
{

//Start and End Date range for the backtest:
SetStartDate(2013, 1, 1);
SetEndDate(2015, 1, 1);

//Cash allocation
SetCash(25000);

//Add as many securities as you like. All the data will be passed into the event handler:

vtx = new Vortex(14);
RegisterIndicator("SPY", vtx, Resolution.Daily);

}

//Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol.
{

return ;
}

Log(vtx.HI.Current.Value.ToString());
Log(vtx.LO.Current.Value.ToString());
//Log(vtx.VMplus.Current.Value.ToString());
//Log(vtx.VMminus.Current.Value.ToString());
//Log(vtx.VIplus.Current.Value.ToString());
//Log(vtx.VIminus.Current.Value.ToString());
//Log(vtx.TrueRange.Current.Value.ToString());
Plot("Vortex", vtx.VIplus, vtx.VIminus);
//var quantity = Portfolio["SPY"].Quantity;
Console.WriteLine((vtx.VIplus-vtx.VIminus).ToString());
if ( vtx.VIplus > vtx.VIminus)
{
SetHoldings("SPY", 1.0);
}
else
{
SetHoldings("SPY", -1.0);
}
}
}
}```