Exemplo n.º 1
0
    def _add_pnl_and_performance_contribution_tables(
            self, ticker_to_pnl: Dict[Ticker, PricesSeries]):
        # For each ticker compute the PnL for each period (each year, month etc)
        pnl_df = QFDataFrame.from_dict(ticker_to_pnl)
        agg_performance = pnl_df.groupby(pd.Grouper(key=pnl_df.index.name, freq=self._frequency.to_pandas_freq())) \
            .apply(lambda s: s.iloc[-1] - s.iloc[0])

        # Format the column labels, so that they point exactly to the considered time frame
        column_labels_format = {
            Frequency.YEARLY: "%Y",
            Frequency.MONTHLY: "%b %Y",
        }
        columns_format = column_labels_format[self._frequency]
        performance_df = agg_performance.rename(
            index=lambda timestamp: timestamp.strftime(columns_format))

        # Transpose the original data frame, so that performance for each period is presented in a separate column
        performance_df = performance_df.transpose()
        performance_df.index = performance_df.index.set_names("Asset")
        performance_df = performance_df.reset_index()
        performance_df["Asset"] = performance_df["Asset"].apply(
            lambda t: t.name)

        performance_tables = self._create_performance_tables(
            performance_df.copy())
        performance_contribution_tables = self._create_performance_contribution_tables(
            performance_df.copy())

        # Add the text and all figures into the document
        self.document.add_element(
            HeadingElement(level=2, text="Profit and Loss"))
        self.document.add_element(
            ParagraphElement(
                "The following tables provide the details on the Total profit and "
                "loss for each asset (notional in currency units)."))
        self.document.add_element(ParagraphElement("\n"))

        for table in performance_tables:
            self.document.add_element(
                HeadingElement(level=3,
                               text="Performance between: {} - {}".format(
                                   table.model.data.columns[1],
                                   table.model.data.columns[-1])))
            self.document.add_element(table)
            self.document.add_element(ParagraphElement("\n"))

        self.document.add_element(NewPageElement())

        # Add performance contribution table
        self.document.add_element(
            HeadingElement(level=2, text="Performance contribution"))
        for table in performance_contribution_tables:
            self.document.add_element(
                HeadingElement(
                    level=3,
                    text="Performance contribution between {} - {}".format(
                        table.model.data.columns[1],
                        table.model.data.columns[-1])))
            self.document.add_element(table)
Exemplo n.º 2
0
    def _add_open_positions_table(self):
        open_positions_dict = self._portfolio.open_positions_dict

        contracts = open_positions_dict.keys()

        # Return a readable name for each ticker (name property for FutureTickers and ticker for Tickers)
        tickers = [
            self._portfolio.contract_ticker_mapper.contract_to_ticker(
                contract, strictly_to_specific_ticker=False)
            for contract in contracts
        ]
        tickers = [ticker.name for ticker in tickers]

        specific_tickers = [
            self._portfolio.contract_ticker_mapper.contract_to_ticker(
                contract).ticker for contract in contracts
        ]

        # Get the information whether it is a long or short position
        directions = [
            open_positions_dict[contract].direction() for contract in contracts
        ]
        directions = [
            "LONG" if direction == 1 else "SHORT" for direction in directions
        ]

        # Get the total exposure and market value for each open position
        total_exposures = [
            "{:,.2f}".format(open_positions_dict[contract].total_exposure())
            for contract in contracts
        ]
        pnls = [
            "{:,.2f}".format(open_positions_dict[contract].unrealised_pnl)
            for contract in contracts
        ]

        # Get the time of opening the positions
        start_time = [
            open_positions_dict[contract].start_time.date()
            for contract in contracts
        ]

        data = {
            "Tickers name": tickers,
            "Specific ticker": specific_tickers,
            "Direction": directions,
            "Total Exposure": total_exposures,
            "PnL": pnls,
            "Position Creation": start_time
        }

        table = DFTable(QFDataFrame.from_dict(data),
                        css_classes=['table', 'left-align'])
        self.document.add_element(table)
Exemplo n.º 3
0
    def _add_open_positions_table(self):
        open_positions_dict = self._portfolio.open_positions_dict
        tickers = open_positions_dict.keys()

        # Get the information whether it is a long or short position
        directions = [open_positions_dict[t].direction() for t in tickers]
        directions = [
            "LONG" if direction == 1 else "SHORT" for direction in directions
        ]

        # Get the total exposure and market value for each open position
        total_exposures = [
            "{:,.2f}".format(open_positions_dict[t].total_exposure())
            for t in tickers
        ]
        pnls = [
            "{:,.2f}".format(open_positions_dict[t].unrealised_pnl)
            for t in tickers
        ]

        # Get the time of opening the positions
        start_time = [
            open_positions_dict[t].start_time.date() for t in tickers
        ]

        data = {
            "Tickers name": [t.name for t in tickers],
            "Specific ticker": tickers,
            "Direction": directions,
            "Total Exposure": total_exposures,
            "PnL": pnls,
            "Position Creation": start_time
        }

        table = DFTable(QFDataFrame.from_dict(data),
                        css_classes=['table', 'left-align'])
        self.document.add_element(table)