File size: 2,508 Bytes
558db1e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
from table_builder import trans

def build_bench_html(bench, bench_ticker, trading_days, equity, bt_stats, has_curr, curr_bt_stats, curr):
    bench_html = ""
    if bench is not None and not bench.empty:
        bench_base = float(bench.iloc[0])
        bench_total = (float(bench.iloc[-1]) / bench_base - 1) if bench_base > 1e-5 else 0.0
        n_yrs_bt = len(equity) / trading_days
        port_ann_r = (1 + bt_stats["total_ret"]) ** (1 / max(n_yrs_bt, 0.1)) - 1
        bench_ann_r = (1 + bench_total) ** (1 / max(n_yrs_bt, 0.1)) - 1
        curr_ann_r = None
        if has_curr and curr_bt_stats:
            curr_ann_r = (1 + curr_bt_stats["total_ret"]) ** (1 / max(n_yrs_bt, 0.1)) - 1
            
        bench_html = (
            f'<div class="mc"><div class="ml">{bench_ticker} Ann. Return</div>'
            f'<div class="mv">{bench_ann_r:+.2%}</div></div>'
            f'<div class="mc" title="Annualised return of this portfolio minus {bench_ticker} over the same period">'
            f'<div class="ml">Ann. Alpha vs {bench_ticker} &#9432;</div>'
            + trans(curr_ann_r - bench_ann_r if curr_ann_r is not None else None,
                    port_ann_r - bench_ann_r, curr=curr, has_curr=has_curr, is_pct=True,
                    tooltip=f"Alpha = your portfolio's ann. return minus {bench_ticker}'s ann. return. Positive = outperformance.")
            + '</div>'
        )
    return bench_html

def build_oos_section(oos_stats):
    oos_section = ""
    if oos_stats:
        o_col = "green" if oos_stats['ann_ret'] >= 0 else "red"
        oos_section = (
            f'<div class="mg">'
            f'<div class="mc" title="Annualised return on the unseen test year. This is the honest signal.">'
            f'<div class="ml">Walk-Fwd Ann. Return &#9432;</div>'
            f'<div class="mv {o_col}">{oos_stats["ann_ret"]:+.2%}</div></div>'
            f'<div class="mc" title="Risk-adjusted return on the unseen test year.">'
            f'<div class="ml">Walk-Fwd Sharpe &#9432;</div>'
            f'<div class="mv blue">{oos_stats["sharpe"]:.2f}</div></div>'
            f'<div class="mc" title="Worst drawdown during the unseen test year.">'
            f'<div class="ml">Walk-Fwd Max DD &#9432;</div>'
            f'<div class="mv red">{oos_stats["max_dd"]:.2%}</div></div>'
            f'<div class="mc"><div class="ml">DD Duration</div>'
            f'<div class="mv yellow">{oos_stats["dd_days"]} days</div></div>'
            f'</div>'
        )
    return oos_section