Beispiel #1
0
def sqn(returns: QFSeries):
    """
    Calculates the SQN = mean return of trade / std(returns of trades). The returns passed to the function may wither
    be defined as percentage PnL of trades or as r_multiply = percentage PnL / risk.
    """
    result = returns.mean() / returns.std()
    return result
Beispiel #2
0
def create_qq_chart(strategy: QFSeries) -> Chart:
    colors = Chart.get_axes_colors()

    strategy = strategy.to_log_returns()
    # Normalize
    strategy = strategy - strategy.mean()
    strategy = strategy / strategy.std()
    # Sort
    strategy_values = sorted(strategy.values)

    # Create benchmark
    benchmark_values = list(range(1, len(strategy_values) + 1))
    n = len(strategy_values) + 1
    benchmark_values = map(lambda x: x / n, benchmark_values)
    benchmark_values = list(map(lambda x: norm.ppf(x), benchmark_values))

    # Figure out the limits.
    maximum = max(max(benchmark_values), max(strategy_values))

    result = LineChart(start_x=-maximum, end_x=maximum, upper_y=maximum, lower_y=-maximum)
    result.add_decorator(ScatterDecorator(
        benchmark_values, strategy_values, color=colors[0], alpha=0.6, edgecolors='black', linewidths=0.5))

    result.add_decorator(VerticalLineDecorator(0, color='black', linewidth=1))
    result.add_decorator(HorizontalLineDecorator(0, color='black', linewidth=1))

    result.add_decorator(TitleDecorator("Normal Distribution Q-Q"))
    result.add_decorator(AxesLabelDecorator("Normal Distribution Quantile", "Observed Quantile"))

    # Add diagonal line.
    result.add_decorator(DiagonalLineDecorator(color=colors[1]))

    return result
Beispiel #3
0
    def _get_monte_carlos_simulator_outputs(self, scenarios_df: PricesDataFrame, total_returns: SimpleReturnsSeries) \
            -> DFTable:
        _, all_scenarios_number = scenarios_df.shape
        rows = []

        # Add the Median Return value
        median_return = np.median(total_returns)
        rows.append(("Median Return", "{:.2%}".format(median_return)))

        # Add the Mean Return value
        mean_return = total_returns.mean()
        rows.append(("Mean Return", "{:.2%}".format(mean_return)))

        trade_returns = QFSeries(data=[trade.percentage_pnl for trade in self.trades])
        sample_len = int(self._average_number_of_trades_per_year())
        std = trade_returns.std()
        expectation_adj_series = np.ones(sample_len) * (trade_returns.mean() - 0.5 * std * std)
        expectation_adj_series = SimpleReturnsSeries(data=expectation_adj_series)
        expectation_adj_series = expectation_adj_series.to_prices(suggested_initial_date=0)
        mean_volatility_adjusted_return = expectation_adj_series.iloc[-1] / expectation_adj_series.iloc[0] - 1.0
        rows.append(("Mean Volatility Adjusted Return", "{:.2%}".format(mean_volatility_adjusted_return)))

        # Add the Median Drawdown
        max_drawdowns = max_drawdown(scenarios_df)
        median_drawdown = np.median(max_drawdowns)
        rows.append(("Median Maximum Drawdown", "{:.2%}".format(median_drawdown)))

        # Add the Median Return / Median Drawdown
        rows.append(("Return / Drawdown", "{:.2f}".format(median_return / median_drawdown)))

        # Probability, that the return will be > 0
        scenarios_with_positive_result = total_returns[total_returns > 0.0].count()
        probability = scenarios_with_positive_result / all_scenarios_number
        rows.append(("Probability of positive return", "{:.2%}".format(probability)))

        table = DFTable(data=QFDataFrame.from_records(rows, columns=["Measure", "Value"]),
                        css_classes=['table', 'left-align'])
        table.add_columns_classes(["Measure"], 'wide-column')

        return table
Beispiel #4
0
    def _get_simulation_plot(self, scenarios_df: PricesDataFrame) -> Chart:
        chart = LineChart(log_scale=True)

        for _, scenario in scenarios_df.items():
            data_element = DataElementDecorator(scenario, linewidth=0.5)
            chart.add_decorator(data_element)

        # Add a legend
        legend = LegendDecorator(key="legend_decorator")

        # Add Ensemble average
        ensemble_avg = scenarios_df.mean(axis=1)
        ensemble_avg_data_element = DataElementDecorator(ensemble_avg, color="#e1e5f4", linewidth=3)
        chart.add_decorator(ensemble_avg_data_element)
        legend.add_entry(ensemble_avg_data_element, "Ensemble average")

        # Add Expectation (vol adjusted)
        trade_returns = QFSeries(data=[trade.percentage_pnl for trade in self.trades])
        std = trade_returns.std()
        expectation_adj_series = np.ones(len(ensemble_avg)) * (trade_returns.mean() - 0.5 * std * std)
        expectation_adj_series = SimpleReturnsSeries(data=expectation_adj_series, index=ensemble_avg.index)
        expectation_adj_series = expectation_adj_series.to_prices()

        data_element = DataElementDecorator(expectation_adj_series, color="#46474b", linewidth=2)
        chart.add_decorator(data_element)
        legend.add_entry(data_element, "Expectation (vol adjusted)")

        # Add title
        title_decorator = TitleDecorator("Monte Carlo Simulations (log scale)", key="title")
        chart.add_decorator(title_decorator)

        position_decorator = AxesPositionDecorator(*self.full_image_axis_position)
        chart.add_decorator(position_decorator)

        chart.add_decorator(legend)

        return chart