Coverage for src / monte_neo / cli / menu / generator.py: 0%
45 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"""Indicator generation workflow."""
3from __future__ import annotations
5import time
6from typing import TYPE_CHECKING
8import questionary
10from monte_neo.cli.styles import CUSTOM_STYLE
11from monte_neo.core.generator import GeneratorConfig, IndicatorGenerator
12from monte_neo.utils.console import console
14if TYPE_CHECKING:
15 from monte_neo.cli.menu.main import InteractiveMenu
18def generate_indicator_workflow(menu: InteractiveMenu, sequential: bool = False) -> None:
19 """Generate indicator workflow."""
20 title = "🚀 Generate Indicator" if not sequential else "🔄 Sequential Generate Indicator"
21 console.print(f"\n[bold cyan]{title}[/]\n")
23 if not menu._target_metrics:
24 console.print("[yellow]⚠ Please set target metrics first[/]\n")
25 return
27 files = menu.storage.list_files()
28 if not files:
29 console.print("[yellow]⚠ No data available. Download data first.[/]\n")
30 return
32 file_choices = [f"{f['symbol']}_{f['timeframe']}" for f in files]
33 selected = questionary.select("Select data:", choices=file_choices, style=CUSTOM_STYLE).ask()
35 if not selected:
36 return
38 symbol, timeframe = selected.split("_")
40 # Get iterations and types
41 iterations = _get_iterations()
42 if not iterations: return
44 indicator_types = _get_indicator_types()
45 if not indicator_types: return
47 # Confirm and Run
48 if not questionary.confirm("Start generation?", style=CUSTOM_STYLE).ask():
49 return
51 _run_generation(menu, symbol, timeframe, iterations, indicator_types, sequential)
54def _get_iterations() -> int | None:
55 return questionary.select(
56 "Number of iterations:",
57 choices=[
58 {"name": "1,000 (fast test)", "value": 1000},
59 {"name": "10,000 (standard)", "value": 10000},
60 {"name": "100,000 (thorough)", "value": 100000},
61 {"name": "1M (heavy)", "value": 1000000},
62 {"name": "10M (expert)", "value": 10000000},
63 {"name": "100M (extreme)", "value": 100000000},
64 {"name": "1B (insane)", "value": 1000000000},
65 ],
66 style=CUSTOM_STYLE,
67 ).ask()
70def _get_indicator_types() -> list[str] | None:
71 return questionary.checkbox(
72 "Select indicator types to search:",
73 choices=[
74 {"name": "SMA", "value": "sma", "checked": True},
75 {"name": "RSI", "value": "rsi", "checked": True},
76 {"name": "MACD", "value": "macd", "checked": True},
77 {"name": "🧬 Dynamic", "value": "dynamic", "checked": True},
78 ],
79 style=CUSTOM_STYLE,
80 ).ask()
83def _run_generation(menu: InteractiveMenu, symbol: str, timeframe: str, iterations: int, types: list[str], sequential: bool = False) -> None:
84 data = menu.storage.load(symbol, timeframe)
85 menu._last_data = data # Restore to allow charting after generation
87 config = GeneratorConfig(
88 max_iterations=iterations,
89 target_metrics=menu._target_metrics,
90 indicator_types=types,
91 population_size=menu._pop_size,
92 generations=menu._generations,
93 mutation_rate=menu._mutation_rate,
94 crossover_rate=menu._crossover_rate,
95 use_sl_tp=menu._use_sl_tp,
96 stop_loss_pct=menu._stop_loss_pct,
97 take_profit_pct=menu._take_profit_pct,
98 use_mc_shuffling="shuffling" in menu._mc_methods,
99 use_mc_noise="noise" in menu._mc_methods,
100 use_mc_sensitivity="sensitivity" in menu._mc_methods,
101 use_mc_walk_forward="walk_forward" in menu._mc_methods,
102 use_mc_block_bootstrap="block_bootstrap" in menu._mc_methods,
103 use_sequential_mc=sequential,
104 mc_pass_threshold=getattr(menu, "_mc_pass_threshold", 0.80),
105 use_gpu=getattr(menu, "_use_gpu", True),
106 gpu_precision=getattr(menu, "_gpu_precision", "float32"),
107 metal_driver=getattr(menu, "_metal_driver", "cpp"),
108 initial_capital=menu.config.initial_capital,
109 leverage=menu.config.leverage,
110 )
112 generator = IndicatorGenerator(config)
113 menu.progress.start(iterations, "Generating indicator...")
114 generator.set_progress_callback(menu.progress.update)
116 result = generator.generate(data)
117 time.sleep(0.1)
118 menu.progress.update(iterations, iterations, "Done")
119 menu.progress.stop()
121 from monte_neo.cli.menu.results import show_generation_result
122 show_generation_result(menu, result)