Ejemplo n.º 1
0
def cagr(qf_series: QFSeries, frequency=None):
    """
    Returns the Compound Annual Growth Rate (CAGR) calculated for the given series.

    Parameters
    ----------
    qf_series: QFSeries
        series of returns of an asset
    frequency: Frequency
        Frequency of the timeseries of returns;
        if it is None (by default) it is inferred from the timeseries of returns

    Returns
    -------
    float
        annual compound return for the given series of prices

    """
    prices_tms = qf_series.to_prices(frequency=frequency, initial_price=1.0)

    last_date = prices_tms.index[-1]
    first_date = prices_tms.index[0]
    period_length = last_date - first_date
    period_length_in_years = to_days(period_length) / DAYS_PER_YEAR_AVG

    total_return = prices_tms[-1] / prices_tms[0] - 1
    return annualise_total_return(
        total_return=total_return,
        period_length_in_years=period_length_in_years,
        returns_type=SimpleReturnsSeries)
Ejemplo n.º 2
0
def avg_nr_of_trades_per1y(trades_returns: QFSeries, start_date: datetime,
                           end_date: datetime):
    """
    Calculates average number of trades per year for a given data-frame of trades.
    """
    period_length = end_date - start_date
    period_length_in_years = to_days(period_length) / DAYS_PER_YEAR_AVG
    avg_number_of_trades_1y = len(trades_returns) / period_length_in_years
    return avg_number_of_trades_1y
Ejemplo n.º 3
0
def avg_nr_of_trades_per1y(trades: QFDataFrame, start_date: datetime,
                           end_date: datetime):
    """
    Calculates average number of trades per year for a given data-frame of trades.
    """
    returns = trades[TradeField.Return]
    period_length = end_date - start_date
    period_length_in_years = to_days(period_length) / DAYS_PER_YEAR_AVG
    avg_number_of_trades_1y = returns.count() / period_length_in_years
    return avg_number_of_trades_1y
Ejemplo n.º 4
0
    def _add_statistics_table(self):
        table = Table(column_names=["Measure", "Value"], css_class="table stats-table")

        number_of_trades = self.returns_of_trades.count()
        table.add_row(["Number of trades", number_of_trades])

        period_length = self.end_date - self.start_date
        period_length_in_years = to_days(period_length) / DAYS_PER_YEAR_AVG
        avg_number_of_trades = number_of_trades / period_length_in_years / self.nr_of_assets_traded
        table.add_row(["Avg number of trades per year per asset", avg_number_of_trades])

        positive_trades = self.returns_of_trades[self.returns_of_trades > 0]
        negative_trades = self.returns_of_trades[self.returns_of_trades < 0]

        percentage_of_positive = positive_trades.count() / number_of_trades
        percentage_of_negative = negative_trades.count() / number_of_trades
        table.add_row(["% of positive trades", percentage_of_positive * 100])
        table.add_row(["% of negative trades", percentage_of_negative * 100])

        avg_positive = positive_trades.mean()
        avg_negative = negative_trades.mean()
        table.add_row(["Avg positive trade [%]", avg_positive * 100])
        table.add_row(["Avg negative trade [%]", avg_negative * 100])

        best_return = max(self.returns_of_trades)
        worst_return = min(self.returns_of_trades)
        table.add_row(["Best trade [%]", best_return * 100])
        table.add_row(["Worst trade [%]", worst_return * 100])

        max_dd = max_drawdown(self.returns_of_trades)
        table.add_row(["Max drawdown [%]", max_dd * 100])

        prices_tms = self.returns_of_trades.to_prices()
        total_return = prices_tms.iloc[-1] / prices_tms.iloc[0] - 1
        table.add_row(["Total return [%]", total_return * 100])

        annualised_ret = annualise_total_return(total_return, period_length_in_years, SimpleReturnsSeries)
        table.add_row(["Annualised return [%]", annualised_ret * 100])

        avg_return = self.returns_of_trades.mean()
        table.add_row(["Avg return of trade [%]", avg_return * 100])

        std_of_returns = self.returns_of_trades.std()
        table.add_row(["Std of return of trades [%]", std_of_returns * 100])

        # System Quality Number
        sqn = avg_return / std_of_returns
        table.add_row(["SQN", sqn])
        table.add_row(["SQN for 100 trades", sqn * 10])  # SQN * sqrt(100)
        table.add_row(["SQN * Sqrt(avg number of trades per year)", sqn * sqrt(avg_number_of_trades)])

        self.document.add_element(table)
Ejemplo n.º 5
0
    def _objective_function(self, trades: QFDataFrame):
        """
        Calculates the simple SQN * sqrt(average number of trades per year)
        """

        number_of_instruments_traded = len(self.all_tickers_tested)
        returns = trades[TradeField.Return]

        period_length = self.backtest_summary.end_date - self.backtest_summary.start_date
        period_length_in_years = to_days(period_length) / DAYS_PER_YEAR_AVG
        avg_number_of_trades_1y = returns.count() / period_length_in_years / number_of_instruments_traded

        sqn = returns.mean() / returns.std()
        sqn = sqn * np.sqrt(avg_number_of_trades_1y)
        return sqn
Ejemplo n.º 6
0
 def test_to_days(self):
     expected = 3
     actual = to_days(Timedelta('3 days'))
     self.assertEqual(expected, actual)