Esempio n. 1
0
    def generate_random_after(self,
                              n_range,
                              n_prob=None,
                              min_space=None,
                              seed=None):
        """See `vectorbt.signals.nb.generate_random_after_nb`.

        Example:
            Generate exactly one random signal after each signal in `signals`:

            ```python-repl
            >>> print(signals.vbt.signals.generate_random_after(1, seed=42))
                            a      b      c
            2018-01-01  False  False  False
            2018-01-02  False  False  False
            2018-01-03   True   True  False
            2018-01-04  False  False  False
            2018-01-05   True  False   True
            ```"""
        n_range = reshape_fns.to_1d(n_range)
        if n_prob is not None:
            n_prob = reshape_fns.to_1d(n_prob)
            checks.assert_same_shape(n_range, n_prob)
        return self.wrap_array(
            nb.generate_random_after_nb(self.to_2d_array(),
                                        n_range,
                                        n_prob=n_prob,
                                        min_space=min_space,
                                        seed=seed))
Esempio n. 2
0
    def closed_rate(self):
        """How many positions are closed in each column."""
        closed_count = reshape_fns.to_1d(self.closed.count, raw=True)
        count = reshape_fns.to_1d(self.count, raw=True)

        closed_rate = closed_count / count
        return self.wrap_reduced_array(closed_rate)
Esempio n. 3
0
    def win_rate(self):
        """How many positions won in each column."""
        winning_count = reshape_fns.to_1d(self.winning.count, raw=True)
        count = reshape_fns.to_1d(self.count, raw=True)

        win_rate = winning_count / count
        return self.wrap_reduced_array(win_rate)
Esempio n. 4
0
 def total_costs(self):
     """Total costs of each column."""
     total_paid_fees = reshape_fns.to_1d(self.total_paid_fees, raw=True)
     total_paid_slippage = reshape_fns.to_1d(self.total_paid_slippage,
                                             raw=True)
     total_costs = total_paid_fees + total_paid_slippage
     return self.wrap_reduced_array(total_costs)
Esempio n. 5
0
    def loss_rate(self):
        """How many positions lost in each column."""
        losing_count = reshape_fns.to_1d(self.losing.count, raw=True)
        count = reshape_fns.to_1d(self.count, raw=True)

        loss_rate = losing_count / count
        return self.wrap_reduced_array(loss_rate)
Esempio n. 6
0
 def total_costs(self):
     """Total costs."""
     total_fees_paid = reshape_fns.to_1d(self.total_fees_paid, raw=True)
     total_slippage_paid = reshape_fns.to_1d(self.total_slippage_paid,
                                             raw=True)
     total_costs = total_fees_paid + total_slippage_paid
     return self.wrap_reduced_array(total_costs)
Esempio n. 7
0
    def closed_rate(self):
        """Rate of closed positions."""
        closed_count = reshape_fns.to_1d(self.closed.count, raw=True)
        count = reshape_fns.to_1d(self.count, raw=True)

        closed_rate = closed_count / count
        return self.wrapper.wrap_reduced(closed_rate)
Esempio n. 8
0
    def win_rate(self):
        """Rate of profitable events."""
        winning_count = reshape_fns.to_1d(self.winning.count, raw=True)
        count = reshape_fns.to_1d(self.count, raw=True)

        win_rate = winning_count / count
        return self.wrapper.wrap_reduced(win_rate)
