| Overall Statistics |
|
Total Trades 794 Average Win 0.96% Average Loss -0.43% Compounding Annual Return 43.813% Drawdown 16.100% Expectancy 0.506 Net Profit 113.552% Sharpe Ratio 1.643 Loss Rate 53% Win Rate 47% Profit-Loss Ratio 2.21 Alpha 0.313 Beta 0.035 Annual Standard Deviation 0.193 Annual Variance 0.037 Information Ratio 0.787 Tracking Error 0.252 Treynor Ratio 9.133 Total Fees $800.11 |
namespace QuantConnect
{
/*
* QuantConnect University: Futures Example
*
* QuantConnect allows importing generic data sources! This example demonstrates importing a futures
* data from the popular open data source Quandl.
*
* QuantConnect has a special deal with Quandl giving you access to Stevens Continuous Futurs (SCF) for free.
* If you'd like to download SCF for local backtesting, you can download it through Quandl.com.
*/
public class VolatilityETN : QCAlgorithm
{
string shortTerm = "VXX";
string longTerm = "VXZ";
decimal IVTS = 0;
string VIX = "YAHOO/INDEX_VIX";
string VXV = "CBOEFE/INDEX_VXV";
DateTime sampledToday;
//Initialize the data and resolution you require for your strategy:
public override void Initialize()
{
SetStartDate(2010,8,1);
SetEndDate(2012,9,1);
SetCash(25000);
AddSecurity(SecurityType.Equity, shortTerm, Resolution.Minute);
AddSecurity(SecurityType.Equity, longTerm, Resolution.Minute);
// by default, custom data does not fill forward. since this is
// daily data, it is emitted at midnight each day, but it will
// fill forward on the minute. below I set the exchange property
// so we don't perform fill forward during not equity hours
AddData<Quandl>(VXV, Resolution.Daily, fillDataForward: true);
AddData<Quandl>(VIX, Resolution.Daily, fillDataForward: true);
// since we're using fill forward logic we need to specify an exchange
// so we don't fill forward our minute data on the weekends
Securities[VIX].Exchange = new EquityExchange();
Securities[VXV].Exchange = new EquityExchange();
}
/// <summary>
/// Event - v3.0 DATA EVENT HANDLER: Basic template for user to override for receiving all subscription data in a single event
/// </summary>
/// <code>
/// TradeBars bars = slice.Bars;
/// Ticks ticks = slice.Ticks;
/// TradeBar spy = slice["SPY"];
/// List<Tick> aaplTicks = slice["AAPL"]
/// Quandl oil = slice["OIL"]
/// dynamic anySymbol = slice[symbol];
/// DataDictionary<Quandl> allQuandlData = slice.Get<Quand>
/// Quandl oil = slice.Get<Quandl>("OIL")
/// </code>
/// <param name="slice">The current slice of data keyed by symbol string</param>
public override void OnData(Slice data)
{
// make sure we have the data first before the sampledToday checks
// gets all Quandl data from our 'Slice' object
var quandls = data.Get<Quandl>();
if (!quandls.ContainsKey(VIX) || !quandls.ContainsKey(VXV)) return;
// add logic to have orders placed once / day
if (sampledToday.Date == Time.Date) return;
if (Time.TimeOfDay <= new TimeSpan(15, 45, 0)) return;
Log("Time is "+ Time);
// IVTS = VIX / VXV
IVTS = quandls[VIX].Value / quandls[VXV].Value;
Log("IVTS is " + IVTS);
// Add buy/sell logic
int count = new int();
if (IVTS <= .91m){
count = 1;
} else if ((0.91m < IVTS) && (IVTS <= 0.97m)) {
count = 2;
} else if (IVTS > .97m && IVTS <= 1.05m) {
count = 3;
} else {
count = 4;
}
Log("Count is " + count);
switch (count)
{
case 1:
SetHoldings(shortTerm, -.6);
SetHoldings(longTerm, .4);
break;
case 2:
SetHoldings(shortTerm, -.32);
SetHoldings(longTerm, .68);
break;
case 3:
SetHoldings(shortTerm, -.25);
SetHoldings(longTerm, .75);
break;
case 4:
SetHoldings(shortTerm, -.10);
SetHoldings(longTerm, .90);
break;
default:
Log("there is an error");
break;
}
sampledToday = Time;
}
}
}