Esempio n. 1
0
def compute_returns_table(pricer: returnslib.Pricer, target_currency: Currency,
                          account_data: List[AccountData],
                          intervals: List[Interval]):
    """Compute a table of sequential returns."""
    header = ["Return"]
    rows = [["Total"], ["Ex-div"], ["Div"]]
    for intname, date1, date2 in intervals:
        header.append(intname)
        cash_flows = returnslib.truncate_and_merge_cash_flows(
            pricer, account_data, date1, date2)
        returns = returnslib.compute_returns(cash_flows, pricer,
                                             target_currency, date2)
        rows[0].append(returns.total)
        rows[1].append(returns.exdiv)
        rows[2].append(returns.div)
    return Table(header, rows)
Esempio n. 2
0
def write_returns_html(
        dirname: str,
        pricer: returnslib.Pricer,
        account_data: List[AccountData],
        title: str,
        end_date: Date,
        target_currency: Optional[Currency] = None) -> subprocess.Popen:
    """Write out returns report to a directory with files in it."""

    logging.info("Writing returns dir for %s: %s", title, dirname)
    os.makedirs(dirname, exist_ok=True)
    with open(path.join(dirname, "index.html"), "w") as indexfile:
        fprint = partial(print, file=indexfile)
        fprint(RETURNS_TEMPLATE_PRE.format(style=STYLE, title=title))

        if not target_currency:
            cost_currencies = set(r.cost_currency for r in account_data)
            target_currency = cost_currencies.pop()
            assert not cost_currencies, (
                "Incompatible cost currencies {} for accounts {}".format(
                    cost_currencies,
                    ",".join([r.account for r in account_data])))

        # TOOD(blais): Prices should be plot separately, by currency.
        # fprint("<h2>Prices</h2>")
        # pairs = set((r.currency, r.cost_currency) for r in account_data)
        # plots = plot_prices(dirname, pricer.price_map, pairs)
        # for _, filename in sorted(plots.items()):
        #     fprint('<img src={} style="width: 100%"/>'.format(filename))

        fprint("<h2>Cash Flows</h2>")

        cash_flows = returnslib.truncate_and_merge_cash_flows(
            pricer, account_data, None, end_date)
        returns = returnslib.compute_returns(cash_flows, pricer,
                                             target_currency, end_date)

        transactions = data.sorted(
            [txn for ad in account_data for txn in ad.transactions])

        # Note: This is where the vast majority of the time is spent.
        plots = plot_flows(dirname, pricer.price_map, cash_flows, transactions,
                           returns.total)
        fprint('<img src={} style="width: 100%"/>'.format(plots["flows"]))
        fprint('<img src={} style="width: 100%"/>'.format(plots["cumvalue"]))

        fprint("<h2>Returns</h2>")
        fprint(
            render_table(Table(["Total", "Ex-Div", "Div"],
                               [[returns.total, returns.exdiv, returns.div]]),
                         floatfmt="{:.2%}"))

        # Compute table of returns over intervals.
        table = compute_returns_table(pricer, target_currency, account_data,
                                      get_calendar_intervals(TODAY))
        fprint("<p>", render_table(table, floatfmt="{:.1%}", classes=["full"]),
               "</p>")

        table = compute_returns_table(pricer, target_currency, account_data,
                                      get_cumulative_intervals(TODAY))
        fprint("<p>", render_table(table, floatfmt="{:.1%}", classes=["full"]),
               "</p>")

        fprint('<h2 class="new-page">Accounts</h2>')
        fprint("<p>Cost Currency: {}</p>".format(target_currency))
        accounts_df = get_accounts_table(account_data)
        fprint(accounts_df.to_html())

        fprint('<h2 class="new-page">Cash Flows</h2>')
        df = investments.cash_flows_to_table(cash_flows)
        fprint(df.to_html())

        fprint(RETURNS_TEMPLATE_POST)

    return indexfile.name