{"record":{"id":"03b9a29223f3c63a","repo":"nautechsystems/nautilus_trader","slug":"plotly-is-required-for-visualization-install-it-w","errorCode":null,"errorMessage":"plotly is required for visualization. Install it with: pip install nautilus_trader[visualization]","messagePattern":"plotly is required for visualization\\. Install it with: pip install nautilus_trader\\[visualization\\]","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"python/nautilus_trader/analysis/tearsheet.py","lineNumber":413,"sourceCode":"    str or None\n        HTML string if output_path is None, otherwise None.\n\n    Raises\n    ------\n    ImportError\n        If plotly is not installed.\n    ValueError\n        If ``bars_with_fills`` is configured without a node, a supplied node has no\n        run configuration ID, or the matching run configuration sets\n        ``dispose_on_completion=True``.\n\n    \"\"\"\n    if not PLOTLY_AVAILABLE:\n        msg = (\n            \"plotly is required for visualization. \"\n            \"Install it with: pip install nautilus_trader[visualization]\"\n        )\n        raise ImportError(msg)\n\n    _require_not_none(engine, \"engine\")\n\n    if not hasattr(engine, \"get_result\"):\n        return _create_tearsheet_from_result(\n            result=engine,\n            node=node,\n            run_config_id=run_config_id,\n            currency=currency,\n            output_path=output_path,\n            title=title,\n            config=config,\n            benchmark_returns=benchmark_returns,\n            benchmark_name=benchmark_name,\n        )\n\n    result = engine.get_result()\n    stats_returns = dict(result.stats_returns)","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/python/nautilus_trader/analysis/tearsheet.py#L395-L431","documentation":"BetfairExecutionClientConfig::validate() rejects order_request_rate_per_second == 0. This field throttles order-placement requests specifically and is separate from the general request_rate_per_second; only the execution client config carries it. Zero would make order submission impossible, so validation aborts the connect before any live trading can start.","triggerScenarios":"Setting order_request_rate_per_second: 0 in a live execution config; deserializing an exec config from a template that zero-initializes numeric fields; calling validate() during deployment checks.","commonSituations":"Placeholder zeros left in configs promoted from test to live; misunderstanding the two rate fields and zeroing both; schema migration adding the field with a zero default.","solutions":["Set a positive order request rate matching your app key's order transaction limits","Omit the field so the default applies","Add a deployment gate that runs validate() on the exec config before the node starts"],"exampleFix":"// before\n.order_request_rate_per_second(0)\n\n// after\n.order_request_rate_per_second(5)","handlingStrategy":"validation","validationCode":"let config = BetfairExecutionClientConfig::builder()\n    .order_request_rate_per_second(5)\n    .build()?;\nconfig.validate()?;","typeGuard":"fn is_positive_rate(v: u32) -> bool {\n    v > 0\n}","tryCatchPattern":null,"preventionTips":["Check both rate fields when tuning the execution client","Never promote a config with zeroed numeric fields to live","Add a pre-deploy assertion that validates the exec config"],"tags":["betfair","config","rate-limit","orders","live-trading","rust"],"backgroundTag":"invalid-rate-limit-config","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}