@@ -86,7 +86,10 @@ def _per_window_table(bt):
8686 runs = bt .get_all_backtest_runs ()
8787 if not runs :
8888 return "No runs available."
89- header = "| Window | CAGR | Sharpe | Sortino | Max DD | Win Rate | Trades |"
89+ header = (
90+ "| Window | CAGR | Sharpe | Sortino"
91+ " | Max DD | Win Rate | Trades |"
92+ )
9093 sep = "|--------|------|--------|---------|--------|----------|--------|"
9194 rows = [header , sep ]
9295 for run in runs :
@@ -98,7 +101,7 @@ def _per_window_table(bt):
98101 f"| { _fmt_pct (m .cagr )} "
99102 f"| { _fmt_dec (m .sharpe_ratio )} "
100103 f"| { _fmt_dec (m .sortino_ratio )} "
101- f"| { _fmt_pct (abs (m .max_drawdown ) if m .max_drawdown else None )} "
104+ f"| { _fmt_pct (abs (m .max_drawdown ) if m .max_drawdown else None )} " # noqa: E501
102105 f"| { _fmt_pct (m .win_rate )} "
103106 f"| { m .number_of_trades or 0 } |"
104107 )
@@ -135,8 +138,8 @@ def _trading_activity_table(backtests):
135138 f"| { _fmt_dec (getattr (s , 'trades_per_month' , None ))} "
136139 f"| { _fmt_dec (tpw )} "
137140 f"| { getattr (s , 'number_of_trades' , None ) or 0 } "
138- f"| { _fmt_pct (getattr (s , 'average_trade_return_percentage' , None ))} "
139- f"| { _fmt_pct (getattr (s , 'median_trade_return_percentage' , None ))} "
141+ f"| { _fmt_pct (getattr (s , 'average_trade_return_percentage' , None ))} " # noqa: E501
142+ f"| { _fmt_pct (getattr (s , 'median_trade_return_percentage' , None ))} " # noqa: E501
140143 f"| { _fmt_dec (getattr (s , 'average_trade_duration' , None ))} "
141144 f"| { getattr (s , 'max_consecutive_wins' , None ) or 0 } "
142145 f"| { getattr (s , 'max_consecutive_losses' , None ) or 0 } "
@@ -215,8 +218,14 @@ def _full_analysis(backtests):
215218 trades = _top_trades (bt , 5 )
216219 if trades :
217220 md += "### Top Trades\n \n "
218- md += "| Symbol | Opened | Closed | Return % | Net Gain | Window |\n "
219- md += "|--------|--------|--------|----------|----------|--------|\n "
221+ md += (
222+ "| Symbol | Opened | Closed"
223+ " | Return % | Net Gain | Window |\n "
224+ )
225+ md += (
226+ "|--------|--------|--------"
227+ "|----------|----------|--------|\n "
228+ )
220229 for t in trades :
221230 md += (
222231 f"| { t ['symbol' ]} | { t ['opened' ]} | { t ['closed' ]} "
@@ -667,7 +676,6 @@ def _symbol_breakdown(bt):
667676 for run in bt .get_all_backtest_runs ():
668677 for t in (run .trades or []):
669678 sym = getattr (t , 'target_symbol' , '' ) or '—'
670- cost = getattr (t , 'cost' , 0 ) or 0
671679 ng = getattr (t , 'net_gain' , 0 ) or 0
672680 entry = sym_stats .setdefault (sym , {
673681 'count' : 0 , 'gain' : 0.0 , 'wins' : 0 , 'losses' : 0
@@ -738,10 +746,18 @@ def _return_scenarios(bt):
738746 md += f"- Max Drawdown: { _fmt_pct (s .max_drawdown )} \n "
739747 md += f"- VaR 95%: { _fmt_pct (getattr (s , 'var_95' , None ))} \n "
740748 md += f"- CVaR 95%: { _fmt_pct (getattr (s , 'cvar_95' , None ))} \n "
741- md += f"- % Winning Months: { _fmt_pct (getattr (s , 'percentage_winning_months' , None ))} \n "
742- md += f"- % Winning Years: { _fmt_pct (getattr (s , 'percentage_winning_years' , None ))} \n "
743- md += f"- Max Consecutive Wins: { getattr (s , 'max_consecutive_wins' , '—' )} \n "
744- md += f"- Max Consecutive Losses: { getattr (s , 'max_consecutive_losses' , '—' )} \n "
749+ win_mo = _fmt_pct (
750+ getattr (s , 'percentage_winning_months' , None )
751+ )
752+ win_yr = _fmt_pct (
753+ getattr (s , 'percentage_winning_years' , None )
754+ )
755+ md += f"- % Winning Months: { win_mo } \n "
756+ md += f"- % Winning Years: { win_yr } \n "
757+ cons_w = getattr (s , 'max_consecutive_wins' , '—' )
758+ cons_l = getattr (s , 'max_consecutive_losses' , '—' )
759+ md += f"- Max Consecutive Wins: { cons_w } \n "
760+ md += f"- Max Consecutive Losses: { cons_l } \n "
745761
746762 return md
747763
@@ -809,7 +825,6 @@ def _window_coverage(backtests):
809825 for bt in backtests :
810826 for run in bt .get_all_backtest_runs ():
811827 name = run .backtest_date_range_name or "—"
812- ts = getattr (run , 'trading_symbol' , 'EUR' ) or 'EUR'
813828 start = _fmt_date (run .backtest_start_date )
814829 end = _fmt_date (run .backtest_end_date )
815830 days = 0
@@ -1239,9 +1254,10 @@ def _get_tools(self):
12391254 {
12401255 "name" : "get_symbol_breakdown" ,
12411256 "description" : (
1242- "Get per-symbol trade breakdown for a strategy — "
1243- "how many trades per symbol, net gain, win rate. "
1244- "Useful for understanding concentration and diversification."
1257+ "Get per-symbol trade breakdown for a "
1258+ "strategy — how many trades per symbol, "
1259+ "net gain, win rate. Useful for "
1260+ "understanding concentration."
12451261 ),
12461262 "inputSchema" : {
12471263 "type" : "object" ,
@@ -1383,10 +1399,13 @@ def _get_tools(self):
13831399 "description" : (
13841400 "Strategy selections as {strategy_id: tag} "
13851401 "where tag is 'keep', 'maybe', or 'reject'. "
1386- "E.g. {'my_strategy': 'keep', 'other': 'reject'}. "
1387- "When a user clicks 'Apply Selection' on this "
1388- "note, the dashboard filters to show only "
1389- "these strategies."
1402+ "E.g. {'my_strategy': 'keep', "
1403+ "'other': 'reject'}. "
1404+ "When a user clicks "
1405+ "'Apply Selection' on this "
1406+ "note, the dashboard filters "
1407+ "to show only these "
1408+ "strategies."
13901409 ),
13911410 },
13921411 },
@@ -1494,7 +1513,10 @@ def _get_tools(self):
14941513 "description" : (
14951514 "Array of conditions, each with metric, "
14961515 "operator (>, <, >=, <=, ==), and value. "
1497- "E.g. [{\" metric\" :\" sharpe_ratio\" ,\" operator\" :\" >\" ,\" value\" :1.0}]"
1516+ "E.g. [{\" metric\" :"
1517+ "\" sharpe_ratio\" ,"
1518+ "\" operator\" :\" >\" ,"
1519+ "\" value\" :1.0}]"
14981520 ),
14991521 "items" : {
15001522 "type" : "object" ,
@@ -1553,7 +1575,7 @@ def _handle_tool_call(self, name, arguments):
15531575 f"| { _fmt_pct (s .cagr )} "
15541576 f"| { _fmt_dec (s .sharpe_ratio )} "
15551577 f"| { _fmt_dec (s .sortino_ratio )} "
1556- f"| { _fmt_pct (abs (s .max_drawdown ) if s .max_drawdown else None )} "
1578+ f"| { _fmt_pct (abs (s .max_drawdown ) if s .max_drawdown else None )} " # noqa: E501
15571579 f"| { _fmt_pct (s .win_rate )} "
15581580 f"| { _fmt_dec (s .profit_factor )} "
15591581 f"| { _fmt_dec (s .trades_per_year , 0 )} "
@@ -1571,7 +1593,11 @@ def _handle_tool_call(self, name, arguments):
15711593 sid = arguments .get ("strategy_id" , "" )
15721594 bt = self ._bt_map .get (sid )
15731595 if not bt :
1574- return f"Strategy '{ sid } ' not found. Available: { list (self ._bt_map .keys ())} "
1596+ avail = list (self ._bt_map .keys ())
1597+ return (
1598+ f"Strategy '{ sid } ' not found."
1599+ f" Available: { avail } "
1600+ )
15751601 md = f"# { bt .algorithm_id } \n \n "
15761602 if bt .parameters :
15771603 params = ", " .join (
@@ -1585,8 +1611,16 @@ def _handle_tool_call(self, name, arguments):
15851611 trades = _top_trades (bt , 10 )
15861612 if trades :
15871613 md += "## Top Trades\n \n "
1588- md += "| Symbol | Opened | Closed | Return % | Net Gain | Window |\n "
1589- md += "|--------|--------|--------|----------|----------|--------|\n "
1614+ md += (
1615+ "| Symbol | Opened | Closed"
1616+ " | Return % | Net Gain"
1617+ " | Window |\n "
1618+ )
1619+ md += (
1620+ "|--------|--------|--------"
1621+ "|----------|----------"
1622+ "|--------|\n "
1623+ )
15901624 for t in trades :
15911625 md += (
15921626 f"| { t ['symbol' ]} | { t ['opened' ]} | { t ['closed' ]} "
@@ -1666,8 +1700,16 @@ def _handle_tool_call(self, name, arguments):
16661700 if not trades :
16671701 return "No trades found."
16681702 md = f"# Trades for { sid } \n \n "
1669- md += "| Symbol | Opened | Closed | Return % | Net Gain | Window |\n "
1670- md += "|--------|--------|--------|----------|----------|--------|\n "
1703+ md += (
1704+ "| Symbol | Opened | Closed"
1705+ " | Return % | Net Gain"
1706+ " | Window |\n "
1707+ )
1708+ md += (
1709+ "|--------|--------|--------"
1710+ "|----------|----------"
1711+ "|--------|\n "
1712+ )
16711713 for t in trades :
16721714 md += (
16731715 f"| { t ['symbol' ]} | { t ['opened' ]} | { t ['closed' ]} "
@@ -1801,14 +1843,25 @@ def _handle_tool_call(self, name, arguments):
18011843 sid = arguments .get ("strategy_id" , "" )
18021844 bt = self ._bt_map .get (sid )
18031845 if not bt :
1804- return f"Strategy '{ sid } ' not found. Available: { list (self ._bt_map .keys ())} "
1805- return f"# Symbol Breakdown — { sid } \n \n " + _symbol_breakdown (bt )
1846+ avail = list (self ._bt_map .keys ())
1847+ return (
1848+ f"Strategy '{ sid } ' not found."
1849+ f" Available: { avail } "
1850+ )
1851+ return (
1852+ f"# Symbol Breakdown — { sid } \n \n "
1853+ + _symbol_breakdown (bt )
1854+ )
18061855
18071856 elif name == "get_return_scenarios" :
18081857 sid = arguments .get ("strategy_id" , "" )
18091858 bt = self ._bt_map .get (sid )
18101859 if not bt :
1811- return f"Strategy '{ sid } ' not found. Available: { list (self ._bt_map .keys ())} "
1860+ avail = list (self ._bt_map .keys ())
1861+ return (
1862+ f"Strategy '{ sid } ' not found."
1863+ f" Available: { avail } "
1864+ )
18121865 return f"# Return Scenarios — { sid } \n \n " + _return_scenarios (bt )
18131866
18141867 elif name == "get_correlation_matrix" :
@@ -2000,7 +2053,11 @@ def _handle_tool_call(self, name, arguments):
20002053 matched = _filter_strategies (self ._backtests , conditions )
20012054 if not matched :
20022055 return "No strategies match all conditions."
2003- md = f"# Filtered Strategies ({ len (matched )} of { len (self ._backtests )} )\n \n "
2056+ total = len (self ._backtests )
2057+ md = (
2058+ f"# Filtered Strategies"
2059+ f" ({ len (matched )} of { total } )\n \n "
2060+ )
20042061 md += "**Conditions:** "
20052062 md += ", " .join (
20062063 f"{ c ['metric' ]} { c ['operator' ]} { c ['value' ]} "
@@ -2023,7 +2080,7 @@ def _handle_tool_call(self, name, arguments):
20232080 f"| { _fmt_pct (s .cagr )} "
20242081 f"| { _fmt_dec (s .sharpe_ratio )} "
20252082 f"| { _fmt_dec (s .sortino_ratio )} "
2026- f"| { _fmt_pct (abs (s .max_drawdown ) if s .max_drawdown else None )} "
2083+ f"| { _fmt_pct (abs (s .max_drawdown ) if s .max_drawdown else None )} " # noqa: E501
20272084 f"| { _fmt_pct (s .win_rate )} "
20282085 f"| { _fmt_dec (s .profit_factor )} |\n "
20292086 )
0 commit comments