Ejemplo n.º 1
0
    def generate_both(cls, shape, entry_choice_func_nb, exit_choice_func_nb,
                      entry_args, exit_args, **kwargs):
        """See `vectorbt.signals.nb.generate_enex_nb`.

        `**kwargs` will be passed to pandas constructor.

        Example:
            Generate entry and exit signals one after another:
            ```python-repl
            >>> @njit
            ... def entry_choice_func_nb(col, from_i, to_i, wait1):
            ...     next_pos = col + from_i + wait1
            ...     if next_pos < to_i:
            ...          return np.array([next_pos])
            ...     return np.empty(0, dtype=np.int_)
            >>> @njit
            ... def exit_choice_func_nb(col, from_i, to_i, wait2):
            ...     next_pos = col + from_i + wait2
            ...     if next_pos < to_i:
            ...          return np.array([next_pos])
            ...     return np.empty(0, dtype=np.int_)

            >>> en, ex = pd.DataFrame.vbt.signals.generate_both(
            ...     (5, 3), entry_choice_func_nb, exit_choice_func_nb, (0,), (1,),
            ...     index=sig.index, columns=sig.columns)
            >>> en
                            a      b      c
            2020-01-01   True  False  False
            2020-01-02  False   True  False
            2020-01-03  False  False   True
            2020-01-04   True  False  False
            2020-01-05  False  False  False
            >>> ex
                            a      b      c
            2020-01-01  False  False  False
            2020-01-02  False  False  False
            2020-01-03   True  False  False
            2020-01-04  False  False  False
            2020-01-05  False   True  False
            ```"""
        checks.assert_numba_func(entry_choice_func_nb)
        checks.assert_numba_func(exit_choice_func_nb)

        if not isinstance(shape, tuple):
            shape = (shape, 1)
        elif isinstance(shape, tuple) and len(shape) == 1:
            shape = (shape[0], 1)

        result1, result2 = nb.generate_enex_nb(
            shape,
            entry_choice_func_nb,
            exit_choice_func_nb,
            entry_args,
            exit_args
        )
        if cls.is_series():
            if shape[1] > 1:
                raise ValueError("Use DataFrame accessor")
            return pd.Series(result1[:, 0], **kwargs), pd.Series(result2[:, 0], **kwargs)
        return pd.DataFrame(result1, **kwargs), pd.DataFrame(result2, **kwargs)
Ejemplo n.º 2
0
 def apply_nb(i, shape, entry_wait, exit_wait, entry_input_list,
              exit_input_list, entry_in_output_tuples,
              exit_in_output_tuples, entry_param_tuples,
              exit_param_tuples, entry_args, exit_args):
     return generate_enex_nb(
         shape, entry_wait, exit_wait, entry_choice_func,
         (*entry_input_list, *entry_in_output_tuples[i],
          *entry_param_tuples[i], *entry_args), exit_choice_func,
         (*exit_input_list, *exit_in_output_tuples[i],
          *exit_param_tuples[i], *exit_args))
Ejemplo n.º 3
0
    def generate_both(cls, shape, entry_choice_func_nb, exit_choice_func_nb,
                      entry_args=None, exit_args=None, entry_wait=1, exit_wait=1, **kwargs):
        """See `vectorbt.signals.nb.generate_enex_nb`.

        `**kwargs` will be passed to pandas constructor.

        ## Example

        Generate entry and exit signals one after another. Each column increment
        the number of ticks to wait before placing the exit signal.
        ```python-repl
        >>> @njit
        ... def entry_choice_func_nb(from_i, to_i, col, temp_idx_arr):
        ...     temp_idx_arr[0] = from_i
        ...     return temp_idx_arr[:1]  # array with one signal

        >>> @njit
        ... def exit_choice_func_nb(from_i, to_i, col, temp_idx_arr):
        ...     wait = col
        ...     temp_idx_arr[0] = from_i + wait
        ...     if temp_idx_arr[0] < to_i:
        ...         return temp_idx_arr[:1]  # array with one signal
        ...     return temp_idx_arr[:0]  # empty array

        >>> temp_idx_arr = np.empty((1,), dtype=np.int_)  # reuse memory
        >>> en, ex = pd.DataFrame.vbt.signals.generate_both(
        ...     (5, 3), entry_choice_func_nb, exit_choice_func_nb,
        ...     entry_args=(temp_idx_arr,), exit_args=(temp_idx_arr,),
        ...     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  False  False
        2020-01-04  False   True  False
        2020-01-05   True  False   True
        >>> ex
                        a      b      c
        2020-01-01  False  False  False
        2020-01-02   True  False  False
        2020-01-03  False   True  False
        2020-01-04   True  False   True
        2020-01-05  False  False  False
        ```
        """
        checks.assert_numba_func(entry_choice_func_nb)
        checks.assert_numba_func(exit_choice_func_nb)
        if entry_args is None:
            entry_args = ()
        if exit_args is None:
            exit_args = ()

        if not isinstance(shape, tuple):
            shape = (shape, 1)
        elif isinstance(shape, tuple) and len(shape) == 1:
            shape = (shape[0], 1)

        result1, result2 = nb.generate_enex_nb(
            shape,
            entry_wait, exit_wait,
            entry_choice_func_nb, entry_args,
            exit_choice_func_nb, exit_args
        )
        if cls.is_series():
            if shape[1] > 1:
                raise ValueError("Use DataFrame accessor")
            return pd.Series(result1[:, 0], **kwargs), pd.Series(result2[:, 0], **kwargs)
        return pd.DataFrame(result1, **kwargs), pd.DataFrame(result2, **kwargs)