67 KiB
67 KiB
Patterns and projections¶
Patterns¶
In [ ]:
from vectorbtpro import * # whats_imported() vbt.settings.set_theme("dark")
In [ ]:
data = vbt.BinanceData.pull( "BTCUSDT", start="2020-06-01 UTC", end="2022-06-01 UTC" ) data.plot().show_svg()
In [ ]:
data_window = data.loc["2021-09-25":"2021-11-25"] data_window.plot(plot_volume=False).show_svg()
In [ ]:
price_window = data_window.hlc3 price_window.vbt.plot().show_svg()
In [ ]:
pattern = np.array([1, 2, 3, 2, 3, 2]) pd.Series(pattern).vbt.plot().show_svg()
Interpolation¶
Linear¶
In [ ]:
resized_pattern = vbt.nb.interp_resize_1d_nb( pattern, 10, vbt.enums.InterpMode.Linear ) resized_pattern
In [ ]:
def plot_linear(n): resized_pattern = vbt.nb.interp_resize_1d_nb( pattern, n, vbt.enums.InterpMode.Linear ) return pd.Series(resized_pattern).vbt.plot()
In [ ]:
plot_linear(7).show_svg()
In [ ]:
resized_pattern = vbt.nb.interp_resize_1d_nb( pattern, 7, vbt.enums.InterpMode.Linear ) ratio = (len(pattern) - 1) / (len(resized_pattern) - 1) new_points = np.arange(len(resized_pattern)) * ratio fig = pd.Series(pattern).vbt.plot() pd.Series(resized_pattern, index=new_points).vbt.scatterplot(fig=fig).show_svg()
Nearest¶
In [ ]:
resized_pattern = vbt.nb.interp_resize_1d_nb( pattern, 10, vbt.enums.InterpMode.Nearest ) resized_pattern
In [ ]:
def plot_nearest(n): resized_pattern = vbt.nb.interp_resize_1d_nb( pattern, n, vbt.enums.InterpMode.Nearest ) return pd.Series(resized_pattern).vbt.plot()
In [ ]:
plot_nearest(7).show_svg()
Discrete¶
In [ ]:
resized_pattern = vbt.nb.interp_resize_1d_nb( pattern, 10, vbt.enums.InterpMode.Discrete ) resized_pattern
In [ ]:
def plot_discrete(n): resized_pattern = vbt.nb.interp_resize_1d_nb( pattern, n, vbt.enums.InterpMode.Discrete ) return pd.Series(resized_pattern).vbt.plot( trace_kwargs=dict( line=dict(dash="dot"), connectgaps=True ) )
In [ ]:
plot_discrete(7).show_svg()
Mixed¶
In [ ]:
resized_pattern = vbt.nb.interp_resize_1d_nb( pattern, 10, vbt.enums.InterpMode.Mixed ) resized_pattern
In [ ]:
def plot_mixed(n): lin_resized_pattern = vbt.nb.interp_resize_1d_nb( pattern, n, vbt.enums.InterpMode.Linear ) mix_resized_pattern = vbt.nb.interp_resize_1d_nb( pattern, n, vbt.enums.InterpMode.Mixed ) fig = pd.Series(lin_resized_pattern, name="Linear").vbt.plot() return pd.Series(mix_resized_pattern, name="Mixed").vbt.plot(fig=fig)
In [ ]:
plot_mixed(7).show_svg()
In [ ]:
resized_pattern = vbt.nb.interp_resize_1d_nb( pattern, len(price_window), vbt.enums.InterpMode.Mixed ) resized_pattern.shape
Rescaling¶
In [ ]:
pattern_scale = (resized_pattern.min(), resized_pattern.max()) price_window_scale = (price_window.min(), price_window.max()) rescaled_pattern = vbt.utils.array_.rescale_nb( resized_pattern, pattern_scale, price_window_scale ) rescaled_pattern = pd.Series(rescaled_pattern, index=price_window.index)
In [ ]:
fig = price_window.vbt.plot() rescaled_pattern.vbt.plot( trace_kwargs=dict( fill="tonexty", fillcolor="rgba(255, 100, 0, 0.25)" ), fig=fig ).show_svg()
Rebasing¶
In [ ]:
pct_pattern = np.array([1, 1.3, 1.6, 1.3, 1.6, 1.3]) resized_pct_pattern = vbt.nb.interp_resize_1d_nb( pct_pattern, len(price_window), vbt.enums.InterpMode.Mixed ) rebased_pattern = resized_pct_pattern / resized_pct_pattern[0] rebased_pattern *= price_window.values[0] rebased_pattern = pd.Series(rebased_pattern, index=price_window.index) fig = price_window.vbt.plot() rebased_pattern.vbt.plot( trace_kwargs=dict( fill="tonexty", fillcolor="rgba(255, 100, 0, 0.25)" ), fig=fig ).show_svg()
Similarity¶
In [ ]:
abs_distances = np.abs(rescaled_pattern - price_window.values) mae = abs_distances.sum() max_abs_distances = np.column_stack(( (price_window.max() - rescaled_pattern), (rescaled_pattern - price_window.min()) )).max(axis=1) max_mae = max_abs_distances.sum() similarity = 1 - mae / max_mae similarity
In [ ]:
quad_distances = (rescaled_pattern - price_window.values) ** 2 rmse = np.sqrt(quad_distances.sum()) max_quad_distances = np.column_stack(( (price_window.max() - rescaled_pattern), (rescaled_pattern - price_window.min()) )).max(axis=1) ** 2 max_rmse = np.sqrt(max_quad_distances.sum()) similarity = 1 - rmse / max_rmse similarity
In [ ]:
quad_distances = (rescaled_pattern - price_window.values) ** 2 mse = quad_distances.sum() max_quad_distances = np.column_stack(( (price_window.max() - rescaled_pattern), (rescaled_pattern - price_window.min()) )).max(axis=1) ** 2 max_mse = max_quad_distances.sum() similarity = 1 - mse / max_mse similarity
In [ ]:
vbt.nb.pattern_similarity_nb(price_window.values, pattern)
In [ ]:
vbt.nb.pattern_similarity_nb( price_window.values, pct_pattern, rescale_mode=vbt.enums.RescaleMode.Rebase )
In [ ]:
vbt.nb.pattern_similarity_nb( price_window.values, pct_pattern, interp_mode=vbt.enums.InterpMode.Nearest, rescale_mode=vbt.enums.RescaleMode.Rebase, distance_measure=vbt.enums.DistanceMeasure.RMSE )
In [ ]:
price_window.vbt.plot_pattern( pct_pattern, interp_mode="nearest", rescale_mode="rebase", fill_distance=True ).show_svg()
In [ ]:
adj_pct_pattern = np.array([1, 1.3, 1.6, 1.45, 1.6, 1.3]) vbt.nb.pattern_similarity_nb( price_window.values, adj_pct_pattern, interp_mode=vbt.enums.InterpMode.Nearest, rescale_mode=vbt.enums.RescaleMode.Rebase, distance_measure=vbt.enums.DistanceMeasure.RMSE )
In [ ]:
price_window.vbt.plot_pattern( adj_pct_pattern, interp_mode="discrete", rescale_mode="rebase", ).show_svg()
In [ ]:
vbt.nb.pattern_similarity_nb( price_window.values, adj_pct_pattern, interp_mode=vbt.enums.InterpMode.Discrete, rescale_mode=vbt.enums.RescaleMode.Rebase, distance_measure=vbt.enums.DistanceMeasure.RMSE )
Relative¶
In [ ]:
abs_pct_distances = abs_distances / rescaled_pattern pct_mae = abs_pct_distances.sum() max_abs_pct_distances = max_abs_distances / rescaled_pattern max_pct_mae = max_abs_pct_distances.sum() similarity = 1 - pct_mae / max_pct_mae similarity
In [ ]:
vbt.nb.pattern_similarity_nb( price_window.values, pct_pattern, error_type=vbt.enums.ErrorType.Relative )
In [ ]:
vbt.nb.pattern_similarity_nb( np.array([10, 30, 100]), np.array([1, 2, 3]), error_type=vbt.enums.ErrorType.Absolute )
In [ ]:
vbt.nb.pattern_similarity_nb( np.array([10, 30, 100]), np.array([1, 2, 3]), error_type=vbt.enums.ErrorType.Relative )
Inverse¶
In [ ]:
vbt.nb.pattern_similarity_nb(price_window.values, pattern, invert=True)
In [ ]:
price_window.vbt.plot_pattern(pattern, invert=True).show_svg()
In [ ]:
pattern.max() + pattern.min() - pattern
Max error¶
In [ ]:
vbt.nb.pattern_similarity_nb( price_window.values, pattern, )
In [ ]:
vbt.nb.pattern_similarity_nb( price_window.values, pattern, max_error=np.array([0.5, 0.5, 0.5, 0.5, 0.5, 0.5]), )
In [ ]:
vbt.nb.pattern_similarity_nb( price_window.values, pattern, max_error=np.array([0.5]), )
In [ ]:
price_window.vbt.plot_pattern( pattern, max_error=0.5 ).show_svg()
In [ ]:
vbt.nb.pattern_similarity_nb( price_window.values, pattern, max_error=np.array([0.5]), max_error_strict=True )
In [ ]:
vbt.nb.pattern_similarity_nb( price_window.values, adj_pct_pattern, rescale_mode=vbt.enums.RescaleMode.Rebase, max_error=np.array([0.2, 0.1, 0.05, 0.1, 0.05, 0.1]), max_error_strict=True )
In [ ]:
vbt.nb.pattern_similarity_nb( price_window.values, pattern, max_error=np.array([0.1]), error_type=vbt.enums.ErrorType.Relative )
In [ ]:
price_window.vbt.plot_pattern( pattern, max_error=0.1, error_type="relative" ).show_svg()
In [ ]:
price_window.vbt.plot_pattern( adj_pct_pattern, rescale_mode="rebase", max_error=np.array([0.2, 0.1, 0.05, 0.1, 0.05, 0.1]) ).show_svg()
In [ ]:
vbt.nb.pattern_similarity_nb( price_window.values, adj_pct_pattern, rescale_mode=vbt.enums.RescaleMode.Rebase, max_error=np.array([0.2, 0.1, 0.05, 0.1, 0.05, 0.1]) + 0.05, max_error_strict=True )
Interpolation¶
In [ ]:
vbt.nb.pattern_similarity_nb( price_window.values, adj_pct_pattern, rescale_mode=vbt.enums.RescaleMode.Rebase, max_error=np.array([np.nan, np.nan, 0.1, np.nan, 0.1, np.nan]), max_error_interp_mode=vbt.enums.InterpMode.Discrete, max_error_strict=True )
In [ ]:
price_window.vbt.plot_pattern( adj_pct_pattern, rescale_mode="rebase", max_error=np.array([np.nan, np.nan, 0.1, np.nan, 0.1, np.nan]), max_error_interp_mode="discrete" ).show_svg()
Max distance¶
In [ ]:
vbt.nb.pattern_similarity_nb(price_window.values, pattern)
In [ ]:
vbt.nb.pattern_similarity_nb( price_window.values, pattern, max_error=np.array([0.5]), max_error_as_maxdist=True )
Further filters¶
In [ ]:
vbt.nb.pattern_similarity_nb(price_window.values, pattern, max_pct_change=0.3)
In [ ]:
vbt.nb.pattern_similarity_nb(price_window.values, pattern, min_similarity=0.9)
Rolling similarity¶
In [ ]:
price = data.hlc3 similarity = price.vbt.rolling_pattern_similarity( pattern, window=30, error_type="relative", max_error=0.05, max_error_interp_mode="discrete" ) similarity.describe()
In [ ]:
end_row = similarity.argmax() + 1 start_row = end_row - 30 fig = data.iloc[start_row:end_row].plot(plot_volume=False) price.iloc[start_row:end_row].vbt.plot_pattern( pattern, error_type="relative", max_error=0.05, max_error_interp_mode="discrete", plot_obj=False, fig=fig ).show_svg()
In [ ]:
end_row = similarity.argmin() + 1 start_row = end_row - 30 fig = data.iloc[start_row:end_row].plot(plot_volume=False) price.iloc[start_row:end_row].vbt.plot_pattern( pattern, invert=True, error_type="relative", max_error=0.05, max_error_interp_mode="discrete", plot_obj=False, fig=fig ).show_svg()
In [ ]:
inv_similarity = price.vbt.rolling_pattern_similarity( pattern, window=30, invert=True, error_type="relative", max_error=0.05, max_error_interp_mode="discrete" ) inv_similarity.describe()
In [ ]:
end_row = inv_similarity.argmax() + 1 start_row = end_row - 30 fig = data.iloc[start_row:end_row].plot(plot_volume=False) price.iloc[start_row:end_row].vbt.plot_pattern( pattern, invert=True, error_type="relative", max_error=0.05, max_error_interp_mode="discrete", plot_obj=False, fig=fig ).show_svg()
Indicator¶
In [ ]:
patsim = vbt.PATSIM.run( price, vbt.Default(pattern), error_type=vbt.Default("relative"), max_error=vbt.Default(0.05), max_error_interp_mode=vbt.Default("discrete"), window=[30, 45, 60, 75, 90] )
In [ ]:
patsim.wrapper.columns
In [ ]:
patsim.plot(column=60).show_svg()
In [ ]:
patsim.overlay_with_heatmap(column=60).show_svg()
In [ ]:
exits = patsim.similarity >= 0.8 exits.sum()
In [ ]:
patsim = vbt.PATSIM.run( price, vbt.Default(pattern), error_type=vbt.Default("relative"), max_error=vbt.Default(0.05), max_error_interp_mode=vbt.Default("discrete"), window=[30, 45, 60, 75, 90], invert=[False, True], min_similarity=[0.7, 0.8], param_product=True ) exits = ~patsim.similarity.isnull() exits.sum()
In [ ]:
groupby = [ name for name in patsim.wrapper.columns.names if name != "patsim_window" ] max_sim = patsim.similarity.groupby(groupby, axis=1).max() entries = ~max_sim.xs(True, level="patsim_invert", axis=1).isnull() exits = ~max_sim.xs(False, level="patsim_invert", axis=1).isnull()
In [ ]:
fig = data.plot(ohlc_trace_kwargs=dict(opacity=0.5)) entries[0.8].vbt.signals.plot_as_entries(price, fig=fig) exits[0.8].vbt.signals.plot_as_exits(price, fig=fig).show_svg()
Search¶
In [ ]:
pattern_range_records = vbt.nb.find_pattern_1d_nb( price.values, pattern, window=30, max_window=90, error_type=vbt.enums.ErrorType.Relative, max_error=np.array([0.05]), max_error_interp_mode=vbt.enums.InterpMode.Discrete, min_similarity=0.85 ) pattern_range_records
In [ ]:
start_row = pattern_range_records[1]["start_idx"] end_row = pattern_range_records[1]["end_idx"] fig = data.iloc[start_row:end_row + 30].plot(plot_volume=False) price.iloc[start_row:end_row].vbt.plot_pattern( pattern, error_type="relative", max_error=0.05, max_error_interp_mode="discrete", plot_obj=False, fig=fig ).show_svg()
In [ ]:
pattern_ranges = vbt.PatternRanges.from_pattern_search( price, pattern, window=30, max_window=120, error_type="relative", max_error=0.05, max_error_interp_mode="discrete", min_similarity=0.85 ) pattern_ranges
In [ ]:
pattern_ranges = price.vbt.find_pattern( pattern, window=30, max_window=90, error_type="relative", max_error=0.05, max_error_interp_mode="discrete", min_similarity=0.85 )
In [ ]:
print(pattern_ranges.records_readable)
In [ ]:
pattern_ranges.wrapper.columns
In [ ]:
pattern_ranges.search_configs
In [ ]:
pattern_ranges.plot().show_svg()
In [ ]:
pattern_ranges.loc["2021-09-01":"2022-01-01"].plot().show_svg()
In [ ]:
pattern_ranges.stats()
Overlapping¶
In [ ]:
pattern_ranges = price.vbt.find_pattern( pattern, window=30, max_window=120, error_type="relative", max_error=0.05, max_error_interp_mode="discrete", min_similarity=0.85, overlap_mode="allow" )
In [ ]:
pattern_ranges.count()
In [ ]:
pattern_ranges.overlap_coverage
In [ ]:
pattern_ranges.plot(plot_zones=False, plot_patterns=False).show_svg()
Random selection¶
In [ ]:
def run_prob_search(row_select_prob, window_select_prob): return price.vbt.find_pattern( pattern, window=30, max_window=120, row_select_prob=row_select_prob, window_select_prob=window_select_prob, error_type="relative", max_error=0.05, max_error_interp_mode="discrete", min_similarity=0.8, )
In [ ]:
%timeit run_prob_search(1.0, 1.0)
In [ ]:
%timeit run_prob_search(0.5, 0.25)
In [ ]:
run_prob_search(1.0, 1.0).count()
In [ ]:
pd.Series([ run_prob_search(0.5, 0.25).count() for i in range(100) ]).vbt.plot().show_svg()
Params¶
In [ ]:
pattern_ranges = price.vbt.find_pattern( vbt.Param([ [1, 2, 1], [2, 1, 2], [1, 2, 3], [3, 2, 1] ]), window=30, max_window=120, )
In [ ]:
pattern_ranges.count()
In [ ]:
pattern_ranges = price.vbt.find_pattern( vbt.Param([ [1, 2, 1], [2, 1, 2], [1, 2, 3], [3, 2, 1] ], keys=["v-top", "v-bottom", "rising", "falling"]), window=30, max_window=120, ) pattern_ranges.count()
In [ ]:
pattern_ranges.plot(column="falling").show_svg()
In [ ]:
pattern_ranges = price.vbt.find_pattern( vbt.Param([ [1, 2, 1], [2, 1, 2], [1, 2, 3], [3, 2, 1] ], keys=["v-top", "v-bottom", "rising", "falling"]), window=30, max_window=120, min_similarity=vbt.Param([0.8, 0.85]) ) pattern_ranges.count()
In [ ]:
pattern_ranges.plot(column=("v-bottom", 0.8)).show_svg()
In [ ]:
pattern_ranges = price.vbt.find_pattern( vbt.Param([ [1, 2, 1], [2, 1, 2], [1, 2, 3], [3, 2, 1] ], keys=["v-top", "v-bottom", "rising", "falling"], level=0), window=vbt.Param([30, 30, 7, 7], level=0), max_window=vbt.Param([120, 120, 30, 30], level=0), min_similarity=vbt.Param([0.8, 0.85], level=1) ) pattern_ranges.count()
Configs¶
In [ ]:
mult_data = vbt.BinanceData.pull( ["BTCUSDT", "ETHUSDT"], start="2020-06-01 UTC", end="2022-06-01 UTC" ) mult_price = mult_data.hlc3
In [ ]:
pattern_ranges = mult_price.vbt.find_pattern( search_configs=[ vbt.PSC(pattern=[1, 2, 3, 2, 3, 2], window=30), [ vbt.PSC(pattern=mult_price.iloc[-30:, 0]), vbt.PSC(pattern=mult_price.iloc[-30:, 1]), ] ], min_similarity=0.8 ) pattern_ranges.count()
In [ ]:
pattern_ranges = mult_price.vbt.find_pattern( search_configs=[ vbt.PSC(pattern=[1, 2, 3, 2, 3, 2], window=30, name="double_top"), [ vbt.PSC(pattern=mult_price.iloc[-30:, 0], name="last"), vbt.PSC(pattern=mult_price.iloc[-30:, 1], name="last"), ] ], min_similarity=0.8 ) pattern_ranges.count()
In [ ]:
pattern_ranges = mult_price.vbt.find_pattern( search_configs=[ vbt.PSC(pattern=[1, 2, 3, 2, 3, 2], window=30, name="double_top"), [ vbt.PSC(pattern=mult_price.iloc[-30:, 0], name="last"), vbt.PSC(pattern=mult_price.iloc[-30:, 1], name="last"), ] ], rescale_mode=vbt.Param(["minmax", "rebase"]), min_similarity=0.8, open=mult_data.open, high=mult_data.high, low=mult_data.low, close=mult_data.close, ) pattern_ranges.count()
In [ ]:
pattern_ranges.plot(column=("rebase", "last", "ETHUSDT")).show_svg()
Mask¶
In [ ]:
mask = pattern_ranges.last_pd_mask mask.sum()
Indicator¶
In [ ]:
pattern_ranges = price.vbt.find_pattern( pattern, window=30, max_window=120, row_select_prob=0.5, window_select_prob=0.5, overlap_mode="allow", seed=42 ) pr_mask = pattern_ranges.map_field( "similarity", idx_arr=pattern_ranges.last_idx.values ).to_pd() pr_mask[~pr_mask.isnull()]
In [ ]:
patsim = vbt.PATSIM.run( price, vbt.Default(pattern), window=vbt.Default(30), max_window=vbt.Default(120), row_select_prob=vbt.Default(0.5), window_select_prob=vbt.Default(0.5), min_similarity=vbt.Default(0.85), seed=42 ) ind_mask = patsim.similarity ind_mask[~ind_mask.isnull()]
Combination¶
In [ ]:
price_highs = vbt.PATSIM.run( data.high, pattern=np.array([1, 3, 2, 4]), window=40, max_window=50 ) macd = data.run("talib_macd").macd macd_lows = vbt.PATSIM.run( macd, pattern=np.array([4, 2, 3, 1]), window=40, max_window=50 ) fig = vbt.make_subplots( rows=3, cols=1, shared_xaxes=True, vertical_spacing=0.02 ) fig.update_layout(height=500) data.high.rename("Price").vbt.plot( add_trace_kwargs=dict(row=1, col=1), fig=fig ) macd.rename("MACD").vbt.plot( add_trace_kwargs=dict(row=2, col=1), fig=fig ) price_highs.similarity.rename("Price Sim").vbt.plot( add_trace_kwargs=dict(row=3, col=1), fig=fig ) macd_lows.similarity.rename("MACD Sim").vbt.plot( add_trace_kwargs=dict(row=3, col=1), fig=fig ) fig.show_svg()
In [ ]:
cond1 = (price_highs.similarity >= 0.8).vbt.rolling_any(10) cond2 = (macd_lows.similarity >= 0.8).vbt.rolling_any(10) exits = cond1 & cond2 fig = data.plot(ohlc_trace_kwargs=dict(opacity=0.5)) exits.vbt.signals.plot_as_exits(data.close, fig=fig).show_svg()
Projections¶
In [ ]:
pattern_ranges = price.vbt.find_pattern( [1, 1.2], window=7, rescale_mode="rebase", max_error=0.01, max_error_interp_mode="discrete", max_error_strict=True ) pattern_ranges.count()
Pattern projections¶
In [ ]:
range_idxs, raw_projections = vbt.nb.map_ranges_to_projections_nb( vbt.to_2d_array(price), pattern_ranges.get_field_arr("col"), pattern_ranges.get_field_arr("start_idx"), pattern_ranges.get_field_arr("end_idx"), pattern_ranges.get_field_arr("status") )
In [ ]:
range_idxs
In [ ]:
raw_projections
In [ ]:
projections = pattern_ranges.get_projections() print(projections)
In [ ]:
pattern_ranges.duration.values
In [ ]:
projections = pattern_ranges.get_projections(incl_end_idx=False) print(projections)
In [ ]:
projections.iloc[-1] / projections.iloc[0] - 1
In [ ]:
projections.vbt.plot().show_svg()
Delta projections¶
In [ ]:
delta_ranges = pattern_ranges.with_delta(4)
In [ ]:
fig = pattern_ranges.loc["2021-01":"2021-03"].plot() delta_ranges.loc["2021-01":"2021-03"].plot( plot_ohlc=False, plot_close=False, plot_markers=False, closed_shape_kwargs=dict(fillcolor="DeepSkyBlue"), fig=fig ).show_svg()
In [ ]:
projections = delta_ranges.get_projections() print(projections)
In [ ]:
np.mean(projections.iloc[-1] / projections.iloc[0] - 1)
In [ ]:
pattern_ranges = mult_price.vbt.find_pattern( [1, 1.2], window=7, max_window=30, rescale_mode="rebase", max_error=0.01, max_error_interp_mode="discrete", max_error_strict=True, overlap_mode="allow" ) pattern_ranges.count()
In [ ]:
delta_ranges = pattern_ranges.with_delta(4)
In [ ]:
projections = delta_ranges.get_projections()
In [ ]:
(projections.iloc[-1] / projections.iloc[0] - 1).describe()
In [ ]:
projections = delta_ranges.get_projections(id_level="end_idx")
In [ ]:
print(projections.columns)
In [ ]:
btc_projections = projections.xs("BTCUSDT", level="symbol", axis=1) total_proj_return = btc_projections.iloc[-1] / btc_projections.iloc[0] - 1 total_proj_return.vbt.scatterplot( trace_kwargs=dict( marker=dict( color=total_proj_return.values, colorscale="Temps_r", cmid=0 ) ) ).show_svg()
Plotting¶
In [ ]:
btc_projections.vbt.plot_projections(plot_bands=False).show_svg()
Colorization¶
In [ ]:
btc_projections["2020-08-03"]
In [ ]:
btc_projections["2020-08-03"].median()
In [ ]:
btc_projections.vbt.plot_projections( plot_bands=False, colorize=np.std ).show_svg()
Bands¶
In [ ]:
projections.xs("ETHUSDT", level="symbol", axis=1).median(axis=1)
In [ ]:
print(projections.groupby("symbol", axis=1).median())
In [ ]:
projections.median(axis=1)
In [ ]:
btc_projections.vbt.plot_projections().show_svg()
In [ ]:
btc_projections.iloc[-1].quantile(0.8)
In [ ]:
btc_projections.vbt.plot_projections( plot_lower=False, plot_middle="30%", plot_upper=False, plot_aux_middle=False, ).show_svg()
In [ ]:
btc_projections.iloc[-1].vbt.qqplot().show_svg()
In [ ]:
btc_projections.vbt.plot_projections( plot_lower="P=20%", plot_middle="mean", plot_upper="P=80%", plot_aux_middle=False, ).show_svg()
In [ ]:
def finishes_at_quantile(df, q): nth_element = int(np.ceil(q * (df.shape[1] - 1))) nth_index = np.argsort(df.iloc[-1])[nth_element] return df.iloc[:, nth_index] btc_projections.vbt.plot_projections( plot_lower=partial(finishes_at_quantile, q=0.2), plot_middle=False, plot_upper=partial(finishes_at_quantile, q=0.8), ).show_svg()
Filtering¶
In [ ]:
crossed_mask = projections.expanding().max().iloc[1] >= 1.05 filt_projections = projections.loc[:, crossed_mask] filt_projections.iloc[-1].describe()
In [ ]:
filt_projections.vbt.plot_projections().show_svg()
Latest projections¶
In [ ]:
pattern_ranges = price.vbt.find_pattern( pattern=data.close.iloc[-7:], rescale_mode="rebase", overlap_mode="allow" ) pattern_ranges.count()
In [ ]:
pattern_ranges = pattern_ranges.status_closed pattern_ranges.count()
In [ ]:
projections = pattern_ranges.get_projections() projections.vbt.plot_projections(plot_bands=False).show_svg()
In [ ]:
delta_ranges = pattern_ranges.with_delta(7) projections = delta_ranges.get_projections(start_value=-1) fig = data.iloc[-7:].plot(plot_volume=False) projections.vbt.plot_projections(fig=fig).show_svg()
In [ ]:
projections.mean(axis=1)
In [ ]:
next_data = vbt.BinanceData.pull( "BTCUSDT", start="2022-05-31", end="2022-06-08" ) next_data.close
Quick plotting¶
In [ ]:
delta_ranges.plot_projections().show_svg()
Non-uniform projections¶
In [ ]:
windows = np.arange(10, 31) window_tuples = combinations(windows, 2) window_tuples = filter(lambda x: abs(x[0] - x[1]) >= 5, window_tuples) fast_windows, slow_windows = zip(*window_tuples) fast_sma = data.run("sma", fast_windows, short_name="fast_sma") slow_sma = data.run("sma", slow_windows, short_name="slow_sma") entries = fast_sma.real_crossed_above(slow_sma.real) exits = fast_sma.real_crossed_below(slow_sma.real) entries.shape
In [ ]:
entry_ranges = entries.vbt.signals.delta_ranges(30, close=data.close) entry_ranges = entry_ranges.status_closed entry_ranges.count().sum()
In [ ]:
exit_ranges = exits.vbt.signals.delta_ranges(30, close=data.close) exit_ranges = exit_ranges.status_closed exit_ranges.count().sum()
In [ ]:
entry_projections = entry_ranges.get_projections() entry_projections.shape
In [ ]:
exit_projections = exit_ranges.get_projections() exit_projections.shape
In [ ]:
fig = entry_projections.vbt.plot_projections( plot_projections=False, lower_trace_kwargs=dict(name="Lower (entry)", line_color="green"), middle_trace_kwargs=dict(name="Middle (entry)", line_color="green"), upper_trace_kwargs=dict(name="Upper (entry)", line_color="green"), plot_aux_middle=False, plot_fill=False ) fig = exit_projections.vbt.plot_projections( plot_projections=False, lower_trace_kwargs=dict(name="Lower (exit)", line_color="orangered"), middle_trace_kwargs=dict(name="Middle (exit)", line_color="orangered"), upper_trace_kwargs=dict(name="Upper (exit)", line_color="orangered"), plot_aux_middle=False, plot_fill=False, fig=fig ) fig.show_svg()
In [ ]:
entry_ranges = entries.vbt.signals.between_ranges(exits, close=data.close) entry_ranges = entry_ranges.status_closed entry_ranges.count().sum()
In [ ]:
exit_ranges = exits.vbt.signals.between_ranges(entries, close=data.close) exit_ranges = exit_ranges.status_closed exit_ranges.count().sum()
In [ ]:
entry_projections = entry_ranges.get_projections() entry_projections.shape
In [ ]:
exit_projections = exit_ranges.get_projections() exit_projections.shape
In [ ]:
rand_cols = np.random.choice(entry_projections.shape[1], 100) entry_projections.iloc[:, rand_cols].vbt.plot_projections(plot_bands=False).show_svg()
In [ ]:
rand_cols = np.random.choice(exit_projections.shape[1], 100) exit_projections.iloc[:, rand_cols].vbt.plot_projections(plot_bands=False).show_svg()
Shrinking¶
In [ ]:
entry_projections = entry_ranges.get_projections(proj_period="30d") entry_projections.shape
In [ ]:
exit_projections = exit_ranges.get_projections(proj_period="30d") exit_projections.shape
In [ ]:
rand_cols = np.random.choice(entry_projections.shape[1], 100) entry_projections.iloc[:, rand_cols].vbt.plot_projections().show_svg()
In [ ]:
rand_cols = np.random.choice(exit_projections.shape[1], 100) exit_projections.iloc[:, rand_cols].vbt.plot_projections().show_svg()
Stretching¶
In [ ]:
entry_projections = entry_ranges.get_projections( proj_period="30d", extend=True ) entry_projections.shape
In [ ]:
exit_projections = exit_ranges.get_projections( proj_period="30d", extend=True ) exit_projections.shape
In [ ]:
rand_cols = np.random.choice(entry_projections.shape[1], 100) entry_projections.iloc[:, rand_cols].vbt.plot_projections().show_svg()
In [ ]:
rand_cols = np.random.choice(exit_projections.shape[1], 100) exit_projections.iloc[:, rand_cols].vbt.plot_projections().show_svg()
Quick plotting¶
In [ ]:
entry_ranges.wrapper.columns
In [ ]:
entry_ranges.plot_projections( column=(25, 30), last_n=10, proj_period="30d", extend=True, plot_lower=False, plot_upper=False, plot_aux_middle=False, projection_trace_kwargs=dict(opacity=0.3) ).show_svg()
Open projections¶
In [ ]:
exit_ranges = exits.vbt.signals.between_ranges( entries, incl_open=True, close=data.close ) exit_ranges.count().sum()
In [ ]:
exit_ranges.wrapper.columns[exit_ranges.status_open.col_arr]
In [ ]:
exit_ranges.status_closed.plot_projections( column=(20, 30), plot_bands=False ).show_svg()
In [ ]:
exit_ranges.plot_projections( column=(20, 30), plot_bands=False ).show_svg()
In [ ]:
column = (20, 30) signal_index = data.wrapper.index[np.flatnonzero(exits[column])[-1]] plot_start_index = signal_index - pd.Timedelta(days=10) sub_close = data.close[plot_start_index:] sub_exits = exits.loc[plot_start_index:, column] fig = sub_close.vbt.plot() sub_exits.vbt.signals.plot_as_exits(sub_close, fig=fig) projections = exit_ranges[column].status_closed.get_projections( start_value=sub_close.loc[signal_index], start_index=signal_index ) projections.vbt.plot_projections(plot_bands=False, fig=fig).show_svg()
In [ ]: