"Futures not allowed for live trading" error upon attempt to paper trade or broker trade. Could someone from Quantopian explain this. Targeted algorithm is not trading Futures, but instead is using them as an indicator to trade valid sids. Why this is not allowed? What particular hurdles are there? How this could be "fixed"?

120
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 talib
from math import trunc
from pytz import timezone
import numpy as np
import pandas as pd
import datetime
import math
import time
import re
import functools
import itertools

#Max_Wager in \$ we want to invest into this algorithm
Max_Wager = 0 #5000.
#Or set above Max_Wager to 0 and set Max_Wager_Percent, as percent of portfolio
Max_Wager_Percent = 40.

History = 128
# Setting thresholds
threshold_vix_too_low = 10.8 # first percentile, very rare case, very likely VIX will pop so we want to be in UVXY

threshold_xiv = -0.049 # 60th percentile, as we want to be primarily in XIV
threshold_uvxy = -threshold_xiv # symmetry

threshold_vxv_xiv = 0.79 # first percentile, very rare case
threshold_vxv_uvxy = 2 - threshold_vxv_xiv # symmetry

threshold_macd = -0.55 # first percentile, we want to pass 99% of the cases here

threshold_vix_high = 19.9 # 85th percentile, we are already going to be in XIV 60% of the time, so need to be careful
# no more than total 75% of the time in XIV

threshold_vix_low = 11.5 # 5th percentile, very rare case, may be VIX will pop so we want to be in UVXY

threshold_vc_low = -0.148 # 1.5th percentile, very rare, we are already going to be in XIV 60% of the time, so need to be careful
# no more than total 75% of the time in XIV

threshold_vc_high = 0.046 #80th percentile, we will hardly be in UVXY (actually 51 is 80th percentile)
# so we need to pick up some cases where which is biased towards UVXY to get to at least 15% of the time in UVXY

threshold_vc_low_2 = 0.0 #50th percentile, below this we go for UVXY in lieu of any other signals
threshold_vc_high_2 = -0.06 # testing this, this is fitted

# relaxing condition to invest in XIV from 60th to 62nd percentile (~5%), absolute value also relaxes ~5% from -0.049 to -0.046
threshold_xiv_2 = -0.046 # 62th percentile
# this is to check for one last time if no signals have it, before we default to TQQQ

threshold_uvxy_2 = -0.008 # 85th percentile, taking a risk to invest in UVXY when there's hardly any contango or backwardation
# this is to check for one last time if no signals have it, before we default to TQQQ

threshold_xiv_ratio = -0.06 # first percentile
# if XIV has dropepd that much we probably don't want to be long XIVeven though other signals say yes, default to TQQQ
threshold_uvxy_ratio = -threshold_xiv_ratio # symmetry
# if XIV has gone up that much we probably don't want to be long UVXY even though other signals say yes, default to TQQQ

# Blending two V1 and V2 ratios  together using a weighted average
ratio_weight = 0.7

def initialize(context):

fetch_csv(vixUrl,
symbol='v',
skiprows=1,
date_column='Date',
post_func=shift_data)

fetch_csv(vxvUrl,
symbol='vxv',
skiprows=2,
date_column='Date',
post_func=shift_data)

context.xiv = sid(40516)
context.tqqq = sid(39214)
context.uvxy = sid(41969)
context.spyg = sid(22009)
context.vix = -1
context.futures = continuous_future('VX')

schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_open(hours = 0, minutes = 1))

def my_rebalance(context, data):

update_indices(context, data)
last_vix = data.current('v', 'Close')
last_vxv = data.current('vxv', 'Close')

cl_chain = data.current_chain(context.futures)
front = cl_chain
second = cl_chain

last_vx1 = data.current(front, 'price')
last_vx2 = data.current(second, 'price')

log.info("%s %5.3f %s %5.3f Vix %5.3f Vxv %5.3f" %(front, last_vx1, second, last_vx2, last_vix, last_vxv))

# Calculating the gap ratio between spot vix and the first month vix future
last_ratio_v_v1 = last_vix/last_vx1
# Calculating the contango ratio of the front and second month VIX Futures
last_ratio_v1_v2 = last_vx1/last_vx2
# average of above 2 using ratio_weight (more to front month)
last_ratio = (ratio_weight*last_ratio_v_v1) + ((1-ratio_weight)*last_ratio_v1_v2) - 1
# VIX to VXV ratio
vix_vxv_ratio = last_vix/last_vxv

# Retrieve SPY prices for technical indicators
prices = data.history(context.spyg, 'open', 40, '1d')
# Retrieve SPY MACD data
macda, signal, hist = talib.MACD(prices, fastperiod=12,slowperiod=26,signalperiod=9)
macd = macda[-1] - signal[-1]

# Calculate how much vix moved the previous day
if (context.vix <> -1) :
vix_ratio = last_vix/context.vix -1
else :
vix_ratio = 0
context.vix = last_vix

#change in XIV from previous day
xiv_history = data.history(context.xiv, 'price', 2, '1d')
xiv_ratio = xiv_history/xiv_history - 1

if last_vix < threshold_vix_too_low: # if VIX is too low, invest in UVXY witht he hope of a spike
log.info("CASE UVXY 0")
target_sid = context.uvxy

elif last_ratio < threshold_xiv: # if contango is high, invest in XIV to gain from decay
log.info("CASE XIV 1")
target_sid = context.xiv

elif vix_vxv_ratio < threshold_vxv_xiv: # if short term vol is low compared to mid term, invest in XIV to gain from decay
log.info("CASE XIV 2")
target_sid = context.xiv

elif last_ratio > threshold_uvxy and macd > threshold_macd: # if backwardation is high, invest in UVXY to gain from decay
log.info("CASE UVXY 3")
target_sid = context.uvxy

