Coverage for src / monte_neo / cli / menu / settings.py: 0%
55 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-28 16:27 +0200
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-28 16:27 +0200
1"""Evolutionary settings workflow."""
3from __future__ import annotations
5from typing import TYPE_CHECKING
7import questionary
8from rich.console import Console
10from monte_neo.cli.styles import CUSTOM_STYLE
12if TYPE_CHECKING:
13 from monte_neo.cli.menu.main import InteractiveMenu
15console = Console()
18def settings_workflow(menu: InteractiveMenu) -> None:
19 """Settings menu for evolutionary parameters."""
20 console.print("\n[bold cyan]⚙️ Evolutionary Settings[/]\n")
22 choices = [
23 {"name": f"👥 Population Size ({menu._pop_size})", "value": "pop_size"},
24 {"name": f"🔄 Generations ({menu._generations})", "value": "generations"},
25 {"name": f"🧪 Mutation Rate ({menu._mutation_rate:.2f})", "value": "mutation"},
26 {"name": f"🧬 Crossover Rate ({menu._crossover_rate:.2f})", "value": "crossover"},
27 {"name": f"🛡️ Stop Loss ({menu._stop_loss_pct:.1f}%)", "value": "sl"},
28 {"name": f"🎯 Take Profit ({menu._take_profit_pct:.1f}%)", "value": "tp"},
29 {"name": f"⚖️ Use SL/TP ({'✅' if menu._use_sl_tp else '❌'})", "value": "use_sl_tp"},
30 {"name": f"🏁 MC Threshold ({menu._mc_pass_threshold:.0%})", "value": "mc_threshold"},
31 {"name": f"🚀 Use GPU ({'✅' if menu._use_gpu else '❌'})", "value": "use_gpu"},
32 {"name": f"💎 GPU Precision ({menu._gpu_precision})", "value": "gpu_precision"},
33 {"name": f"⚡ Metal Driver ({menu._metal_driver.upper()})", "value": "metal_driver"},
34 {"name": "🔙 Back", "value": "back"},
35 ]
37 choice = questionary.select("Select setting to modify:", choices=choices, style=CUSTOM_STYLE).ask()
39 if choice == "pop_size":
40 val = questionary.text("Population Size:", default=str(menu._pop_size)).ask()
41 if val: menu._pop_size = int(val)
42 elif choice == "generations":
43 val = questionary.text("Generations:", default=str(menu._generations)).ask()
44 if val: menu._generations = int(val)
45 elif choice == "mutation":
46 val = questionary.text("Mutation Rate (0.0-1.0):", default=str(menu._mutation_rate)).ask()
47 if val: menu._mutation_rate = float(val)
48 elif choice == "crossover":
49 val = questionary.text("Crossover Rate (0.0-1.0):", default=str(menu._crossover_rate)).ask()
50 if val: menu._crossover_rate = float(val)
51 elif choice == "sl":
52 rr_choices = [
53 {"name": "Custom (%)", "value": "custom"},
54 {"name": "Conservative (0.5%)", "value": 0.5},
55 {"name": "Standard (1.0%)", "value": 1.0},
56 {"name": "Aggressive (2.0%)", "value": 2.0},
57 ]
58 val = questionary.select("Select Stop Loss:", choices=rr_choices, style=CUSTOM_STYLE).ask()
59 if val == "custom":
60 val = questionary.text("Stop Loss Percentage:", default=str(menu._stop_loss_pct)).ask()
61 if val: menu._stop_loss_pct = float(val)
62 elif val is not None:
63 menu._stop_loss_pct = val
64 elif choice == "tp":
65 rr_choices = [
66 {"name": "Custom (%)", "value": "custom"},
67 {"name": f"Risk Ratio 1:1 ({menu._stop_loss_pct * 1.0:.1f}%)", "value": menu._stop_loss_pct * 1.0},
68 {"name": f"Risk Ratio 1.5:1 ({menu._stop_loss_pct * 1.5:.1f}%)", "value": menu._stop_loss_pct * 1.5},
69 {"name": f"Risk Ratio 2:1 ({menu._stop_loss_pct * 2.0:.1f}%)", "value": menu._stop_loss_pct * 2.0},
70 {"name": f"Risk Ratio 3:1 ({menu._stop_loss_pct * 3.0:.1f}%)", "value": menu._stop_loss_pct * 3.0},
71 ]
72 val = questionary.select("Select Take Profit (Risk Ratio):", choices=rr_choices, style=CUSTOM_STYLE).ask()
73 if val == "custom":
74 val = questionary.text("Take Profit Percentage:", default=str(menu._take_profit_pct)).ask()
75 if val: menu._take_profit_pct = float(val)
76 elif val is not None:
77 menu._take_profit_pct = val
78 elif choice == "use_sl_tp":
79 menu._use_sl_tp = not menu._use_sl_tp
80 elif choice == "mc_threshold":
81 val = questionary.text("MC Pass Threshold (0.0-1.0):", default=str(menu._mc_pass_threshold)).ask()
82 if val: menu._mc_pass_threshold = float(val)
83 elif choice == "use_gpu":
84 menu._use_gpu = not menu._use_gpu
85 elif choice == "gpu_precision":
86 prec_choices = [
87 {"name": "float32 (Standard)", "value": "float32"},
88 {"name": "float16 (Faster)", "value": "float16"},
89 {"name": "float8_e4m3 (Extreme - 4x memory)", "value": "float8_e4m3"},
90 {"name": "float8_e5m2 (Extreme - 4x memory)", "value": "float8_e5m2"},
91 ]
92 val = questionary.select("Select GPU Precision:", choices=prec_choices, style=CUSTOM_STYLE).ask()
93 if val: menu._gpu_precision = val
94 elif choice == "metal_driver":
95 driver_choices = [
96 {"name": "Auto-Select (Recommended, Micro-Benchmark)", "value": "auto"},
97 {"name": "Clang C++ (Optimized)", "value": "cpp"},
98 {"name": "Objective-C++ (Native)", "value": "objc"},
99 {"name": "Apple Swift (Modern)", "value": "swift"},
100 ]
101 val = questionary.select("Select Metal Driver:", choices=driver_choices, style=CUSTOM_STYLE).ask()
102 if val:
103 menu._metal_driver = val
104 menu.config.metal_driver = val
105 from monte_neo.utils.config import save_config
106 save_config(menu.config, "config.yaml")
107 console.print(f"[green]Metal driver set to {val.upper()} and saved to config.yaml[/]")