feat(research): comando CLI research-trigger + flag force
- option_chain_research_cycle: parametro force=True bypassa il gate enabled, per testare la raccolta prima di accendere il cron. - CLI `option-chain research-trigger`: esegue UNA volta il collector full-chain (source='research', book_depth popolato), come il gemello `trigger` per il collettore live. Verificato: 324 quote ETH su 7 scadenze (DTE 1..80), book_depth su tutte. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1204,6 +1204,70 @@ def option_chain_trigger(
|
||||
)
|
||||
|
||||
|
||||
@option_chain.command(name="research-trigger")
|
||||
@click.option(
|
||||
"--strategy",
|
||||
"strategy_path",
|
||||
type=click.Path(exists=True, dir_okay=False, path_type=Path),
|
||||
default=_DEFAULT_STRATEGY_PATH,
|
||||
show_default=True,
|
||||
)
|
||||
@click.option(
|
||||
"--db",
|
||||
"db_path",
|
||||
type=click.Path(dir_okay=False, path_type=Path),
|
||||
default=_DEFAULT_DB_PATH,
|
||||
show_default=True,
|
||||
)
|
||||
@click.option(
|
||||
"--audit",
|
||||
"audit_path",
|
||||
type=click.Path(dir_okay=False, path_type=Path),
|
||||
default=_DEFAULT_AUDIT_PATH,
|
||||
show_default=True,
|
||||
)
|
||||
@click.option(
|
||||
"--token",
|
||||
type=str,
|
||||
default=None,
|
||||
help="MCP bearer token (override su CERBERO_BITE_MCP_TOKEN).",
|
||||
)
|
||||
@click.option("--asset", default="ETH", show_default=True)
|
||||
def option_chain_research_trigger(
|
||||
strategy_path: Path,
|
||||
db_path: Path,
|
||||
audit_path: Path,
|
||||
token: str | None,
|
||||
asset: str,
|
||||
) -> None:
|
||||
"""Esegue UNA volta il collector research full-chain (source='research').
|
||||
|
||||
Cattura tutte le scadenze ed entrambe le ali con book_depth_top3
|
||||
popolato. ``force=True``: gira anche se ``research_collector.enabled``
|
||||
è false, utile per testare prima di accendere il cron orario.
|
||||
"""
|
||||
from cerbero_bite.runtime.dependencies import build_runtime # noqa: PLC0415
|
||||
from cerbero_bite.runtime.option_chain_research_cycle import ( # noqa: PLC0415
|
||||
collect_option_chain_research,
|
||||
)
|
||||
|
||||
cfg = load_strategy(strategy_path).config
|
||||
ctx = build_runtime(
|
||||
cfg=cfg,
|
||||
endpoints=load_endpoints(),
|
||||
token=load_token(value=token),
|
||||
db_path=db_path,
|
||||
audit_path=audit_path,
|
||||
bot_tag=load_bot_tag(),
|
||||
)
|
||||
n = asyncio.run(collect_option_chain_research(ctx, asset=asset, force=True))
|
||||
console.print(
|
||||
f"[green]Persisted {n} research quote(s) for {asset}[/green]"
|
||||
if n > 0
|
||||
else "[yellow]No quotes persisted (chain empty or fetch failed)[/yellow]"
|
||||
)
|
||||
|
||||
|
||||
@option_chain.command(name="analyze")
|
||||
@click.option(
|
||||
"--strategy",
|
||||
|
||||
@@ -70,12 +70,16 @@ async def collect_option_chain_research(
|
||||
asset: str = "ETH",
|
||||
now: datetime | None = None,
|
||||
batch_size: int = DEFAULT_BATCH_SIZE,
|
||||
force: bool = False,
|
||||
) -> int:
|
||||
"""Collect + persist un singolo snapshot full-chain ``research`` per
|
||||
``asset``. Ritorna il numero di quote persistiti (0 su fallimento
|
||||
best-effort o se il collettore è disabilitato)."""
|
||||
best-effort o se il collettore è disabilitato).
|
||||
|
||||
``force=True`` bypassa il gate ``enabled`` (usato dal trigger CLI per
|
||||
testare la raccolta prima di accendere il cron schedulato)."""
|
||||
rc = getattr(ctx.cfg, "research_collector", None)
|
||||
if rc is None or not rc.enabled:
|
||||
if rc is None or (not rc.enabled and not force):
|
||||
return 0
|
||||
|
||||
when = (now or datetime.now(UTC)).astimezone(UTC)
|
||||
|
||||
Reference in New Issue
Block a user