def generate_random_both(cls, shape, n=None, entry_prob=None, exit_prob=None, seed=None, entry_wait=1, exit_wait=1, **kwargs): """Generate entry and exit signals randomly and iteratively. If `n` is set, see `vectorbt.signals.nb.generate_rand_enex_nb`. If `entry_prob` and `exit_prob` are set, see `vectorbt.signals.nb.generate_rand_enex_by_prob_nb`. For arguments, see `SignalsAccessor.generate_random`. ## Example For each column, generate two entries and exits randomly: ```python-repl >>> en, ex = pd.DataFrame.vbt.signals.generate_random_both( ... (5, 3), n=2, seed=42, index=sig.index, columns=sig.columns) >>> en a b c 2020-01-01 True True True 2020-01-02 False False False 2020-01-03 True True False 2020-01-04 False False True 2020-01-05 False False False >>> ex a b c 2020-01-01 False False False 2020-01-02 True True True 2020-01-03 False False False 2020-01-04 False True False 2020-01-05 True False True ``` For each column and time step, pick entry with 50% probability and exit right after: ```python-repl >>> en, ex = pd.DataFrame.vbt.signals.generate_random_both( ... (5, 3), entry_prob=0.5, exit_prob=1., ... seed=42, index=sig.index, columns=sig.columns) >>> en a b c 2020-01-01 True True True 2020-01-02 False False False 2020-01-03 False False False 2020-01-04 False False True 2020-01-05 True False False >>> ex a b c 2020-01-01 False False False 2020-01-02 True True False 2020-01-03 False False True 2020-01-04 False True False 2020-01-05 True False True ``` """ flex_2d = True if not isinstance(shape, tuple): flex_2d = False shape = (shape, 1) elif isinstance(shape, tuple) and len(shape) == 1: flex_2d = False shape = (shape[0], 1) if n is not None: n = np.broadcast_to(n, shape[1]) entries, exits = nb.generate_rand_enex_nb(shape, n, entry_wait, exit_wait, seed=seed) elif entry_prob is not None and exit_prob is not None: entry_prob = np.broadcast_to(entry_prob, shape) exit_prob = np.broadcast_to(exit_prob, shape) entries, exits = nb.generate_rand_enex_by_prob_nb( shape, entry_prob, exit_prob, entry_wait, exit_wait, flex_2d, seed=seed) else: raise ValueError("At least n, or entry_prob and exit_prob should be set") if cls.is_series(): if shape[1] > 1: raise ValueError("Use DataFrame accessor") return pd.Series(entries[:, 0], **kwargs), pd.Series(exits[:, 0], **kwargs) return pd.DataFrame(entries, **kwargs), pd.DataFrame(exits, **kwargs)
def generate_random_both(cls, shape, n=None, entry_prob=None, exit_prob=None, seed=None, **kwargs): """Generate entry and exit signals randomly and iteratively. If `n` is set, see `vectorbt.signals.nb.generate_rand_enex_nb`. If `prob` is set, see `vectorbt.signals.nb.generate_rand_enex_by_prob_nb`. `entry_prob` and `exit_prob` must be either a single number or an array that will be broadcast to match `shape`. `**kwargs` will be passed to pandas constructor. Example: For each column, generate two entries and exits randomly: ```python-repl >>> en, ex = pd.DataFrame.vbt.signals.generate_random_both( ... (5, 3), n=2, seed=42, index=sig.index, columns=sig.columns) >>> en a b c 2020-01-01 True True True 2020-01-02 False False False 2020-01-03 True True False 2020-01-04 False False True 2020-01-05 False False False >>> ex a b c 2020-01-01 False False False 2020-01-02 True True True 2020-01-03 False False False 2020-01-04 False True False 2020-01-05 True False True ``` For each column and time step, pick entry with 50% probability and exit right after: ```python-repl >>> en, ex = pd.DataFrame.vbt.signals.generate_random_both( ... (5, 3), entry_prob=0.5, exit_prob=1., ... seed=42, index=sig.index, columns=sig.columns) >>> en a b c 2020-01-01 True True False 2020-01-02 False False True 2020-01-03 False True False 2020-01-04 True False True 2020-01-05 False False False >>> ex a b c 2020-01-01 False False False 2020-01-02 True True False 2020-01-03 False False True 2020-01-04 False True False 2020-01-05 True False True ```""" if not isinstance(shape, tuple): shape = (shape, 1) elif isinstance(shape, tuple) and len(shape) == 1: shape = (shape[0], 1) if n is not None: entries, exits = nb.generate_rand_enex_nb(shape, n, seed=seed) elif entry_prob is not None and exit_prob is not None: entry_prob = np.broadcast_to(entry_prob, shape) exit_prob = np.broadcast_to(exit_prob, shape) entries, exits = nb.generate_rand_enex_by_prob_nb(shape, entry_prob, exit_prob, seed=seed) else: raise ValueError("At least n, or entry_prob and exit_prob must be set") if cls.is_series(): if shape[1] > 1: raise ValueError("Use DataFrame accessor") return pd.Series(entries[:, 0], **kwargs), pd.Series(exits[:, 0], **kwargs) return pd.DataFrame(entries, **kwargs), pd.DataFrame(exits, **kwargs)