Esempio n. 9
0
    def generate_random(cls, shape, n_range, n_prob=None, min_space=None, seed=None, **kwargs):
        """See `vectorbt.signals.nb.generate_random_nb`.

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

        Example:
            For each column, generate either 1 (with 30% probability) or 2 (with 70% probability)
            signals randomly. Leave one position free between signals:

            ```python-repl
            >>> print(pd.DataFrame.vbt.signals.generate_random((5, 3), [1, 2], 
            ...     n_prob=[0.3, 0.7], min_space=1, seed=42, index=index, columns=columns))
                            a      b      c
            2018-01-01   True  False  False
            2018-01-02  False   True  False
            2018-01-03   True  False  False
            2018-01-04  False   True   True
            2018-01-05  False  False  False
            ```"""
        if not isinstance(shape, tuple):
            shape = (shape, 1)
        elif isinstance(shape, tuple) and len(shape) == 1:
            shape = (shape[0], 1)

        n_range = reshape_fns.to_1d(n_range)
        if n_prob is not None:
            n_prob = reshape_fns.to_1d(n_prob)
            checks.assert_same_shape(n_range, n_prob)
        result = nb.generate_random_nb(shape, n_range, n_prob=n_prob, min_space=min_space, seed=seed)

        if cls.is_series():
            return pd.Series(result[:, 0], **kwargs)
        return pd.DataFrame(result, **kwargs)
Esempio n. 10
0
 def calmar_ratio(self):
     """Calmar ratio, or drawdown ratio, of a strategy."""
     return self.wrapper.wrap_reduced(
         nb.calmar_ratio_nb(
             self.returns.vbt.to_2d_array(),
             reshape_fns.to_1d(self.annualized_return, raw=True),
             reshape_fns.to_1d(self.max_drawdown, raw=True),
             self.ann_factor))
Esempio n. 11
0
    def appt(self):
        """Average profitability per trade (APPT)

        For every trade you place, you are likely to win/lose this amount.
        What matters is that your APPT comes up positive."""
        appt = reshape_fns.to_1d(self.win_rate, raw=True) * reshape_fns.to_1d(self.avg_win, raw=True) - \
            reshape_fns.to_1d(self.loss_rate, raw=True) * reshape_fns.to_1d(self.avg_loss, raw=True)
        return self.wrap_metric(appt)
Esempio n. 12
0
    def profit_factor(self):
        """Profit factor."""
        total_win = reshape_fns.to_1d(self.winning.total_pnl, raw=True)
        total_loss = reshape_fns.to_1d(self.losing.total_pnl, raw=True)

        # Otherwise columns with only wins or losses will become NaNs
        has_values = reshape_fns.to_1d(self.count, raw=True) > 0
        total_win[np.isnan(total_win) & has_values] = 0.
        total_loss[np.isnan(total_loss) & has_values] = 0.

        profit_factor = total_win / np.abs(total_loss)
        return self.wrapper.wrap_reduced(profit_factor)
Esempio n. 13
0
    def profit_factor(self):
        """Profit factor of each column."""
        total_win = reshape_fns.to_1d(self.winning.total_pnl, raw=True)
        total_loss = reshape_fns.to_1d(self.losing.total_pnl, raw=True)

        # Otherwise columns with only wins or losses will become NaNs
        has_trades = reshape_fns.to_1d(self.portfolio.has_trades, raw=True)
        total_win[np.isnan(total_win) & has_trades] = 0.
        total_loss[np.isnan(total_loss) & has_trades] = 0.

        profit_factor = total_win / np.abs(total_loss)
        return self.wrap_reduced_array(profit_factor)
Esempio n. 14
0
    def expectancy(self):
        """Average profitability."""
        win_rate = reshape_fns.to_1d(self.win_rate, raw=True)
        avg_win = reshape_fns.to_1d(self.winning.avg_pnl, raw=True)
        avg_loss = reshape_fns.to_1d(self.losing.avg_pnl, raw=True)

        # Otherwise columns with only wins or losses will become NaNs
        has_values = reshape_fns.to_1d(self.count, raw=True) > 0
        avg_win[np.isnan(avg_win) & has_values] = 0.
        avg_loss[np.isnan(avg_loss) & has_values] = 0.

        expectancy = win_rate * avg_win - (1 - win_rate) * np.abs(avg_loss)
        return self.wrapper.wrap_reduced(expectancy)
