Back to Community
A vix strategy which sharp rate > 1.7 and mdd < 0.15, seeking advices.

Features:
1, np.polyfit and vix/vxv as signal;
2, no overnight positions
3, dynamic adjusting position size by vvix value
4, inter-day trailing stop at -3%
5, 2012-present, sharp rate is above 1.5

Issues:
1, 2013 Jan - 2014 Oct no trades, which is a problem and lost chance for more profits;
2, need more carefully dealing with situation in 2008;

Clone Algorithm
48
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
'''
Features:
1, np.polyfit and vix/vxv as signal;
2, no overnight positions
3, dynamic adjust position size by vvix value
4, interday trailing stop at -3%
5, 2012-present, sharp rate is 1.5

Issues:
1, 2013 Jan - 2014 Oct no trade, which is a problem;
2, need think of situation in 2008 carefully;
'''


from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline.factors import CustomFactor
from quantopian.pipeline.data.quandl import cboe_vix as vixData
from quantopian.pipeline.data.quandl import cboe_vxv as vxvData
from quantopian.pipeline.data.quandl import cboe_vvix as vvixData
import pandas as pd
import numpy as np

class getVix(CustomFactor):  
    def compute(self, today, assets, out, vix):   
        out[:] = vix[-1]  

class getVxv(CustomFactor):  
    def compute(self, today, assets, out, vxv):   
        out[:] = vxv[-1]  

class getVvix(CustomFactor):  
    def compute(self, today, assets, out, vvix):   
        out[:] = vvix[-1]  
        
def initialize(context):
    set_slippage(slippage.FixedSlippage(spread=0.00))       
    context.vxx       = sid(38054)
    context.xiv       = sid(40516)
    context.uvxy      = sid(41969)
    context.threshold = 0.0
    context.vixList   = []
    context.vxvList   = []
    context.vvixList  = []
    context.trading_day = False
    context.position_price = 0.0
         
    pipe = Pipeline()
    attach_pipeline(pipe, 'my_pipeline')
    vix  = getVix(inputs  = [vixData.vix_close],window_length = 1) 
    vxv  = getVxv(inputs  = [vxvData.close],window_length = 1)  
    vvix = getVvix(inputs = [vvixData.vvix],window_length = 1) 
    pipe.add(vix, 'vix')
    pipe.add(vxv, 'vxv')
    pipe.add(vvix,'vvix')
    schedule_function(open_positions,  
                      date_rules.every_day(), 
                      time_rules.market_open(minutes = 30))
    schedule_function(close_positions,
                      date_rules.every_day(), 
                      time_rules.market_close())
                      
def before_trading_start(context, data):
    output =  pipeline_output('my_pipeline')
    output =  output.dropna()    
    vix    =  output.loc[sid(38054),'vix']
    vxv    =  output.loc[sid(38054),'vxv'] 
    vvix   =  output.loc[sid(38054),'vvix']     
    context.vixList.append(vix)
    context.vxvList.append(vxv)
    context.vvixList.append(vvix)
    
# Trailing stop    
def handle_data(context, data):  
    if context.trading_day and context.account.leverage > 0:
        now   = data.current(context.xiv, 'price')
        last  = context.position_price
        pct   = (now - last) / last 
        if pct < -0.03:
            date  = get_datetime('US/Eastern').strftime(" %Y-%m-%d ")
            log.warn( 'Trailing stop at: ' + str(date) + str(round(pct,3)))    
            for s in context.portfolio.positions:
                order_target_percent(s, 0.0)

# Got these parametbers by np.polyfit analysis     
def estimateVxv(context, data, vix_value):
    return     -0.00364131 * vix_value * vix_value + \
                1.07400974 * vix_value +  \
                1.88132538    

def getDelta(context, data, vix_value, vxv_value):
    estimatedVxv = estimateVxv(context, data, vix_value)
    return vxv_value - estimatedVxv
    
def getScaleByVvix(context, data):
    if len(context.vvixList) >10 + 2:
        return np.mean(context.vvixList[-10:])/110.00
    else:
        return 0.85

def open_positions(context, data):    
    vix  = context.vixList[-1]
    vxv  = context.vxvList[-1]
    v2   = round(vix/vxv,2)  
    delta = getDelta(context, data, vix, vxv)
    scale = getScaleByVvix(context, data)    
    if v2 < 0.92 and delta > context.threshold:        
        order_target_percent(context.uvxy,  - 0.5 * scale)
        context.trading_day = True
        context.position_price = data.current(context.xiv, 'price')
        
def close_positions(context, data):
    order_target_percent(context.uvxy, 0.0)
    context.trading_day = False
    
    
    
   
There was a runtime error.