def tail_vix_future(vix_spot, vix_future): """Contract: Short VIX future (>35dte). Entry: Every friday if VIX spot >= 15 and bear market. Exit: Every friday if VIX spot < 15 or bull market. Weight: 1 (based on VIX future price, not VIX spot). :param vix_spot: Vix spot data. :param vix_future: Vix future data.""" bear, bull = MA_regime(vix_spot.close, 5, 100, 'bear'), MA_regime(vix_spot.close, 5, 100, 'bull') entry_vix, exit_vix = vix_spot[vix_spot.close >= 15].dropna( ).index, vix_spot[vix_spot.close < 15].dropna().index weekly_friday = pd.date_range(vix_future.index[0], vix_future.index[-1], freq='W-FRI').date entry, exit = set(bear).intersection(entry_vix, weekly_friday), set( set(bull).union(exit_vix)).intersection(weekly_friday) tail_vix = Strategy('Tail') tail_vix.add_instrument(1, vix_future, entry, 35, -1, 'f', 'Roll') tail_vix.adjust_instrument(1, 'stop_date', exit) tail_vix.type_investment(1, 'underlying') tail_vix.weights(1, 1) tail_vix = Portfolio(tail_vix) tail_vix.weights({'Tail': 1}) tail_vix.fit() return tail_vix
def dstat_adjustment(spx_future, spx_spot): """Contract: Short SPX future (>35dte). Entry: Every last business day of the month + when trend (bull/bear) changes + at Dstat Down event. Exit: Roll. Weight: 0.25 bull and 0.75 bear. :param spx_future: SPX future data. :param spx_spot: SPX spot data.""" entry_trend = change_trend(spx_spot) entry_eom = entry_dates(spx_future.index[0], spx_future.index[-1], 'BM') entry_dstat, exit_dstat = search_dstat(spx_spot, [0, 1, 1], 2, 0.05, 0.95), exit_dstat_down(spx_spot) down_dates, entry_dstat, exit_dstat = match_entry_exit( entry_dstat, exit_dstat) entry = list(entry_trend) + list(entry_eom) + list(entry_dstat) entry = sorted(set(entry).intersection(down_dates)) dstat_adj = Strategy('DSTAT adjustment') dstat_adj.add_instrument(1, spx_future, entry, 35, 1, 'f', 'Roll') dstat_adj.adjust_instrument(1, 'stop_date', exit_dstat) dstat_adj.type_investment(1, 'underlying') bear, bull = MA_regime(spx_spot.close, 10, 200, 'bear'), MA_regime(spx_spot.close, 10, 200, 'bull') weights = pd.Series(0.75, index=list(bear) + list(bull)) weights.loc[bull] = 0.25 dstat_adj.weights(1, weights) return dstat_adj
def change_trend(spx_spot): """Compute the date when trend changes (pass from bear to bull or bull to bear). :param spx_spot: SPX spot data.""" bear = MA_regime(spx_spot.close, 10, 200, 'bear') bull = MA_regime(spx_spot.close, 10, 200, 'bull') trend = pd.Series(index=list(bear) + list(bull)) trend.loc[bear], trend.loc[bull] = 0, 1 trend = trend.sort_index() shift_trend = trend - trend.shift(1) change_bull = shift_trend[shift_trend == 1].dropna().index change_bear = shift_trend[shift_trend == -1].dropna().index change = sorted(list(change_bull) + list(change_bear)) return change
def trend_adjustment(spx_future, spx_spot): """Contract: Short SPX future (>35dte). Entry: Every last business day of the month + when trend (bull/bear) changes. Exit: Roll. Weight: 0.25 bull and 0.75 bear. :param spx_future: SPX future data. :param spx_spot: SPX spot data.""" entry_trend = change_trend(spx_spot) entry_eom = entry_dates(spx_future.index[0], spx_future.index[-1], 'BM') entry = list(entry_trend) + list(entry_eom) trend_adj = Strategy('Trend adjustment') trend_adj.add_instrument(1, spx_future, entry, 35, -1, 'f', 'Roll') trend_adj.type_investment(1, 'underlying') bear, bull = MA_regime(spx_spot.close, 10, 200, 'bear'), MA_regime(spx_spot.close, 10, 200, 'bull') weights = pd.Series(0.75, index=list(bear) + list(bull)) weights.loc[bull] = 0.25 trend_adj.weights(1, weights) return trend_adj
def TY(bond_future, spx_spot): """Contract : Long 10Y TY bond future (>35dte). Entry : Every last business day of the month + when trend (bull/bear) changes. Exit: Roll. Weight : 0.75 bull and 0.25 bear. :param bond_future: 10Y TY future data. :param spx_spot: SPX spot data.""" entry_trend = change_trend(spx_spot) entry_eom = entry_dates(bond_future.index[0], bond_future.index[-1], 'BM') entry = sorted(list(entry_trend) + list(entry_eom)) ty = Strategy('TY') ty.add_instrument(1, bond_future, entry, 35, 1, 'f', 'Roll') ty.type_investment(1, 'value') bear, bull = MA_regime(spx_spot.close, 10, 200, 'bear'), MA_regime(spx_spot.close, 10, 200, 'bull') weights = pd.Series(0.25, index=list(bear) + list(bull)) weights.loc[bull] = 0.75 ty.weights(1, weights) return ty
def tail_hedging(spx_put, spx_spot): """Contract : Long SPX put -0.05Δ (>35dte). Entry : Pass from Dstat up to Dstat down + Exit: Roll + Pass from Dstat down to Dstat up + 2x stop gain with pause of 180days. Weight : 0.01 (based on premium value, not underlying). :param spx_put: SPX put data. :param spx_spot: SPX spot data.""" bull = MA_regime(spx_spot.close, 10, 200, 'bull') entry_dstat, exit_dstat = search_dstat(spx_spot, [-1, 0], 1, 0.1, 0.9), search_dstat( spx_spot, [0, -1], 1, 0.1, 0.9) entry = set(entry_dstat).intersection(bull) tail = Strategy('Tail') tail.add_instrument(1, spx_put, entry, 35, 1, 'o', 'Expiry', -0.05) tail.adjust_instrument(1, 'stop_date', exit_dstat) dates = list(tail.instruments[1].groupby('trade_id').apply( lambda x: dates_stop_gain(x, 2)).dropna().values) dates.remove(str_to_datetime('2010-04-27')) tail.pause(1, dates, 180) tail.adjust_instrument(1, 'stop_gain', 2) tail.type_investment(1, 'value') tail.weights(1, 0.01) return tail
[return1, return2, return3, returns4]) returns = np.array([return1, return2, return3, returns4]) bounds = [(0.25, 1), (0.1, 1), (0.1, 0.25), (0.1, 0.25)] optimal_weights, optimal_returns, optimal_risks = markowitz( returns, bounds) plot_efficient_frontiere(returns, optimal_returns, optimal_risks, bounds) ####################################################### Genetic Algorithm ####################################################### portfolio = Portfolio(strat1, strat2, strat3, strat4) portfolio.weights({ 'strategy1': 1, 'strategy2': 1, 'strategy3': 1, 'strategy4': 1 }) bounds = [[(0.25, 1), (0.1, 1), (0.1, 0.25), (0.1, 0.25)], [(0.25, 1), (0.1, 1), (0.1, 0.25), (0.1, 0.25)]] bear = MA_regime(spx_spot.close, 10, 200, 'bear') bull = MA_regime(spx_spot.close, 10, 200, 'bull') regime = pd.Series(0, index=set(spx_put.index).union(bear, bull)) regime.loc[bull] = 1 genetic_algorithm(portfolio, regime, bounds, n_population=50, n_generation=10, tournsize=3, CXPB=0.5, MUTPB=0.2, indpb=0.05, display=True)