Source code for qf_lib.plotting.helpers.create_returns_bar_chart

#     Copyright 2016-present CERN – European Organization for Nuclear Research
#
#     Licensed under the Apache License, Version 2.0 (the "License");
#     you may not use this file except in compliance with the License.
#     You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#     Unless required by applicable law or agreed to in writing, software
#     distributed under the License is distributed on an "AS IS" BASIS,
#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#     See the License for the specific language governing permissions and
#     limitations under the License.
import math
import numpy as np

from qf_lib.common.enums.axis import Axis
from qf_lib.common.enums.frequency import Frequency
from qf_lib.common.enums.orientation import Orientation
from qf_lib.common.utils.returns.get_aggregate_returns import get_aggregate_returns
from qf_lib.containers.series.qf_series import QFSeries
from qf_lib.plotting.charts.bar_chart import BarChart
from qf_lib.plotting.charts.chart import Chart
from qf_lib.plotting.decorators.axes_formatter_decorator import AxesFormatterDecorator, PercentageFormatter
from qf_lib.plotting.decorators.axes_label_decorator import AxesLabelDecorator
from qf_lib.plotting.decorators.axis_tick_labels_decorator import AxisTickLabelsDecorator
from qf_lib.plotting.decorators.bar_values_decorator import BarValuesDecorator
from qf_lib.plotting.decorators.data_element_decorator import DataElementDecorator
from qf_lib.plotting.decorators.legend_decorator import LegendDecorator
from qf_lib.plotting.decorators.line_decorators import VerticalLineDecorator
from qf_lib.plotting.decorators.title_decorator import TitleDecorator


[docs]def create_returns_bar_chart(returns: QFSeries, frequency: Frequency = Frequency.YEARLY, title: str = None) -> BarChart: """ Constructs a new returns bar chart based on the returns specified. By default, a new annual returns bar chart will be created. Parameters ---------- returns: QFSeries The returns series to use in the chart. frequency: Frequency Frequency of the returns after aggregation It accepts YEARLY, MONTHLY, WEEKLY and DAILY frequencies title: optional title for the chart Returns -------- BarChart """ colors = Chart.get_axes_colors() # Calculate data. aggregate_returns = get_aggregate_returns(returns, frequency, multi_index=False) data_series = QFSeries(_convert_date(aggregate_returns, frequency).sort_index(ascending=True)) chart = BarChart(Orientation.Horizontal, align="center") chart.add_decorator(DataElementDecorator(data_series, key="data_element")) chart.add_decorator(BarValuesDecorator(data_series)) # Format the x-axis so that its labels are shown as a percentage. chart.add_decorator(AxesFormatterDecorator(x_major=PercentageFormatter())) # Format Y axis to make sure we have a tick for each year or 2 years data_series_length = len(data_series) if data_series_length > 10: data_series = data_series[np.arange(data_series_length) % math.ceil(data_series_length / 10) == 0] y_labels = data_series.index chart.add_decorator(AxisTickLabelsDecorator(labels=y_labels, axis=Axis.Y, tick_values=y_labels)) # Add an average line. avg_line = VerticalLineDecorator( aggregate_returns.values.mean(), color=colors[1], key="avg_line", linestyle="--", alpha=0.8) chart.add_decorator(avg_line) # Add a legend. legend = LegendDecorator(key="legend_decorator") legend.add_entry(avg_line, "Mean") chart.add_decorator(legend) # Add a title. if title is None: title = str(frequency).capitalize() + " Returns" title = TitleDecorator(title, key="title_decorator") chart.add_decorator(title) chart.add_decorator(AxesLabelDecorator("Returns", "Year")) return chart
def _convert_date(data_series, frequency: Frequency): format_frequency = { Frequency.YEARLY: "%Y", Frequency.MONTHLY: "%Y %m", Frequency.WEEKLY: "%Y %V", Frequency.DAILY: "%Y %m %d" } return data_series.rename(index=lambda x: x.strftime(format_frequency[frequency]))