elif vix_vxv_ratio > threshold_vxv_uvxy: # if short term vol is high compared to mid term, invest in UVXY to gain from growth
log.info("CASE UVXY 4")
target_sid = context.uvxy

elif last_vix > threshold_vix_high: # if VIX is too high, invest in XIV expecting that VIX will drop
log.info("CASE XIV 5")
target_sid = context.xiv

elif last_vix < threshold_vix_low: # if VIX is too low, invest in XIV expecting that VIX will rise
log.info("CASE UVXY 6")
target_sid = context.uvxy

elif vix_ratio < threshold_vc_low: # Vix down sharply, invest in XIV expecting that futures curve gets pulled down
log.info("CASE XIV 7")
target_sid = context.xiv

elif vix_ratio > threshold_vc_high: # Vix up sharply, invest in UVXY expecting that futures curve gets pulled up
log.info("CASE UVXY 8")
target_sid = context.uvxy

elif vix_ratio > threshold_vc_high_2: #have to think
log.info("CASE XIV 9")
target_sid = context.xiv

elif vix_ratio < threshold_vc_low_2: # vix dropped. There are no other signals. in the absence of any signal, try UVXY
log.info("CASE UVXY 10")
target_sid = context.uvxy

elif last_ratio < threshold_xiv_2: # before we give up on XIV and move to TQQQ let's relax the contango conditions a bit
log.info("CASE XIV 11")
target_sid = context.xiv

elif last_ratio > threshold_uvxy_2: # before we give up on UVXY and move to TQQQ let's relax the backwardation conditions a bit
log.info("CASE UVXY 12")
target_sid = context.uvxy

else:
log.info("CASE TQQQ 13")
target_sid = context.tqqq

if (target_sid == context.xiv and xiv_ratio < threshold_xiv_ratio) :
# indicators say XIV but it just dropped overnight, so got for TQQQ
log.info("CASE TQQQ 14")
target_sid = context.tqqq

elif (target_sid == context.uvxy and xiv_ratio > threshold_uvxy_ratio) :
# indicators say UVXY but it just dropped overnight, so got for TQQQ
log.info("CASE TQQQ 15")
target_sid = context.tqqq

if target_sid not in context.portfolio.positions:

Wager = Max_Wager
if Wager == 0.:
Wager = Max_Wager_Percent/100.*context.portfolio.portfolio_value
Weight = Wager/context.portfolio.portfolio_value
log.info("Wager %5.2f Weight %5.2f" %(Wager, Weight))

order_target_percent(context.tqqq,0)
order_target_percent(context.uvxy,0)
order_target_percent(context.xiv,0)
order_target_percent(target_sid, Weight)

def update_indices(context, data):
context.fetch_failed = False
context.vix_vals = unpack_from_data(context, data, 'v')
context.vxv_vals = unpack_from_data(context, data, 'vxv')

def fix_close(df,closeField):
df = df.rename(columns={closeField:'Close'})
# remove spurious asterisks
df['Date'] = df['Date'].apply(lambda dt: re.sub('\*','',dt))
# convert date column to timestamps
df['Date'] = df['Date'].apply(lambda dt: pd.Timestamp(datetime.datetime.strptime(dt,'%m/%d/%Y')))
df = df.sort_values(by='Date', ascending=True)
return df

last_date = pd.to_datetime(date)
next_dt = tdays[tdays.searchsorted(last_dt) + 1]
return next_dt

last_date = df.index[-1]
blank_row = pd.Series({}, index=df.columns, name=subsequent_date)
# add today, and shift all previous data up to today. This
# should result in the same data frames as in backtest
df = df.append(blank_row).shift(1).dropna(how='all')
return df

def shift_data(df):
log.info("Pre-Shift")
df.fillna(method='ffill')
df['PrevCloses'] = my_rolling_apply_series(df['Close'], to_csv_str, History)
dates = pd.Series(df.index)
dates.index = df.index
df['PrevDates'] = my_rolling_apply_series(dates, to_csv_str, History)
return df

def unpack_from_data(context, data, sym):
try:
v = data.current(sym, 'PrevCloses')
i = data.current(sym, 'PrevDates')
return from_csv_strs(i,v,True).apply(float)
except:
log.warn("Unable to unpack historical {s} data.".format(s=sym))
context.fetch_failed = True

#log.info("VIX: Pre-Massage")
df = fix_close(df,'VIX Close')
#log.info("VIX: Post-Massage")
return df

#log.info("VXV: Pre-Massage")
df.rename(columns={'Unnamed: 0': 'Date'}, inplace=True)
df = fix_close(df,'CLOSE')
#log.info("VXV: Post-Massage")
return df

# convert a series of values to a comma-separated string of said values
def to_csv_str(s):
return functools.reduce(lambda x,y: x+','+y, pd.Series(s).apply(str))

# a specific instance of rolling apply, for Series of any type (not just numeric,
# ala pandas.rolling_apply), where the index of the series is set to the indices
# of the last elements of each subset
def my_rolling_apply_series(s_in, f, n):
s_out = pd.Series([f(s_in[i:i+n]) for i in range(0,len(s_in)-(n-1))])
s_out.index = s_in.index[n-1:]
return s_out

# reconstitutes a Series from two csv-encoded strings, one of the index, one of the values
def from_csv_strs(x, y, idx_is_date):
s = pd.Series(y.split(','),index=x.split(','))
if (idx_is_date):
s.index = s.index.map(lambda x: pd.Timestamp(x))
return s


There was a runtime error.
1 response

I am not quite sure, but I believe they are still developing futures for live trading. Usually they don't implement stuff all at once.