from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Common")
from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Python import PythonQuandl
from datetime import datetime, timedelta
import numpy as np
import math
import time
#https://www.quantconnect.com/tutorials/strategy-library/exploiting-term-structure-of-vix-futures
class VerticalNadionRadiator(QCAlgorithm):
def Initialize(self):
self.es_liq = self.start_time = self.Time
self.SetStartDate(2010, 1, 1) # Set Start Date
self.SetEndDate(2013,3,1)
self.SetCash(100000) # Set Strategy Cash
self.es = self.AddFuture(Futures.Indices.SP500EMini, Resolution.Minute)
self.es.SetFilter(timedelta(3), timedelta(200))
self.ty = self.AddFuture(Futures.Financials.Y10TreasuryNote, Resolution.Minute)
self.ty.SetFilter(timedelta(3), timedelta(200))
self.vx = self.AddFuture(Futures.Indices.VIX, Resolution.Minute)
self.vx.SetFilter(timedelta(0), timedelta(100))
self.spy = self.AddEquity("SPY",Resolution.Minute)
self.spy.SetDataNormalizationMode(DataNormalizationMode.Raw)
self.vx_contracts = []
self.es_contracts = []
self.ty_contracts = []
self.contango = []
self.CONTANGO = False
self.SPY_sma_period = 20 #self.GetParameter("ma_length")
self.SPY_prices = []
self.SPY_sma = []
self.downward_sloping_ma = False
def OnData(self, data):
es_leverage = 5
ty_leverage = 8
ty_stop_pc = 0.015
if self.Time.hour == 15 and self.Time.minute == 0:
self.SPY_prices.append(self.spy.Close)
if len(self.SPY_prices)>self.SPY_sma_period:
self.SPY_prices.pop(0)
self.SPY_sma.append(np.mean(self.SPY_prices))
if len(self.SPY_sma)>5:
self.SPY_sma.pop(0)
if self.SPY_sma[-1] < self.SPY_sma[-2]*1.00025:
self.downward_sloping_ma = True
else:
self.downward_sloping_ma = False
#self.Debug("Today's SMA: "+str(self.SPY_sma[-1])+" vs
#yesterday's: "+str(self.SPY_sma[-2]))
for chain in data.FutureChains:
contracts = [contract for contract in chain.Value]
for j in contracts:
if Futures.Indices.VIX in str(j):
self.vx_contracts = []
elif Futures.Indices.SP500EMini in str(j):
self.es_contracts = []
elif Futures.Financials.Y10TreasuryNote in str(j):
self.ty_contracts = []
for i in contracts:
if Futures.Indices.VIX in str(i):
self.vx_contracts.append(i)
elif Futures.Indices.SP500EMini in str(i):
self.es_contracts.append(i)
elif Futures.Financials.Y10TreasuryNote in str(i):
self.ty_contracts.append(i)
self.vx_contracts = self.ContractSorter(self.vx_contracts)
self.es_contracts = self.ContractSorter(self.es_contracts)
self.ty_contracts = self.ContractSorter(self.ty_contracts)
if len(self.es_contracts) < 0.5 or len(self.ty_contracts)<0.5:
return
if (self.es_contracts[0].Expiry - self.Time).days <5:
if self.Portfolio[self.es_contracts[0].Symbol].Quantity != 0:
quantity = self.Portfolio[self.es_contracts[0].Symbol].Quantity
self.SetHoldings(self.es_contracts[0].Symbol,0)
self.MarketOrder(self.es_contracts[1].Symbol,quantity)
self.Debug("Rolled ES contract forward")
self.es_contracts.pop(0)
if (self.ty_contracts[0].Expiry - self.Time).days <5:
if self.Portfolio[self.ty_contracts[0].Symbol].Quantity != 0:
quantity = self.Portfolio[self.ty_contracts[0].Symbol].Quantity
self.SetHoldings(self.ty_contracts[0].Symbol,0)
self.MarketOrder(self.ty_contracts[1].Symbol,quantity)
self.ty_stop_price = self.ty_stop_price * \
self.ty_contracts[1].AskPrice/self.ty_contracts[0].AskPrice
self.Debug("Rolled TY contract forward")
self.ty_contracts.pop(0)
if (self.Time - self.start_time).days < 10 or len(self.vx_contracts)<1.5:
#or len(self.es_contracts)<0.5 or len(self.ty_contracts)<0.5:
return
if self.vx_contracts[0].AskPrice > 0 and self.vx_contracts[1].AskPrice >0:
self.contango.append(self.vx_contracts[1].AskPrice - self.vx_contracts[0].AskPrice)
if len(self.contango)>1440:
self.contango.pop(0)
if np.min(self.contango)>0.5:
self.CONTANGO = True
else:
self.CONTANGO = False
if not self.Securities["SPY"].Exchange.ExchangeOpen:
return
else:
if self.Portfolio.Invested:
if self.CONTANGO == True and self.downward_sloping_ma == False:
if self.Portfolio[self.ty_contracts[0].Symbol].Quantity !=0:
self.SetHoldings(self.ty_contracts[0].Symbol,0)
if (self.Time - self.es_liq).days > 5 and \
self.Portfolio[self.es_contracts[0].Symbol].Quantity == 0:
es_notional = self.es_contracts[0].AskPrice * \
self.es.SymbolProperties.ContractMultiplier
#self.Debug("ES notional is :" +str(es_notional))
es_to_buy = math.floor(self.Portfolio.Cash*es_leverage / es_notional)
#self.Debug("ES to buy is :" +str(es_to_buy))
#self.Debug("Port cash is : "+str(self.Portfolio.Cash))
self.MarketOrder(self.es_contracts[0].Symbol,es_to_buy)
self.Debug("VX1 and VX2 spread is: "+str(self.contango[-1]))
self.Debug("1. Bought ES @ "+str(self.es_contracts[0].AskPrice))
elif self.CONTANGO == False or self.downward_sloping_ma:
if self.Portfolio[self.es_contracts[0].Symbol].Quantity !=0:
self.SetHoldings(self.es_contracts[0].Symbol,0)
self.es_liq = self.Time
ty_notional = self.ty_contracts[0].AskPrice * \
self.ty.SymbolProperties.ContractMultiplier
ty_to_buy = math.floor(self.Portfolio.Cash*ty_leverage / ty_notional)
self.MarketOrder(self.ty_contracts[0].Symbol,ty_to_buy)
self.ty_stop_price = self.ty_contracts[0].AskPrice * (1-ty_stop_pc)
self.Debug("2. Sold ES @ "+str(self.es_contracts[0].AskPrice))
self.Debug("Bought TY @ "+str(self.ty_contracts[0].AskPrice))
if self.Portfolio[self.ty_contracts[0].Symbol].Quantity !=0 \
and self.ty_contracts[0].AskPrice < self.ty_stop_price:
self.SetHoldings(self.ty_contracts[0].Symbol,0)
self.Debug("3. Stopped out of TY @ "+str(self.ty_contracts[0].AskPrice))
# elif self.downward_sloping_ma:
# self.SetHoldings(self.es_contracts[0].Symbol,0)
elif not self.Portfolio.Invested:
if self.CONTANGO == True and (self.Time - self.es_liq).days > 5\
and self.downward_sloping_ma == False:
es_notional = self.es_contracts[0].AskPrice * \
self.es.SymbolProperties.ContractMultiplier
#self.Debug("ES notional is :" +str(es_notional))
es_to_buy = math.floor(self.Portfolio.Cash*es_leverage / es_notional)
#self.Debug("ES to buy is :" +str(es_to_buy))
#self.Debug("Port cash is : "+str(self.Portfolio.Cash))
self.MarketOrder(self.es_contracts[0].Symbol,es_to_buy)
self.Debug("VX1 and VX2 spread is: "+str(self.contango[-1]))
self.Debug("4. Bought ES @ "+str(self.es_contracts[0].AskPrice))
elif self.CONTANGO == False or self.downward_sloping_ma:
return
def OnOrderEvent(self, orderEvent):
if orderEvent.Status != OrderStatus.Filled:
#time.sleep(3)
self.Transactions.CancelOpenOrders()
def ContractSorter(self,contract_list):
if len(contract_list)>1.5:
return sorted(contract_list, key = lambda x: x.Expiry,reverse = False)
else:
return contract_list