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
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
def create_gross_leverage_chart(gross_lev: QFSeries) -> LineChart: """ Creates a line chart showing gross leverage based on the specified gross leverage values. Parameters ---------- gross_lev: QFSeries Gross leverage as returned by the extract_rets_pos_txn_from_zipline function. Returns ------- LineChart Created line chart """ result = LineChart() result.add_decorator( DataElementDecorator(gross_lev, linewidth=0.5, color="g")) result.add_decorator( HorizontalLineDecorator(gross_lev.mean(), color="g", linestyle="--", linewidth=3)) result.add_decorator(TitleDecorator("Gross leverage")) result.add_decorator(AxesLabelDecorator(y_label="Gross leverage")) return result
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
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