def carry_prev(inst, **kw): """ Analogue of carry_next() but looks at the previous contract. Useful when not trading the nearest contract but one further one. Typically you'd do this for instruments where the near contract has deathly skew - e.g. Eurodollar or VIX. """ current_contract = inst.roll_progression().to_frame().set_index('contract', append=True).swaplevel() prev_contract = inst.roll_progression().apply(inst.next_contract, months=inst.trade_only, reverse=True).to_frame().set_index('contract', append=True).swaplevel() current_prices = inst.contracts(active_only=True).join(current_contract, how='inner')['close'].reset_index('contract') prev_prices = inst.contracts(active_only=True).join(prev_contract, how='inner')['close'].reset_index('contract') # Replace zeros with nan prev_prices[prev_prices == 0] = np.nan current_prices['contract'] = current_prices['contract'].apply(_get_month) prev_prices['contract'] = prev_prices['contract'].apply(_get_month) td = current_prices['contract'] - prev_prices['contract'] td.loc[td <= 0] = td.loc[td <= 0] + 12 td = td / 12 # Apply a 5 day mean to prices to stabilise signal carry = prev_prices['close'] - current_prices['close'] carry = carry.rolling(window=5).mean() / td f = norm_forecast(carry).ffill(limit=3) if f.sum() == 0: print(inst.name + ' carry is zero') return f.interpolate().rolling(window=90).mean().rename('carry')
def carry_spot(inst, **kw): """ Calculates the carry between the current future price and the underlying spot price. """ f = inst.spot() - inst.market_price().reset_index('contract', drop=True) f = f * 365 / inst.time_to_expiry() return norm_forecast(f.ewm(90).mean()).rename('carry_spot')
def open_close(inst, **kw): """ Read this one in a book, and it was easy to test. Consistently unprofitable in its current form. """ #yesterdays open-close, divided by std deviation of returns inst.panama_prices() a = inst.rp().to_frame().set_index('contract', append=True).swaplevel().join(inst.contracts(), how='inner') f = ((a['close']-a['open'])/inst.return_volatility).dropna().reset_index('contract', drop=True) return norm_forecast(f).rename('open_close')
def breakout(inst, **kw): """ Returns a DataFrame of breakout forecasts based on Rob Carver's work here: https://qoppac.blogspot.com.es/2016/05/a-simple-breakout-trading-rule.html """ prices = inst.panama_prices(**kw) lookbacks = [40, 80, 160, 320] res = map(partial(breakout_fn, prices), lookbacks) res = pd.DataFrame(list(res)).transpose() res.columns = pd.Series(lookbacks).map(lambda x: "brk%d" % x) return norm_forecast(res)
def ewmac(inst, **kw): """ Exponentially weighted moving average crossover. Returns a DataFrame with four different periods. """ d = norm_vol(inst.panama_prices(**kw)) columns = [8, 16, 32, 64] f = map(partial(pickleable_ewmac, d), columns) f = pd.DataFrame(list(f)).transpose() f.columns = pd.Series(columns).map(lambda x: "ewmac"+str(x)) return norm_forecast(f)
def carry_next(inst, debug=False, **kw): """ Calculates the carry between the current future price and the next contract we are going to roll to. """ # If not trading nearest contract, Nearer contract price minus current contract price, divided by the time difference # If trading nearest contract, Current contract price minus next contract price, divided by the time difference current_contract = inst.roll_progression().to_frame().set_index( 'contract', append=True).swaplevel() next_contract = inst.roll_progression().apply( inst.next_contract, months=inst.trade_only).to_frame().set_index('contract', append=True).swaplevel() current_prices = inst.contracts(active_only=True).join( current_contract, how='inner')['close'].reset_index('contract') next_prices = inst.contracts(active_only=True).join( next_contract, how='inner')['close'].reset_index('contract') #Replace zeros with nan next_prices[next_prices == 0] = np.nan # Apply a ffill for low volume contracts # next_prices.ffill(inplace=True) current_prices['contract'] = current_prices['contract'].apply(_get_month) next_prices['contract'] = next_prices['contract'].apply(_get_month) td = next_prices['contract'] - current_prices['contract'] td.loc[td <= 0] = td.loc[td <= 0] + 12 td = td / 12 # Apply a 5 day mean to prices to stabilise signal carry = (current_prices['close'] - next_prices['close']) carry = carry.rolling(window=5).mean() / td f = norm_forecast(carry).ffill(limit=3) # if f.isnull().values.any(): # print(inst.name, "has some missing carry values") if f.sum() == 0: print(inst.name + ' carry is zero') if debug == True: return f.rename('carry_next'), current_prices, next_prices, td # return f.mean().rename('carry_next') return f.interpolate().rolling(window=90).mean().rename('carry_next')
def carry_next(inst, debug=False, **kw): """ Calculates the carry between the current future price and the next contract we are going to roll to. """ # If not trading nearest contract, Nearer contract price minus current contract price, divided by the time difference # If trading nearest contract, Current contract price minus next contract price, divided by the time difference current_contract = inst.roll_progression().to_frame().set_index('contract', append=True).swaplevel() next_contract = inst.roll_progression().apply(inst.next_contract, months=inst.trade_only).to_frame().set_index('contract', append=True).swaplevel() current_prices = inst.contracts(active_only=True).join(current_contract, how='inner')['close'].reset_index('contract') next_prices = inst.contracts(active_only=True).join(next_contract, how='inner')['close'].reset_index('contract') #Replace zeros with nan next_prices[next_prices==0] = np.nan # Apply a ffill for low volume contracts # next_prices.ffill(inplace=True) current_prices['contract'] = current_prices['contract'].apply(_get_month) next_prices['contract'] = next_prices['contract'].apply(_get_month) td = next_prices['contract'] - current_prices['contract'] td.loc[td<=0] = td.loc[td<=0] + 12 td = td/12 # Apply a 5 day mean to prices to stabilise signal carry = (current_prices['close'] - next_prices['close']) carry = carry.rolling(window=5).mean()/td f = norm_forecast(carry).ffill(limit=3) # if f.isnull().values.any(): # print(inst.name, "has some missing carry values") if f.sum() == 0: print(inst.name + ' carry is zero') if debug==True: return f.rename('carry_next'), current_prices, next_prices, td # return f.mean().rename('carry_next') return f.interpolate().rolling(window=90).mean().rename('carry_next')