Back to Community
Using VIX as an indicator

This is a simple script I'm trying to complete that notes a MA crossover based on the VIX. I'm having a time importing historical VIX data and getting it to work. I've searched the forum and tried to implement other examples, like from here, but to no avail. They are either not what I'm looking for or they are over my head. Is it possible to import and format it so that it could be used similarly like a data object? I'd love to be able to expand this concept and apply it to other indicators in a similar fashion. I have used AAPL as a placeholder for the VIX data in the backtest so it could finish. Any help or guidance is appreciated.

Clone Algorithm
2
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# To run an algorithm in Quantopian, you need two functions: initialize and 
# handle_data.
import numpy as np
import pandas as pd
import talib


def initialize(context):
    # This initialize function sets any data or variables that you'll use in
    # your algorithm.  For instance, you'll want to define the security (or 
    # securities) you want to backtest.  You'll also want to define any 
    # parameters or values you're going to use.

    context.stock = sid(8554)
    context.vix = sid(24)
    
    # Run this everyday, at market close
    #schedule_function(market_close, date_rules.every_day(), time_rules.market_close(minutes=1))
    
    schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_close(minutes=1))
     
    # Record tracking variables at the end of each day.
    schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close())    

# Rebalance daily.
def my_rebalance(context, data):
    crossover=0
    stock = context.stock
    vix = context.vix
    cash = context.portfolio.cash
    current_position = context.portfolio.positions[context.stock].amount
    
    
    # MA
    context.price_hist = data.history(vix, 'close', 3, '1d')
    context.mavg_short = context.price_hist.mean()
    context.price_hist = data.history(vix, 'close', 60, '1d')
    context.mavg_long = context.price_hist.mean() 
    

    # This is the meat of the algorithm, placed in this if statement.
    if context.mavg_short < context.mavg_long:
        crossover=100
        order_value(stock, cash,)
 
    elif context.mavg_short < context.mavg_long:
        # Now we can sell
        crossover=0
        order(context.stock, -current_position)
        
    record(short=context.mavg_short, long=context.mavg_long, cross=crossover)    

def my_record_vars(context, data):
    log.info('\n : %s' % (context.mavg_long))
There was a runtime error.
3 responses

Dave,
Looks like the post
https://www.quantopian.com/posts/stale-vix-pipeline-feed
shows two ways to get at VIX.

I modified that code slightly (changed target of "out[:] =" in CustomFactor to fix a bug.
Also used record() to plot custom data...click on two versions of VIX to see is_match series...slight mismatch only in two places.

Hopefully, this will help you.
alan

Clone Algorithm
6
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
import pandas as pd
import numpy as np

# for pipeline
from quantopian.pipeline import Pipeline
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline.factors import CustomFactor
from quantopian.pipeline.data.quandl import yahoo_index_vix

# for fetcher
from zipline.utils.tradingcalendar import get_early_closes
from zipline.utils import tradingcalendar
import re

# for pipeline
class Get_VIX(CustomFactor):    
    inputs = [yahoo_index_vix.close]
    window_length = 1    
    def compute(self, today, assets, out, vix):
        out[:] = vix[0][0]     

def before_trading_start(context, data):
    output = pipeline_output('vix_pipeline')
    output = output.dropna()    
    context.pipeline_vix = output['vix'].loc[context.vxx] 

# for fetcher
def addFieldsVIX(df):
    df = reformat_quandl(df,'VIX Close')
    return df

def reformat_quandl(df,closeField):
    df = df.rename(columns={closeField:'price'})
    dates = df.Date.apply(lambda dt: pd.Timestamp(re.sub('\*','',dt), tz='US/Eastern'))
    df['Date'] = dates.apply(next_trading_day)
    return df
            
def next_trading_day(dt):
    tdays = tradingcalendar.trading_days
    normalized_dt = tradingcalendar.canonicalize_datetime(dt)
    idx = tdays.searchsorted(normalized_dt)
    return tdays[idx + 1]


def handle_data(context, data):
    pass

def initialize(context):
    context.vxx = symbol('VXX')
    context.epsilon = .01

    pipe = Pipeline()
    attach_pipeline(pipe, 'vix_pipeline')  
    v = Get_VIX()    
    pipe.add(v, 'vix')
    
    fetch_csv('http://www.cboe.com/publish/scheduledtask/mktdata/datahouse/vixcurrent.csv', 
              symbol='vix', 
              skiprows=1,
              date_column='Date', 
              pre_func=addFieldsVIX)    

    schedule_function(
      myfunc,
       date_rules.every_day(),
       time_rules.market_open())
        
def myfunc(context, data):
    fetched_vix = data['vix'].price  
    mismatch = (abs(fetched_vix - context.pipeline_vix) > context.epsilon)
    log.info("Fetched VIX = %.2f   Pipeline VIX = %.2f  %sMATCH " % (fetched_vix, context.pipeline_vix, "MIS" if mismatch else ""))
    record(cboe_vix=fetched_vix, pipe_vix=context.pipeline_vix, is_match=~mismatch)
There was a runtime error.

Alan,

Thanks for your code, it looks accurate. My problem is that I don't know how to use it. My python skills are on the novice side and I don't know how to take your code and obtain two moving averages, or any other indicator, for the VIX.

Dave,

You may create custom factor in pipeline or create two moving averages as in this sample.

Clone Algorithm
3
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# VIX hist and ma data pipe

import pandas as pd
import numpy as np

from quantopian.pipeline import Pipeline
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline.factors import CustomFactor
from quantopian.pipeline.data.quandl import yahoo_index_vix

def initialize(context):
    context.spy = symbol('spy')
    pipe = Pipeline()
    attach_pipeline(pipe, 'vix_pipeline')  
    v = Get_VIX()    
    pipe.add(v, 'vix') 
    context.vix_hist=np.array([]) 
    schedule_function(myfunc, date_rules.every_day(), time_rules.market_open())  

def before_trading_start(context, data):
    output = pipeline_output('vix_pipeline')
    output = output.dropna()    
    context.pipeline_vix = output['vix'].loc[context.spy]  
        
def myfunc(context, data):
    ma_f = 10
    ma_s = 50
    
    context.vix_hist=np.append(context.vix_hist, context.pipeline_vix)
    if len(context.vix_hist) < ma_s: return
    vix_fast_ma = context.vix_hist[-(ma_f+1):].mean()
    vix_slow_ma = context.vix_hist[-(ma_s+1):].mean()
    
    record(pipe_vix=context.pipeline_vix, vix_fast_ma = vix_fast_ma, vix_slow_ma = vix_slow_ma ) 
    
    
class Get_VIX(CustomFactor):    
    inputs = [yahoo_index_vix.close]
    window_length = 1    
    def compute(self, today, assets, out, vix):
        out[:] = vix[0][0]   
There was a runtime error.