# ################################## HOW TO USE #################################### # # # # This is a Jupyter notebook formatted as a script # # Format: https://jupytext.readthedocs.io/en/latest/formats.html#the-percent-format # # # # Save this file and remove the '.txt' extension # # In Jupyter Lab, right click on the Python file -> Open With -> Jupytext Notebook # # Make sure to have Jupytext installed: https://github.com/mwouts/jupytext # # # # ################################################################################## # # %% [markdown] # # Alignment # ## Pandas # %% h1_close = h1_data.get("Close") h4_close = h4_data.get("Close") h1_close.iloc[:4] # %% h4_close.iloc[:1] # %% h1_h4_ratio = h1_close / h4_close h1_h4_ratio.iloc[:4] # %% h4_close_shifted = h4_close.shift() h1_h4_ratio = h1_close / h4_close_shifted h1_h4_ratio.iloc[:8] # %% h1_h4_ratio.shift(-1).iloc[:8] # %% h4_h1_close = h4_close.shift(1).resample("1h").last().shift(-1).ffill() h4_h1_close.iloc[:8] # %% fig = h1_close.rename("H1").iloc[:16].vbt.plot() h4_h1_close.rename("H4_H1").iloc[:16].vbt.plot(fig=fig) fig.show() # %% h1_h4_ratio = h1_close / h4_h1_close h1_h4_ratio # %% h1_open = h1_data.get("Open") h4_open = h4_data.get("Open") h1_open.iloc[:8] # %% h4_h1_open = h4_open.resample("1h").first().ffill() h4_h1_open.iloc[:8] # %% [markdown] # ## VBT # %% h4_close.vbt.realign_closing("1h") # %% h4_open.vbt.realign_opening("1h") # %% [markdown] # ### Resampler # %% h4_h1_resampler = h4_close.vbt.wrapper.get_resampler("1h") h4_h1_resampler.source_index # %% h4_h1_resampler.target_index # %% h4_h1_resampler.source_freq # %% h4_h1_resampler.target_freq # %% pd_resampler = h4_close.resample("1h") vbt.Resampler.from_pd_resampler(pd_resampler, source_freq="4h") # %% resampler = vbt.Resampler.from_date_range( source_index=h4_close.index, source_freq="4h", start="2020-01-01 10:00:00", end="2020-01-01 22:00:00", freq="1h", ) # %% h4_close.vbt.realign_closing(resampler) # %% [markdown] # ### Custom index # %% target_index = pd.Index([ "2020-01-01", "2020-02-01", "2020-03-01", "2020-04-01", "2020-05-01", "2020-06-01", "2020-07-01", "2020-08-01", "2020-09-01", "2020-10-01", "2020-11-01", "2020-12-01", "2021-01-01" ]) resampler = vbt.Resampler(h4_close.index, target_index, target_freq=False) h4_close.vbt.realign_closing(resampler) # %% h4_close[h4_close.index < "2020-09-01"].iloc[-1] # %% target_index = pd.Index([ "2020-01-01", "2020-02-01", ]) resampler = vbt.Resampler(h4_close.index, target_index, target_freq=False) h4_close.vbt.realign_closing(resampler) # %% resampler = vbt.Resampler(h4_close.index, target_index, target_freq="30d") h4_close.vbt.realign_closing(resampler) # %% h4_open.vbt.realign("2020-06-07 12:15:00") # %% h4_close.vbt.realign( "2020-06-07 12:15:00", source_rbound=True ) # %% h4_high = h4_data.get("High") h4_high.vbt.realign( target_index, source_rbound=True ) # %% h4_high.index[h4_high.index < "2020-02-01"][-1] # %% h4_high.vbt.realign( target_index, source_rbound=True, target_rbound=True ) # %% resampler = vbt.Resampler(h4_high.index, target_index) resampler.target_rbound_index # %% resampler = vbt.Resampler( h4_high.index, target_index, target_freq=pd.offsets.MonthBegin(1)) resampler.target_rbound_index # %% h4_high.vbt.realign( resampler.replace( target_index=resampler.target_rbound_index, target_freq=False ), wrap_kwargs=dict(index=target_index) ) # %% h4_high.vbt.realign( target_index, freq=pd.offsets.MonthBegin(1), target_rbound="pandas" ) # %% h4_high[h4_high.index < "2020-03-01"].resample(vbt.offset("M")).last() # %% [markdown] # ### Numeric index # %% resampler = vbt.Resampler( source_index=np.arange(len(h4_high)), target_index=np.arange(len(h4_high))[::6], source_freq=1, target_freq=6 ) h4_high.vbt.realign( resampler, source_rbound=True, target_rbound=True ) # %% [markdown] # ### Forward filling # %% min5_index = vbt.date_range(start="2020", freq="5min", periods=3) min1_index = vbt.date_range(start="2020", freq="1min", periods=15) min5_mask = pd.Series(False, index=min5_index) min5_mask.iloc[0] = True min5_mask.iloc[2] = True resampler = vbt.Resampler(min5_index, min1_index) min1_mask = min5_mask.vbt.realign_closing(resampler) min1_mask # %% min1_mask = min5_mask.vbt.realign_closing(resampler, ffill=False) min1_mask # %% min1_mask = min1_mask.fillna(False).astype(bool) min1_mask # %% [markdown] # ## Indicators # %% h4_sma = vbt.talib("SMA").run( h4_data.get("Close"), skipna=True ).real d1_sma = vbt.talib("SMA").run( d1_data.get("Close"), skipna=True ).real h4_sma = h4_sma.ffill() d1_sma = d1_sma.ffill() # %% resampler = vbt.Resampler( d1_sma.index, h4_sma.index, source_freq="1d", target_freq="4h" ) d1_h4_sma = d1_sma.vbt.realign_closing(resampler) # %% d1_sma["2020-12-30":] # %% d1_h4_sma["2020-12-30":] # %% entries = h4_sma.vbt.crossed_above(d1_h4_sma) exits = h4_sma.vbt.crossed_below(d1_h4_sma) def plot_date_range(date_range): fig = h4_sma[date_range].rename("H4").vbt.plot() d1_h4_sma[date_range].rename("D1_H4").vbt.plot(fig=fig) entries[date_range].rename("Entry").vbt.signals.plot_as_entries( y=h4_sma[date_range], fig=fig) exits[date_range].rename("Exit").vbt.signals.plot_as_exits( y=h4_sma[date_range], fig=fig) return fig plot_date_range(slice("2020-02-01", "2020-03-01")).show() # %% d1_open_sma = vbt.talib("SMA").run( d1_data.get("Open"), skipna=True ).real d1_open_sma = d1_open_sma.ffill() d1_h4_open_sma = d1_open_sma.vbt.realign( resampler, source_rbound=False, target_rbound=True, ) # %% d1_open_sma["2020-12-30":] # %% d1_h4_open_sma["2020-12-30":] # %% def generate_bandwidths(freqs): bandwidths = [] for freq in freqs: close = h1_data.resample(freq).get("Close") bbands = vbt.talib("BBANDS").run(close, skipna=True) upperband = bbands.upperband.ffill() middleband = bbands.middleband.ffill() lowerband = bbands.lowerband.ffill() bandwidth = (upperband - lowerband) / middleband bandwidths.append(bandwidth.vbt.realign_closing("1h")) df = pd.concat(bandwidths, axis=1, keys=pd.Index(freqs, name="timeframe")) return df.ffill() bandwidths = generate_bandwidths(["1h", "4h", "1d", "7d"]) bandwidths # %% bandwidths.loc[:, ::-1].vbt.ts_heatmap().show() # %% bbands = vbt.talib("BBANDS").run( h1_data.get("Close"), skipna=True, timeframe=["1h", "4h", "1d", "7d"], broadcast_kwargs=dict(wrapper_kwargs=dict(freq="1h")) ) bandwidth = (bbands.upperband - bbands.lowerband) / bbands.middleband bandwidths # %% [markdown] # ## Testing # %% def generate_signals(data, freq, fast_window, slow_window): open_price = data.resample(freq).get("Open") fast_sma = vbt.talib("SMA")\ .run( open_price, fast_window, skipna=True, short_name="fast_sma" )\ .real.ffill()\ .vbt.realign(data.wrapper.index) slow_sma = vbt.talib("SMA")\ .run( open_price, slow_window, skipna=True, short_name="slow_sma" )\ .real.ffill()\ .vbt.realign(data.wrapper.index) entries = fast_sma.vbt.crossed_above(slow_sma) exits = fast_sma.vbt.crossed_below(slow_sma) return entries, exits fast_window = [10, 20] slow_window = [20, 30] h1_entries, h1_exits = generate_signals(h1_data, "1h", fast_window, slow_window) h4_entries, h4_exits = generate_signals(h1_data, "4h", fast_window, slow_window) d1_entries, d1_exits = generate_signals(h1_data, "1d", fast_window, slow_window) entries = pd.concat( (h1_entries, h4_entries, d1_entries), axis=1, keys=pd.Index(["1h", "4h", "1d"], name="timeframe") ) exits = pd.concat( (h1_exits, h4_exits, d1_exits), axis=1, keys=pd.Index(["1h", "4h", "1d"], name="timeframe") ) (entries.astype(int) - exits.astype(int))\ .resample("1d").sum()\ .vbt.ts_heatmap( trace_kwargs=dict( colorscale=["#ef553b", "rgba(0, 0, 0, 0)", "#17becf"], colorbar=dict( tickvals=[-1, 0, 1], ticktext=["Exit", "", "Entry"] ) ) ).show() # %% pf = vbt.Portfolio.from_signals( h1_data, entries, exits, sl_stop=0.1, freq="1h" ) pf.orders.count() # %% pf.sharpe_ratio # %%