Overall Statistics
Total Trades
25
Average Win
3.40%
Average Loss
-3.75%
Compounding Annual Return
37.491%
Drawdown
9.100%
Expectancy
0.429
Net Profit
20.208%
Sharpe Ratio
1.665
Loss Rate
25%
Win Rate
75%
Profit-Loss Ratio
0.91
Alpha
0.23
Beta
-0.013
Annual Standard Deviation
0.138
Annual Variance
0.019
Information Ratio
1.565
Tracking Error
0.138
Treynor Ratio
-17.829
Total Fees
$46.25
using System;
using System.Linq;
using QuantConnect.Brokerages;
using QuantConnect.Data;
using QuantConnect.Data.Custom;
using QuantConnect.Indicators;
using QuantConnect.Securities;
using QuantConnect.Securities.Future;

namespace QuantConnect.Algorithm.CSharp
{
    public class VIXFuturesTermStructure : QCAlgorithm
    {
        private Future _es;
        private Identity _esIdentity;
        private IndicatorDataPoint _latestEs;
        private IndicatorDataPoint _latestVx;
        private Identity _vix;
        private Future _vx;
        private Identity _vxIdentity;
        private bool _entryLong;
        private DateTime _entryDate;


        public override void Initialize()
        {
            SetStartDate(year: 2018, month: 1, day: 1);
            SetEndDate(year: 2018, month: 8, day: 1);
            SetCash(startingCash: 100000);

            SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage);

            // Schedule.On(DateRules.EveryDay(), TimeRules.At(hour: 9, minute: 31), Rebalance);

            _es = AddFuture(Futures.Indices.SP500EMini);
            _vx = AddFuture(Futures.Indices.VIX);

            _es.SetFilter(f => f.FrontMonth());
            _vx.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(value: 182));

            AddData<QaundlVIX>("CBOE/VIX", Resolution.Daily, TimeZones.Chicago);
            _vix = new Identity("VIX");
            _vxIdentity = new Identity("VX");
            _esIdentity = new Identity("ES");
            PlotIndicator("VIX", _vix);
            PlotIndicator("VIX", _vxIdentity);
            PlotIndicator("ES", _esIdentity);
        }

        public override void OnData(Slice slice)
        {
            if (slice.FutureChains.ContainsKey(_vx.Symbol))
            {
                var vixContract = slice.FutureChains[_vx.Symbol].OrderBy(x => x.Expiry).FirstOrDefault();
                if (vixContract != null)
                {
                    _latestVx = new IndicatorDataPoint(Time, vixContract.LastPrice);
                   
                }
            }

            if (slice.FutureChains.ContainsKey(_es.Symbol))
            {
                var esContract = slice.FutureChains[_es.Symbol].OrderBy(x => x.Expiry).LastOrDefault();
                if (esContract != null)
                {
                    _latestEs = new IndicatorDataPoint(Time, esContract.LastPrice);

                    if (!Portfolio.Invested && _entryLong)
                    {
                        MarketOrder(esContract.Symbol, 1);
                        _entryDate = Time;
                    }

                    if (Portfolio.Invested && Time > _entryDate.AddDays(15))
                    {
                        Liquidate();
                    }
                }
            }
        }


        public void OnData(Quandl data)
        {
            // Updates the identity indicators.
            if (data.Symbol.Value.EndsWith("VIX"))
                _vix.Update(Time, data.Value);
        }

        public override void OnEndOfDay()
        {
            _vxIdentity.Update(_latestVx);
            _esIdentity.Update(_latestEs);
            _entryLong = _vix < _vxIdentity;
        }
    }

    public class QaundlVIX : Quandl
    {
        public QaundlVIX() : base("VIX Close") { }
    }
}