| Overall Statistics |
|
Total Trades 513 Average Win 1.74% Average Loss -1.53% Compounding Annual Return 81.332% Drawdown 29.900% Expectancy 0.188 Net Profit 89.185% Sharpe Ratio 1.348 Loss Rate 45% Win Rate 55% Profit-Loss Ratio 1.14 Alpha 0.461 Beta 0.217 Annual Standard Deviation 0.349 Annual Variance 0.122 Information Ratio 1.186 Tracking Error 0.36 Treynor Ratio 2.166 Total Fees $1548.19 |
-no value-
using System;
using System.CodeDom;
using QuantConnect.Algorithm;
using QuantConnect.Data;
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Custom;
using QuantConnect.Indicators;
namespace Sandbox.DualConsolidation
{
public class DualConsolidation : QCAlgorithm
{
private const string VIX = "YAHOO/INDEX_VIX";
private const string VXV = "CBOEFE/INDEX_VXV";
private SimpleMovingAverage smaVIX;
private SimpleMovingAverage smaVXV;
private IndicatorBase<IndicatorDataPoint> ratio_VXV_VIX;
private string vxx = "VXX";
private string xiv = "XIV";
public override void Initialize()
{
SetStartDate(2015, 11, 11);
SetCash(25000);
// request data
AddData<Quandl>(VIX);
AddData<Quandl>(VXV);
// define data sources for our functional indicator, these are really just 'identities' of the closing price
smaVIX = SMA(VIX, 10);
smaVXV = SMA(VXV, 10);
// the functional indicator takes as arguments two functions,
// the first is a ComputeNextValue function
// the second is an IsReady function
ratio_VXV_VIX = new FunctionalIndicator<IndicatorDataPoint>("ratio",
point => RatioIndicator_ComputeNextValue(point, smaVXV, smaVIX),
ratioIndicator => RatioIndicator_IsReady(ratioIndicator, smaVXV, smaVIX)
);
// we register to the VXV and VIX symbols, so when either of these gets data updates our indicator will recompute
var identityConsolidator = new IdentityDataConsolidator<Quandl>();
RegisterIndicator(VXV, ratio_VXV_VIX, identityConsolidator, x => x.Value);
RegisterIndicator(VIX, ratio_VXV_VIX, identityConsolidator, x => x.Value);
AddSecurity(SecurityType.Equity, vxx, Resolution.Minute);
AddSecurity(SecurityType.Equity, xiv, Resolution.Minute);
}
private DateTime previous;
public void OnData(Quandl data)
{
if (IsWarmingUp) return;
if (previous.Date != data.Time.Date && smaVIX.IsReady && smaVXV.IsReady && ratio_VXV_VIX.IsReady)
{
previous = data.Time;
Plot("Data", smaVIX, smaVXV);
Plot("Ratio", ratio_VXV_VIX);
if (ratio_VXV_VIX < 0.923m)
{
Liquidate(xiv);
SetHoldings(xiv, -1);
} else
{
Liquidate(xiv);
SetHoldings(xiv, 1);
}
}
}
/// <summary>
/// This code is run as part of the ratio_VXV_VIX functional indicator
/// </summary>
/// <remarks>
/// This is the ComputeNextValue function implementation for IndicatorBase
/// </remarks>
private decimal RatioIndicator_ComputeNextValue(IndicatorDataPoint data,
IndicatorBase<IndicatorDataPoint> vxv,
IndicatorBase<IndicatorDataPoint> vix)
{
return vxv / vix;
}
/// <summary>
/// This code is run as part of the ratio_VXV_VIX functional indicator
/// </summary>
/// <remarks>
/// This is the IsReady function implementation for IndicatorBase
/// </remarks>
private bool RatioIndicator_IsReady(IndicatorBase<IndicatorDataPoint> functionalIndicator,
IndicatorBase<IndicatorDataPoint> vxv,
IndicatorBase<IndicatorDataPoint> vix)
{
return vxv.IsReady && vix.IsReady;
}
}
}