Esempio n. 15
0
    def expectancy(self):
        """Average profitability per trade (APPT) of each column."""
        win_rate = reshape_fns.to_1d(self.win_rate, raw=True)
        loss_rate = reshape_fns.to_1d(self.loss_rate, raw=True)
        avg_win = reshape_fns.to_1d(self.winning.avg_pnl, raw=True)
        avg_loss = reshape_fns.to_1d(self.losing.avg_pnl, raw=True)

        # Otherwise columns with only wins or losses will become NaNs
        has_trades = reshape_fns.to_1d(self.portfolio.has_trades, raw=True)
        avg_win[np.isnan(avg_win) & has_trades] = 0.
        avg_loss[np.isnan(avg_loss) & has_trades] = 0.

        expectancy = win_rate * avg_win - loss_rate * np.abs(avg_loss)
        return self.wrap_reduced_array(expectancy)
Esempio n. 16
0
    def describe(self, percentiles=[0.25, 0.5, 0.75], **kwargs):
        """See `vectorbt.timeseries.nb.describe_reduce_func_nb`.

        `**kwargs` will be passed to `TimeSeries_Accessor.wrap_reduced`.

        For `percentiles`, see `pandas.DataFrame.describe`.

        Example:
            ```python-repl
            >>> print(df.vbt.timeseries.describe())
                           a         b        c
            count   5.000000  5.000000  5.00000
            mean    3.000000  3.000000  1.80000
            std     1.581139  1.581139  0.83666
            min     1.000000  1.000000  1.00000
            25.00%  2.000000  2.000000  1.00000
            50.00%  3.000000  3.000000  2.00000
            75.00%  4.000000  4.000000  2.00000
            max     5.000000  5.000000  3.00000
            ```"""
        if percentiles is not None:
            percentiles = reshape_fns.to_1d(percentiles)
        else:
            percentiles = np.empty(0)
        index = pd.Index([
            'count', 'mean', 'std', 'min', *map(lambda x: '%.2f%%' %
                                                (x * 100), percentiles), 'max'
        ])
        return self.reduce_to_array(nb.describe_reduce_func_nb,
                                    percentiles,
                                    index=index,
                                    **kwargs)
Esempio n. 17
0
 def sortino_ratio(self):
     """Sortino ratio of a strategy."""
     return self.wrapper.wrap_reduced(
         nb.sortino_ratio_nb(self.returns.vbt.to_2d_array(),
                             reshape_fns.to_1d(self.downside_risk,
                                               raw=True),
                             self.ann_factor,
                             required_return=self.required_return))
Esempio n. 18
0
    def alpha(self):
        """Annualized alpha.

        !!! note
            `factor_returns` must be set."""
        checks.assert_not_none(self.factor_returns)

        return self.wrapper.wrap_reduced(
            nb.alpha_nb(self.returns.vbt.to_2d_array(),
                        self.factor_returns.vbt.to_2d_array(),
                        reshape_fns.to_1d(self.beta, raw=True),
                        self.ann_factor,
                        risk_free=self.risk_free))
Esempio n. 19
0
 def total_return(self):
     """Total return of each column."""
     total_return = reshape_fns.to_1d(self.total_profit,
                                      raw=True) / self.init_capital
     return self.wrap_reduced_array(total_return)
Esempio n. 20
0
 def profit_factor(self):
     profit_factor = reshape_fns.to_1d(
         self.sum_win, raw=True) / reshape_fns.to_1d(self.sum_loss,
                                                     raw=True)
     return self.wrap_metric(profit_factor)
Esempio n. 21
0
 def total_return(self):
     total_return = reshape_fns.to_1d(self.total_profit,
                                      raw=True) / self.investment
     return self.wrap_metric(total_return)
Esempio n. 22
0
 def total_return(self):
     """Total return."""
     total_return = reshape_fns.to_1d(self.total_profit,
                                      raw=True) / self.init_capital
     return self.wrapper.wrap_reduced(total_return)
