# ################################## 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] # # Pre-analysis # ## Ranking # %% @njit def rank_func_nb(c): if c.sig_in_part_cnt == 1: return 1 return 0 sample_mask = pd.Series([True, True, False, True, True]) ranked = sample_mask.vbt.signals.rank(rank_func_nb) ranked # %% ranked == 1 # %% ranked = sample_mask.vbt.signals.rank( rank_func_nb, after_false=True ) ranked == 1 # %% sample_entries = pd.Series([True, True, True, True, True]) sample_exits = pd.Series([False, False, True, False, False]) ranked = sample_entries.vbt.signals.rank( rank_func_nb, reset_by=sample_exits ) ranked == 1 # %% ranked = sample_entries.vbt.signals.rank( rank_func_nb, reset_by=sample_exits, after_reset=True ) ranked == 1 # %% [markdown] # ### Preset rankers # %% sample_mask = pd.Series([True, True, False, True, True]) ranked = sample_mask.vbt.signals.pos_rank() ranked # %% ranked == 1 # %% ranked = sample_mask.vbt.signals.pos_rank(allow_gaps=True) ranked # %% (ranked > -1) & (ranked % 2 == 1) # %% ranked = sample_mask.vbt.signals.partition_pos_rank(allow_gaps=True) ranked # %% ranked == 1 # %% entry_cond1 = data.get("Low") < bb.lowerband entry_cond2 = bandwidth > 0.3 entry_cond3 = data.get("High") > bb.upperband entry_cond4 = bandwidth < 0.15 entries = (entry_cond1 & entry_cond2) | (entry_cond3 & entry_cond4) entries.vbt.signals.from_nth(0).sum() # %% entries.vbt.signals.from_nth(1).sum() # %% entries.vbt.signals.from_nth(2).sum() # %% exit_cond1 = data.get("High") > bb.upperband exit_cond2 = bandwidth > 0.3 exit_cond3 = data.get("Low") < bb.lowerband exit_cond4 = bandwidth < 0.15 exits = (exit_cond1 & exit_cond2) | (exit_cond3 & exit_cond4) # %% exits.vbt.signals.pos_rank_after(entries, reset_wait=0).max() + 1 # %% entries.vbt.signals.pos_rank_after(exits).max() + 1 # %% ranked = exits.vbt.signals.pos_rank_after(entries, reset_wait=0) highest_ranked = ranked == ranked.max() ranked[highest_ranked.any(axis=1)] # %% exits_after = exits.vbt.signals.from_nth_after(0, entries, reset_wait=0) (exits ^ exits_after).sum() # %% [markdown] # ### Mapped ranks # %% mask = bandwidth.vbt > vbt.Param(np.arange(1, 10) / 10, name="bw_th") mapped_ranks = mask.vbt.signals.pos_rank(as_mapped=True) mapped_ranks.max(group_by=vbt.ExceptLevel("symbol")) # %% [markdown] # ## Cleaning # %% new_exits = exits.vbt.signals.first_after(entries, reset_wait=0) new_entries = entries.vbt.signals.first_after(exits) # %% symbol = "ETHUSDT" fig = data.plot( symbol=symbol, ohlc_trace_kwargs=dict(opacity=0.5), plot_volume=False ) entries[symbol].vbt.signals.plot_as_entries( y=data.get("Close", symbol), fig=fig) exits[symbol].vbt.signals.plot_as_exits( y=data.get("Close", symbol), fig=fig) new_entries[symbol].vbt.signals.plot_as_entry_marks( y=data.get("Close", symbol), fig=fig, trace_kwargs=dict(name="New entries")) new_exits[symbol].vbt.signals.plot_as_exit_marks( y=data.get("Close", symbol), fig=fig, trace_kwargs=dict(name="New exits")) fig.show() # %% new_entries, new_exits = entries.vbt.signals.clean(exits) # %% [markdown] # ## Duration # %% ranges = entries.vbt.signals.between_ranges() ranges.records # %% ranges.start_idx.min(wrap_kwargs=dict(to_index=True)) # %% ranges.duration.describe(wrap_kwargs=dict(to_timedelta=True)) # %% ranges = entries.vbt.signals.between_ranges(target=exits) ranges.avg_duration # %% new_ranges = new_entries.vbt.signals.between_ranges(target=new_exits) new_ranges.avg_duration # %% ranges = entries.vbt.signals.between_ranges(target=exits, relation="manyone") ranges.avg_duration # %% new_ranges = new_entries.vbt.signals.between_ranges(target=new_exits, relation="manyone") new_ranges.avg_duration # %% ranges = entries.vbt.signals.partition_ranges() ranges.duration.describe() # %% new_ranges = new_entries.vbt.signals.partition_ranges() new_ranges.duration.describe() # %% ranges = entries.vbt.signals.between_partition_ranges() ranges.duration.describe(wrap_kwargs=dict(to_timedelta=True)) # %% [markdown] # ## Overview # %% entries.vbt.signals.stats(column="BTCUSDT") # %% entries.vbt.signals.stats(column="BTCUSDT", settings=dict(target=exits)) # %%