Exemple #1
0
 def test_duration_of_drawdowns(self):
     series_of_max_drawdowns, duration_of_drawdowns = list_of_max_drawdowns(
         self.test_dd_prices_tms)
     drawdowns = [0.3, 0.75, 0.25]
     durations = [93, 62, 1]
     assert_lists_equal(durations, duration_of_drawdowns)
     assert_lists_equal(drawdowns, series_of_max_drawdowns)
Exemple #2
0
def create_dd_probability_chart_3d(prices_tms: QFSeries) -> SurfaceChart3D:
    """Create a 3d drawdowns probability chart"""
    def count_dd_above_threshold(drawdown_series: Sequence, threshold: float):
        return sum(1 for dd in drawdown_series if dd > threshold)

    drawdowns, duration_of_drawdowns = list_of_max_drawdowns(prices_tms)
    bear_marker_definitions = np.arange(0.15, 0.55,
                                        0.05)  # rows    -> will  be the Y axis
    all_examined_dds = np.arange(0.01, 0.20,
                                 0.01)  # columns -> will  be the X axis
    percentage_ending_in_bear_market = np.ones(
        (len(bear_marker_definitions), len(all_examined_dds))) * 100

    for i, bear_marker_definition in enumerate(bear_marker_definitions):
        nr_of_bear_markets = count_dd_above_threshold(drawdowns,
                                                      bear_marker_definition)

        for j, examined_dd in enumerate(all_examined_dds):
            if examined_dd <= bear_marker_definition:
                number_of_dds_above = count_dd_above_threshold(
                    drawdowns, examined_dd)
                percentage = nr_of_bear_markets / number_of_dds_above * 100
                percentage_ending_in_bear_market[i, j] = percentage

    chart = SurfaceChart3D(all_examined_dds, bear_marker_definitions,
                           percentage_ending_in_bear_market)
    chart.set_axes_names('examined drawdown', 'bear market definition')
    chart.set_title('Percentage of drawdowns ending in bear market')

    return chart
Exemple #3
0
def avg_drawdown_duration(prices_tms: QFSeries) -> float:
    """
    Finds the average duration of a drawdown for the given timeseries of prices.

    Parameters
    ----------
    prices_tms
        timeseries of prices

    Returns
    -------
    avg_duration
        average duration of a drawdown for the given timeseries of prices expressed in days
    """
    from qf_lib.common.utils.returns.list_of_max_drawdowns import list_of_max_drawdowns
    series_of_max_drawdowns, duration_of_drawdowns = list_of_max_drawdowns(prices_tms)

    if len(duration_of_drawdowns) > 0:
        return mean(duration_of_drawdowns)
    else:
        return 0.0
Exemple #4
0
def create_dd_probability_chart(
        prices_tms: QFSeries,
        bear_market_definition: float = 0.2) -> Tuple[Chart, Chart]:
    """Creates drawdowns probability chart.

    Parameters
    ----------
    prices_tms: QFSeries
        timeseries of prices
    bear_market_definition: float
        definition of bear market threshold

    Returns
    -------
    Tuple[Chart, Chart]
        Returns two charts - one showing the probability of drawdowns going beyond a certain level and one showing the
        marginal increase of probability of drawdowns going beyond the given level.
    """
    def count_dd_above_threshold(drawdown_series: Sequence, threshold: float):
        return sum(1 for dd in drawdown_series if dd > threshold)

    drawdowns, duration_of_drawdowns = list_of_max_drawdowns(prices_tms)

    examined_dds = np.arange(0.01, bear_market_definition, 0.005)
    percentage_ending_in_bear_market = []
    nr_of_bear_markets = count_dd_above_threshold(drawdowns,
                                                  bear_market_definition)

    for examined_dd in examined_dds:
        number_of_dds_above = count_dd_above_threshold(drawdowns, examined_dd)
        percentage = nr_of_bear_markets / number_of_dds_above * 100
        percentage_ending_in_bear_market.append(percentage)

    chart = LineChart()
    chart.add_decorator(
        ScatterDecorator(examined_dds * 100,
                         percentage_ending_in_bear_market,
                         edgecolors='black'))
    chart.add_decorator(
        TitleDecorator("Percentage of drawdowns going beyond {:2.0f}%".format(
            bear_market_definition * 100)))
    axis_dec = AxesLabelDecorator(
        "examined drawdown [%]",
        "chance that drawdown will go beyond {:2.0f}% in [%]".format(
            bear_market_definition * 100))
    chart.add_decorator(axis_dec)
    x_axis_values = examined_dds * 100
    prob_of_dd_chart = LineChart()
    prob_of_dd_chart.add_decorator(
        ScatterDecorator(x_axis_values,
                         percentage_ending_in_bear_market,
                         edgecolors='black'))
    prob_of_dd_chart.add_decorator(
        TitleDecorator("Percentage of drawdowns going beyond {:2.0f}%".format(
            bear_market_definition * 100)))
    axis_dec = AxesLabelDecorator(
        "examined drawdown [%]",
        "chance that drawdown will go beyond {:2.0f}% in [%]".format(
            bear_market_definition * 100))
    prob_of_dd_chart.add_decorator(axis_dec)

    marginal_increase_in_prob_chart = LineChart()
    diff = np.diff([0] + percentage_ending_in_bear_market)
    marginal_increase_in_prob_chart.add_decorator(
        ScatterDecorator(x_axis_values, diff, edgecolors='black'))
    marginal_increase_in_prob_chart.add_decorator(
        TitleDecorator(
            "Marginal increase of probability of drawdowns going beyond {:2.0f}%"
            .format(bear_market_definition * 100)))
    axis_dec = AxesLabelDecorator(
        "examined drawdown [%]",
        "Marginal increase of chance that drawdown will go beyond {:2.0f}% in [%]"
        .format(bear_market_definition * 100))
    marginal_increase_in_prob_chart.add_decorator(axis_dec)

    return prob_of_dd_chart, marginal_increase_in_prob_chart