Esempio n. 23
0
    def plot_against(self,
                     other,
                     name=None,
                     other_name=None,
                     above_trace_kwargs={},
                     below_trace_kwargs={},
                     other_trace_kwargs={},
                     equal_trace_kwargs={},
                     fig=None,
                     **layout_kwargs):
        """Plot Series against `other` as markers.

        Args:
            other (float, int, or array_like): The other time series/value.
            name (str): Name of the time series.
            other_name (str): Name of the other time series/value.
            other_trace_kwargs (dict): Keyword arguments passed to `plotly.graph_objects.Scatter` for `other`.
            above_trace_kwargs (dict): Keyword arguments passed to `plotly.graph_objects.Scatter` for values above `other`.
            below_trace_kwargs (dict): Keyword arguments passed to `plotly.graph_objects.Scatter` for values below `other`.
            equal_trace_kwargs (dict): Keyword arguments passed to `plotly.graph_objects.Scatter` for values equal `other`.
            fig (plotly.graph_objects.Figure): Figure to add traces to.
            **layout_kwargs: Keyword arguments for layout.
        Example:
            Can plot against single values such as benchmarks.
            ```py
            df['a'].vbt.timeseries.plot_against(3)
            ```

            ![](/vectorbt/docs/img/timeseries_plot_against_line.png)

            But also against other time series.

            ```py
            df['a'].vbt.timeseries.plot_against(df['b'])
            ```

            ![](/vectorbt/docs/img/timeseries_plot_against_series.png)"""
        if name is None:
            name = self._obj.name
        if other_name is None:
            other_name = getattr(other, 'name', None)

        # Prepare data
        other = reshape_fns.to_1d(other)
        other = reshape_fns.broadcast_to(other, self._obj)
        above_obj = self._obj[self._obj > other]
        below_obj = self._obj[self._obj < other]
        equal_obj = self._obj[self._obj == other]

        # Set up figure
        if fig is None:
            fig = DefaultFigureWidget()
            fig.update_layout(**layout_kwargs)

        # Plot other
        other_scatter = go.Scatter(x=other.index,
                                   y=other,
                                   line=dict(
                                       color="grey",
                                       width=2,
                                       dash="dot",
                                   ),
                                   name=other_name,
                                   showlegend=other_name is not None)
        other_scatter.update(**other_trace_kwargs)
        fig.add_trace(other_scatter)

        # Plot markets
        above_scatter = go.Scatter(x=above_obj.index,
                                   y=above_obj,
                                   mode='markers',
                                   marker=dict(symbol='circle',
                                               color='green',
                                               size=10),
                                   name=f'{name} (above)',
                                   showlegend=name is not None)
        above_scatter.update(**above_trace_kwargs)
        fig.add_trace(above_scatter)

        below_scatter = go.Scatter(x=below_obj.index,
                                   y=below_obj,
                                   mode='markers',
                                   marker=dict(symbol='circle',
                                               color='red',
                                               size=10),
                                   name=f'{name} (below)',
                                   showlegend=name is not None)
        below_scatter.update(**below_trace_kwargs)
        fig.add_trace(below_scatter)

        equal_scatter = go.Scatter(x=equal_obj.index,
                                   y=equal_obj,
                                   mode='markers',
                                   marker=dict(symbol='circle',
                                               color='grey',
                                               size=10),
                                   name=f'{name} (equal)',
                                   showlegend=name is not None)
        equal_scatter.update(**equal_trace_kwargs)
        fig.add_trace(equal_scatter)

        # If other is a straight line, make y-axis symmetric
        if np.all(other.values == other.values.item(0)):
            maxval = np.nanmax(np.abs(self.to_array()))
            space = 0.1 * 2 * maxval
            y = other.values.item(0)
            fig.update_layout(
                yaxis=dict(range=[y - (maxval + space), y + maxval + space]),
                shapes=[
                    dict(type="line",
                         xref="paper",
                         yref='y',
                         x0=0,
                         x1=1,
                         y0=y,
                         y1=y,
                         line=dict(
                             color="grey",
                             width=2,
                             dash="dot",
                         ))
                ])

        return fig
Esempio n. 24
0
    def to_1d_array(self):
        """Convert to 1-dim NumPy array

        See `vectorbt.utils.reshape_fns.to_1d`."""
        return reshape_fns.to_1d(self._obj, raw=True)
Esempio n. 25
0
 def to_1d_array(self):
     return reshape_fns.to_1d(self._obj, raw=True)