This commit is contained in:
dceoy
2026-06-27 22:56:08 +00:00
parent bba1008be8
commit f27febb6f5
9 changed files with 3695 additions and 2674 deletions
+326 -5
View File
@@ -796,6 +796,108 @@ views <code>cash_events</code> and <code>positions_reconstructed</code> are deri
<div class="doc doc-object doc-function">
<h3 id="mt5cli.cli.grafana_schema" class="doc doc-heading">
<span class="doc doc-object-name doc-function-name">grafana_schema</span>
<a href="#mt5cli.cli.grafana_schema" class="headerlink" title="Permanent link">&para;</a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">grafana_schema</span><span class="p">(</span><span class="n">ctx</span><span class="p">:</span> <span class="n"><span title="typer.Context">Context</span></span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span>
</code></pre></div>
<div class="doc doc-contents ">
<p>Create or refresh Grafana-ready views and indexes in a SQLite database.</p>
<p>Idempotent — safe to run repeatedly on the same database. Requires SQLite
output. Does not connect to MetaTrader 5.</p>
<p><span class="doc-section-title">Raises:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><span title="typer.BadParameter">BadParameter</span></code>
</td>
<td>
<div class="doc-md-description">
<p>If the output format is not SQLite3.</p>
</div>
</td>
</tr>
</tbody>
</table>
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/cli.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-805">805</a></span>
<span class="normal"><a href="#__codelineno-0-806">806</a></span>
<span class="normal"><a href="#__codelineno-0-807">807</a></span>
<span class="normal"><a href="#__codelineno-0-808">808</a></span>
<span class="normal"><a href="#__codelineno-0-809">809</a></span>
<span class="normal"><a href="#__codelineno-0-810">810</a></span>
<span class="normal"><a href="#__codelineno-0-811">811</a></span>
<span class="normal"><a href="#__codelineno-0-812">812</a></span>
<span class="normal"><a href="#__codelineno-0-813">813</a></span>
<span class="normal"><a href="#__codelineno-0-814">814</a></span>
<span class="normal"><a href="#__codelineno-0-815">815</a></span>
<span class="normal"><a href="#__codelineno-0-816">816</a></span>
<span class="normal"><a href="#__codelineno-0-817">817</a></span>
<span class="normal"><a href="#__codelineno-0-818">818</a></span>
<span class="normal"><a href="#__codelineno-0-819">819</a></span>
<span class="normal"><a href="#__codelineno-0-820">820</a></span>
<span class="normal"><a href="#__codelineno-0-821">821</a></span>
<span class="normal"><a href="#__codelineno-0-822">822</a></span>
<span class="normal"><a href="#__codelineno-0-823">823</a></span>
<span class="normal"><a href="#__codelineno-0-824">824</a></span>
<span class="normal"><a href="#__codelineno-0-825">825</a></span>
<span class="normal"><a href="#__codelineno-0-826">826</a></span>
<span class="normal"><a href="#__codelineno-0-827">827</a></span>
<span class="normal"><a href="#__codelineno-0-828">828</a></span>
<span class="normal"><a href="#__codelineno-0-829">829</a></span>
<span class="normal"><a href="#__codelineno-0-830">830</a></span>
<span class="normal"><a href="#__codelineno-0-831">831</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-805" name="__codelineno-0-805"></a><span class="nd">@app</span><span class="o">.</span><span class="n">command</span><span class="p">(</span><span class="n">rich_help_panel</span><span class="o">=</span><span class="s2">&quot;Collection&quot;</span><span class="p">)</span>
<a id="__codelineno-0-806" name="__codelineno-0-806"></a><span class="k">def</span><span class="w"> </span><span class="nf">grafana_schema</span><span class="p">(</span><span class="n">ctx</span><span class="p">:</span> <span class="n">typer</span><span class="o">.</span><span class="n">Context</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-807" name="__codelineno-0-807"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Create or refresh Grafana-ready views and indexes in a SQLite database.</span>
<a id="__codelineno-0-808" name="__codelineno-0-808"></a>
<a id="__codelineno-0-809" name="__codelineno-0-809"></a><span class="sd"> Idempotent — safe to run repeatedly on the same database. Requires SQLite</span>
<a id="__codelineno-0-810" name="__codelineno-0-810"></a><span class="sd"> output. Does not connect to MetaTrader 5.</span>
<a id="__codelineno-0-811" name="__codelineno-0-811"></a>
<a id="__codelineno-0-812" name="__codelineno-0-812"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-813" name="__codelineno-0-813"></a><span class="sd"> typer.BadParameter: If the output format is not SQLite3.</span>
<a id="__codelineno-0-814" name="__codelineno-0-814"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-815" name="__codelineno-0-815"></a> <span class="kn">import</span><span class="w"> </span><span class="nn">sqlite3</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">_sqlite3</span> <span class="c1"># noqa: PLC0415</span>
<a id="__codelineno-0-816" name="__codelineno-0-816"></a>
<a id="__codelineno-0-817" name="__codelineno-0-817"></a> <span class="kn">from</span><span class="w"> </span><span class="nn">.grafana</span><span class="w"> </span><span class="kn">import</span> <span class="n">create_snapshot_tables</span><span class="p">,</span> <span class="n">ensure_grafana_schema</span> <span class="c1"># noqa: PLC0415</span>
<a id="__codelineno-0-818" name="__codelineno-0-818"></a>
<a id="__codelineno-0-819" name="__codelineno-0-819"></a> <span class="n">export_ctx</span> <span class="o">=</span> <span class="n">_get_export_context</span><span class="p">(</span><span class="n">ctx</span><span class="p">)</span>
<a id="__codelineno-0-820" name="__codelineno-0-820"></a> <span class="k">if</span> <span class="n">export_ctx</span><span class="o">.</span><span class="n">output_format</span> <span class="o">!=</span> <span class="s2">&quot;sqlite3&quot;</span><span class="p">:</span>
<a id="__codelineno-0-821" name="__codelineno-0-821"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-822" name="__codelineno-0-822"></a> <span class="s2">&quot;grafana-schema requires SQLite3 output.&quot;</span>
<a id="__codelineno-0-823" name="__codelineno-0-823"></a> <span class="s2">&quot; Use a .db/.sqlite/.sqlite3 extension or --format sqlite3.&quot;</span>
<a id="__codelineno-0-824" name="__codelineno-0-824"></a> <span class="p">)</span>
<a id="__codelineno-0-825" name="__codelineno-0-825"></a> <span class="k">raise</span> <span class="n">typer</span><span class="o">.</span><span class="n">BadParameter</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<a id="__codelineno-0-826" name="__codelineno-0-826"></a> <span class="k">with</span> <span class="n">_sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">export_ctx</span><span class="o">.</span><span class="n">output</span><span class="p">)</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span>
<a id="__codelineno-0-827" name="__codelineno-0-827"></a> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&quot;PRAGMA journal_mode=WAL&quot;</span><span class="p">)</span>
<a id="__codelineno-0-828" name="__codelineno-0-828"></a> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&quot;PRAGMA synchronous=NORMAL&quot;</span><span class="p">)</span>
<a id="__codelineno-0-829" name="__codelineno-0-829"></a> <span class="n">create_snapshot_tables</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span>
<a id="__codelineno-0-830" name="__codelineno-0-830"></a> <span class="n">ensure_grafana_schema</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span>
<a id="__codelineno-0-831" name="__codelineno-0-831"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Grafana schema applied to </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">export_ctx</span><span class="o">.</span><span class="n">output</span><span class="p">)</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 id="mt5cli.cli.history_deals" class="doc doc-heading">
<span class="doc doc-object-name doc-function-name">history_deals</span>
@@ -1166,11 +1268,11 @@ views <code>cash_events</code> and <code>positions_reconstructed</code> are deri
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/cli.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-805">805</a></span>
<span class="normal"><a href="#__codelineno-0-806">806</a></span>
<span class="normal"><a href="#__codelineno-0-807">807</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-805" name="__codelineno-0-805"></a><span class="k">def</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-806" name="__codelineno-0-806"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Run the mt5cli CLI.&quot;&quot;&quot;</span>
<a id="__codelineno-0-807" name="__codelineno-0-807"></a> <span class="n">app</span><span class="p">()</span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-899">899</a></span>
<span class="normal"><a href="#__codelineno-0-900">900</a></span>
<span class="normal"><a href="#__codelineno-0-901">901</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-899" name="__codelineno-0-899"></a><span class="k">def</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-900" name="__codelineno-0-900"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Run the mt5cli CLI.&quot;&quot;&quot;</span>
<a id="__codelineno-0-901" name="__codelineno-0-901"></a> <span class="n">app</span><span class="p">()</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
@@ -1979,6 +2081,225 @@ with no additional validation beyond what MT5 itself performs. Use
<div class="doc doc-object doc-function">
<h3 id="mt5cli.cli.snapshot" class="doc doc-heading">
<span class="doc doc-object-name doc-function-name">snapshot</span>
<a href="#mt5cli.cli.snapshot" class="headerlink" title="Permanent link">&para;</a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nf">snapshot</span><span class="p">(</span>
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a> <span class="n">ctx</span><span class="p">:</span> <span class="n"><span title="typer.Context">Context</span></span><span class="p">,</span>
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="n">symbol</span><span class="p">:</span> <span class="n"><span title="typing.Annotated">Annotated</span></span><span class="p">[</span>
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> <span class="n"><span title="list">list</span></span><span class="p">[</span><span class="n"><span title="str">str</span></span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> <span class="n"><span title="typer.Option">Option</span></span><span class="p">(</span>
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a> <span class="s2">&quot;--symbol&quot;</span><span class="p">,</span>
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="s2">&quot;-s&quot;</span><span class="p">,</span>
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="n"><span title="typer.Option(help)">help</span></span><span class="o">=</span><span class="s2">&quot;Symbol filter for positions/orders (repeat for multiple).&quot;</span><span class="p">,</span>
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="p">),</span>
<a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a> <span class="n">with_account</span><span class="p">:</span> <span class="n"><span title="typing.Annotated">Annotated</span></span><span class="p">[</span>
<a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a> <span class="n"><span title="bool">bool</span></span><span class="p">,</span>
<a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a> <span class="n"><span title="typer.Option">Option</span></span><span class="p">(</span>
<a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a> <span class="s2">&quot;--with-account/--no-account&quot;</span><span class="p">,</span>
<a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a> <span class="n"><span title="typer.Option(help)">help</span></span><span class="o">=</span><span class="s2">&quot;Snapshot account info.&quot;</span><span class="p">,</span>
<a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a> <span class="p">),</span>
<a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a> <span class="p">]</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
<a id="__codelineno-0-18" name="__codelineno-0-18" href="#__codelineno-0-18"></a> <span class="n">with_positions</span><span class="p">:</span> <span class="n"><span title="typing.Annotated">Annotated</span></span><span class="p">[</span>
<a id="__codelineno-0-19" name="__codelineno-0-19" href="#__codelineno-0-19"></a> <span class="n"><span title="bool">bool</span></span><span class="p">,</span>
<a id="__codelineno-0-20" name="__codelineno-0-20" href="#__codelineno-0-20"></a> <span class="n"><span title="typer.Option">Option</span></span><span class="p">(</span>
<a id="__codelineno-0-21" name="__codelineno-0-21" href="#__codelineno-0-21"></a> <span class="s2">&quot;--with-positions/--no-positions&quot;</span><span class="p">,</span>
<a id="__codelineno-0-22" name="__codelineno-0-22" href="#__codelineno-0-22"></a> <span class="n"><span title="typer.Option(help)">help</span></span><span class="o">=</span><span class="s2">&quot;Snapshot open positions.&quot;</span><span class="p">,</span>
<a id="__codelineno-0-23" name="__codelineno-0-23" href="#__codelineno-0-23"></a> <span class="p">),</span>
<a id="__codelineno-0-24" name="__codelineno-0-24" href="#__codelineno-0-24"></a> <span class="p">]</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
<a id="__codelineno-0-25" name="__codelineno-0-25" href="#__codelineno-0-25"></a> <span class="n">with_orders</span><span class="p">:</span> <span class="n"><span title="typing.Annotated">Annotated</span></span><span class="p">[</span>
<a id="__codelineno-0-26" name="__codelineno-0-26" href="#__codelineno-0-26"></a> <span class="n"><span title="bool">bool</span></span><span class="p">,</span>
<a id="__codelineno-0-27" name="__codelineno-0-27" href="#__codelineno-0-27"></a> <span class="n"><span title="typer.Option">Option</span></span><span class="p">(</span>
<a id="__codelineno-0-28" name="__codelineno-0-28" href="#__codelineno-0-28"></a> <span class="s2">&quot;--with-orders/--no-orders&quot;</span><span class="p">,</span>
<a id="__codelineno-0-29" name="__codelineno-0-29" href="#__codelineno-0-29"></a> <span class="n"><span title="typer.Option(help)">help</span></span><span class="o">=</span><span class="s2">&quot;Snapshot active orders.&quot;</span><span class="p">,</span>
<a id="__codelineno-0-30" name="__codelineno-0-30" href="#__codelineno-0-30"></a> <span class="p">),</span>
<a id="__codelineno-0-31" name="__codelineno-0-31" href="#__codelineno-0-31"></a> <span class="p">]</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
<a id="__codelineno-0-32" name="__codelineno-0-32" href="#__codelineno-0-32"></a> <span class="n">with_terminal</span><span class="p">:</span> <span class="n"><span title="typing.Annotated">Annotated</span></span><span class="p">[</span>
<a id="__codelineno-0-33" name="__codelineno-0-33" href="#__codelineno-0-33"></a> <span class="n"><span title="bool">bool</span></span><span class="p">,</span>
<a id="__codelineno-0-34" name="__codelineno-0-34" href="#__codelineno-0-34"></a> <span class="n"><span title="typer.Option">Option</span></span><span class="p">(</span>
<a id="__codelineno-0-35" name="__codelineno-0-35" href="#__codelineno-0-35"></a> <span class="s2">&quot;--with-terminal/--no-terminal&quot;</span><span class="p">,</span>
<a id="__codelineno-0-36" name="__codelineno-0-36" href="#__codelineno-0-36"></a> <span class="n"><span title="typer.Option(help)">help</span></span><span class="o">=</span><span class="s2">&quot;Snapshot terminal info.&quot;</span><span class="p">,</span>
<a id="__codelineno-0-37" name="__codelineno-0-37" href="#__codelineno-0-37"></a> <span class="p">),</span>
<a id="__codelineno-0-38" name="__codelineno-0-38" href="#__codelineno-0-38"></a> <span class="p">]</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
<a id="__codelineno-0-39" name="__codelineno-0-39" href="#__codelineno-0-39"></a> <span class="n">with_grafana_schema</span><span class="p">:</span> <span class="n"><span title="typing.Annotated">Annotated</span></span><span class="p">[</span>
<a id="__codelineno-0-40" name="__codelineno-0-40" href="#__codelineno-0-40"></a> <span class="n"><span title="bool">bool</span></span><span class="p">,</span>
<a id="__codelineno-0-41" name="__codelineno-0-41" href="#__codelineno-0-41"></a> <span class="n"><span title="typer.Option">Option</span></span><span class="p">(</span>
<a id="__codelineno-0-42" name="__codelineno-0-42" href="#__codelineno-0-42"></a> <span class="s2">&quot;--with-grafana-schema/--no-grafana-schema&quot;</span><span class="p">,</span>
<a id="__codelineno-0-43" name="__codelineno-0-43" href="#__codelineno-0-43"></a> <span class="n"><span title="typer.Option(help)">help</span></span><span class="o">=</span><span class="s2">&quot;Ensure Grafana views and indexes exist.&quot;</span><span class="p">,</span>
<a id="__codelineno-0-44" name="__codelineno-0-44" href="#__codelineno-0-44"></a> <span class="p">),</span>
<a id="__codelineno-0-45" name="__codelineno-0-45" href="#__codelineno-0-45"></a> <span class="p">]</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
<a id="__codelineno-0-46" name="__codelineno-0-46" href="#__codelineno-0-46"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span>
</code></pre></div>
<div class="doc doc-contents ">
<p>Snapshot current account, position, order, and terminal state into SQLite.</p>
<p>Appends a timestamped snapshot row for each data type. Never places
orders or modifies trading state.</p>
<p><span class="doc-section-title">Raises:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><span title="typer.BadParameter">BadParameter</span></code>
</td>
<td>
<div class="doc-md-description">
<p>If the output format is not SQLite3.</p>
</div>
</td>
</tr>
</tbody>
</table>
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/cli.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-834">834</a></span>
<span class="normal"><a href="#__codelineno-0-835">835</a></span>
<span class="normal"><a href="#__codelineno-0-836">836</a></span>
<span class="normal"><a href="#__codelineno-0-837">837</a></span>
<span class="normal"><a href="#__codelineno-0-838">838</a></span>
<span class="normal"><a href="#__codelineno-0-839">839</a></span>
<span class="normal"><a href="#__codelineno-0-840">840</a></span>
<span class="normal"><a href="#__codelineno-0-841">841</a></span>
<span class="normal"><a href="#__codelineno-0-842">842</a></span>
<span class="normal"><a href="#__codelineno-0-843">843</a></span>
<span class="normal"><a href="#__codelineno-0-844">844</a></span>
<span class="normal"><a href="#__codelineno-0-845">845</a></span>
<span class="normal"><a href="#__codelineno-0-846">846</a></span>
<span class="normal"><a href="#__codelineno-0-847">847</a></span>
<span class="normal"><a href="#__codelineno-0-848">848</a></span>
<span class="normal"><a href="#__codelineno-0-849">849</a></span>
<span class="normal"><a href="#__codelineno-0-850">850</a></span>
<span class="normal"><a href="#__codelineno-0-851">851</a></span>
<span class="normal"><a href="#__codelineno-0-852">852</a></span>
<span class="normal"><a href="#__codelineno-0-853">853</a></span>
<span class="normal"><a href="#__codelineno-0-854">854</a></span>
<span class="normal"><a href="#__codelineno-0-855">855</a></span>
<span class="normal"><a href="#__codelineno-0-856">856</a></span>
<span class="normal"><a href="#__codelineno-0-857">857</a></span>
<span class="normal"><a href="#__codelineno-0-858">858</a></span>
<span class="normal"><a href="#__codelineno-0-859">859</a></span>
<span class="normal"><a href="#__codelineno-0-860">860</a></span>
<span class="normal"><a href="#__codelineno-0-861">861</a></span>
<span class="normal"><a href="#__codelineno-0-862">862</a></span>
<span class="normal"><a href="#__codelineno-0-863">863</a></span>
<span class="normal"><a href="#__codelineno-0-864">864</a></span>
<span class="normal"><a href="#__codelineno-0-865">865</a></span>
<span class="normal"><a href="#__codelineno-0-866">866</a></span>
<span class="normal"><a href="#__codelineno-0-867">867</a></span>
<span class="normal"><a href="#__codelineno-0-868">868</a></span>
<span class="normal"><a href="#__codelineno-0-869">869</a></span>
<span class="normal"><a href="#__codelineno-0-870">870</a></span>
<span class="normal"><a href="#__codelineno-0-871">871</a></span>
<span class="normal"><a href="#__codelineno-0-872">872</a></span>
<span class="normal"><a href="#__codelineno-0-873">873</a></span>
<span class="normal"><a href="#__codelineno-0-874">874</a></span>
<span class="normal"><a href="#__codelineno-0-875">875</a></span>
<span class="normal"><a href="#__codelineno-0-876">876</a></span>
<span class="normal"><a href="#__codelineno-0-877">877</a></span>
<span class="normal"><a href="#__codelineno-0-878">878</a></span>
<span class="normal"><a href="#__codelineno-0-879">879</a></span>
<span class="normal"><a href="#__codelineno-0-880">880</a></span>
<span class="normal"><a href="#__codelineno-0-881">881</a></span>
<span class="normal"><a href="#__codelineno-0-882">882</a></span>
<span class="normal"><a href="#__codelineno-0-883">883</a></span>
<span class="normal"><a href="#__codelineno-0-884">884</a></span>
<span class="normal"><a href="#__codelineno-0-885">885</a></span>
<span class="normal"><a href="#__codelineno-0-886">886</a></span>
<span class="normal"><a href="#__codelineno-0-887">887</a></span>
<span class="normal"><a href="#__codelineno-0-888">888</a></span>
<span class="normal"><a href="#__codelineno-0-889">889</a></span>
<span class="normal"><a href="#__codelineno-0-890">890</a></span>
<span class="normal"><a href="#__codelineno-0-891">891</a></span>
<span class="normal"><a href="#__codelineno-0-892">892</a></span>
<span class="normal"><a href="#__codelineno-0-893">893</a></span>
<span class="normal"><a href="#__codelineno-0-894">894</a></span>
<span class="normal"><a href="#__codelineno-0-895">895</a></span>
<span class="normal"><a href="#__codelineno-0-896">896</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-834" name="__codelineno-0-834"></a><span class="nd">@app</span><span class="o">.</span><span class="n">command</span><span class="p">(</span><span class="n">rich_help_panel</span><span class="o">=</span><span class="s2">&quot;Collection&quot;</span><span class="p">)</span>
<a id="__codelineno-0-835" name="__codelineno-0-835"></a><span class="k">def</span><span class="w"> </span><span class="nf">snapshot</span><span class="p">(</span>
<a id="__codelineno-0-836" name="__codelineno-0-836"></a> <span class="n">ctx</span><span class="p">:</span> <span class="n">typer</span><span class="o">.</span><span class="n">Context</span><span class="p">,</span>
<a id="__codelineno-0-837" name="__codelineno-0-837"></a> <span class="n">symbol</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span>
<a id="__codelineno-0-838" name="__codelineno-0-838"></a> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-839" name="__codelineno-0-839"></a> <span class="n">typer</span><span class="o">.</span><span class="n">Option</span><span class="p">(</span>
<a id="__codelineno-0-840" name="__codelineno-0-840"></a> <span class="s2">&quot;--symbol&quot;</span><span class="p">,</span>
<a id="__codelineno-0-841" name="__codelineno-0-841"></a> <span class="s2">&quot;-s&quot;</span><span class="p">,</span>
<a id="__codelineno-0-842" name="__codelineno-0-842"></a> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;Symbol filter for positions/orders (repeat for multiple).&quot;</span><span class="p">,</span>
<a id="__codelineno-0-843" name="__codelineno-0-843"></a> <span class="p">),</span>
<a id="__codelineno-0-844" name="__codelineno-0-844"></a> <span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-845" name="__codelineno-0-845"></a> <span class="n">with_account</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span>
<a id="__codelineno-0-846" name="__codelineno-0-846"></a> <span class="nb">bool</span><span class="p">,</span>
<a id="__codelineno-0-847" name="__codelineno-0-847"></a> <span class="n">typer</span><span class="o">.</span><span class="n">Option</span><span class="p">(</span><span class="s2">&quot;--with-account/--no-account&quot;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;Snapshot account info.&quot;</span><span class="p">),</span>
<a id="__codelineno-0-848" name="__codelineno-0-848"></a> <span class="p">]</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
<a id="__codelineno-0-849" name="__codelineno-0-849"></a> <span class="n">with_positions</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span>
<a id="__codelineno-0-850" name="__codelineno-0-850"></a> <span class="nb">bool</span><span class="p">,</span>
<a id="__codelineno-0-851" name="__codelineno-0-851"></a> <span class="n">typer</span><span class="o">.</span><span class="n">Option</span><span class="p">(</span>
<a id="__codelineno-0-852" name="__codelineno-0-852"></a> <span class="s2">&quot;--with-positions/--no-positions&quot;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;Snapshot open positions.&quot;</span>
<a id="__codelineno-0-853" name="__codelineno-0-853"></a> <span class="p">),</span>
<a id="__codelineno-0-854" name="__codelineno-0-854"></a> <span class="p">]</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
<a id="__codelineno-0-855" name="__codelineno-0-855"></a> <span class="n">with_orders</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span>
<a id="__codelineno-0-856" name="__codelineno-0-856"></a> <span class="nb">bool</span><span class="p">,</span>
<a id="__codelineno-0-857" name="__codelineno-0-857"></a> <span class="n">typer</span><span class="o">.</span><span class="n">Option</span><span class="p">(</span><span class="s2">&quot;--with-orders/--no-orders&quot;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;Snapshot active orders.&quot;</span><span class="p">),</span>
<a id="__codelineno-0-858" name="__codelineno-0-858"></a> <span class="p">]</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
<a id="__codelineno-0-859" name="__codelineno-0-859"></a> <span class="n">with_terminal</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span>
<a id="__codelineno-0-860" name="__codelineno-0-860"></a> <span class="nb">bool</span><span class="p">,</span>
<a id="__codelineno-0-861" name="__codelineno-0-861"></a> <span class="n">typer</span><span class="o">.</span><span class="n">Option</span><span class="p">(</span><span class="s2">&quot;--with-terminal/--no-terminal&quot;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;Snapshot terminal info.&quot;</span><span class="p">),</span>
<a id="__codelineno-0-862" name="__codelineno-0-862"></a> <span class="p">]</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
<a id="__codelineno-0-863" name="__codelineno-0-863"></a> <span class="n">with_grafana_schema</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span>
<a id="__codelineno-0-864" name="__codelineno-0-864"></a> <span class="nb">bool</span><span class="p">,</span>
<a id="__codelineno-0-865" name="__codelineno-0-865"></a> <span class="n">typer</span><span class="o">.</span><span class="n">Option</span><span class="p">(</span>
<a id="__codelineno-0-866" name="__codelineno-0-866"></a> <span class="s2">&quot;--with-grafana-schema/--no-grafana-schema&quot;</span><span class="p">,</span>
<a id="__codelineno-0-867" name="__codelineno-0-867"></a> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;Ensure Grafana views and indexes exist.&quot;</span><span class="p">,</span>
<a id="__codelineno-0-868" name="__codelineno-0-868"></a> <span class="p">),</span>
<a id="__codelineno-0-869" name="__codelineno-0-869"></a> <span class="p">]</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
<a id="__codelineno-0-870" name="__codelineno-0-870"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-871" name="__codelineno-0-871"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Snapshot current account, position, order, and terminal state into SQLite.</span>
<a id="__codelineno-0-872" name="__codelineno-0-872"></a>
<a id="__codelineno-0-873" name="__codelineno-0-873"></a><span class="sd"> Appends a timestamped snapshot row for each data type. Never places</span>
<a id="__codelineno-0-874" name="__codelineno-0-874"></a><span class="sd"> orders or modifies trading state.</span>
<a id="__codelineno-0-875" name="__codelineno-0-875"></a>
<a id="__codelineno-0-876" name="__codelineno-0-876"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-877" name="__codelineno-0-877"></a><span class="sd"> typer.BadParameter: If the output format is not SQLite3.</span>
<a id="__codelineno-0-878" name="__codelineno-0-878"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-879" name="__codelineno-0-879"></a> <span class="n">export_ctx</span> <span class="o">=</span> <span class="n">_get_export_context</span><span class="p">(</span><span class="n">ctx</span><span class="p">)</span>
<a id="__codelineno-0-880" name="__codelineno-0-880"></a> <span class="k">if</span> <span class="n">export_ctx</span><span class="o">.</span><span class="n">output_format</span> <span class="o">!=</span> <span class="s2">&quot;sqlite3&quot;</span><span class="p">:</span>
<a id="__codelineno-0-881" name="__codelineno-0-881"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-882" name="__codelineno-0-882"></a> <span class="s2">&quot;snapshot requires SQLite3 output.&quot;</span>
<a id="__codelineno-0-883" name="__codelineno-0-883"></a> <span class="s2">&quot; Use a .db/.sqlite/.sqlite3 extension or --format sqlite3.&quot;</span>
<a id="__codelineno-0-884" name="__codelineno-0-884"></a> <span class="p">)</span>
<a id="__codelineno-0-885" name="__codelineno-0-885"></a> <span class="k">raise</span> <span class="n">typer</span><span class="o">.</span><span class="n">BadParameter</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<a id="__codelineno-0-886" name="__codelineno-0-886"></a> <span class="n">sdk</span><span class="o">.</span><span class="n">update_observability_with_config</span><span class="p">(</span>
<a id="__codelineno-0-887" name="__codelineno-0-887"></a> <span class="n">output</span><span class="o">=</span><span class="n">export_ctx</span><span class="o">.</span><span class="n">output</span><span class="p">,</span>
<a id="__codelineno-0-888" name="__codelineno-0-888"></a> <span class="n">config</span><span class="o">=</span><span class="n">export_ctx</span><span class="o">.</span><span class="n">config</span><span class="p">,</span>
<a id="__codelineno-0-889" name="__codelineno-0-889"></a> <span class="n">symbols</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">symbol</span><span class="p">)</span> <span class="k">if</span> <span class="n">symbol</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-890" name="__codelineno-0-890"></a> <span class="n">include_account</span><span class="o">=</span><span class="n">with_account</span><span class="p">,</span>
<a id="__codelineno-0-891" name="__codelineno-0-891"></a> <span class="n">include_positions</span><span class="o">=</span><span class="n">with_positions</span><span class="p">,</span>
<a id="__codelineno-0-892" name="__codelineno-0-892"></a> <span class="n">include_orders</span><span class="o">=</span><span class="n">with_orders</span><span class="p">,</span>
<a id="__codelineno-0-893" name="__codelineno-0-893"></a> <span class="n">include_terminal</span><span class="o">=</span><span class="n">with_terminal</span><span class="p">,</span>
<a id="__codelineno-0-894" name="__codelineno-0-894"></a> <span class="n">with_grafana_schema</span><span class="o">=</span><span class="n">with_grafana_schema</span><span class="p">,</span>
<a id="__codelineno-0-895" name="__codelineno-0-895"></a> <span class="p">)</span>
<a id="__codelineno-0-896" name="__codelineno-0-896"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Snapshot written to </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">export_ctx</span><span class="o">.</span><span class="n">output</span><span class="p">)</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 id="mt5cli.cli.symbol_info" class="doc doc-heading">
<span class="doc doc-object-name doc-function-name">symbol_info</span>
+110 -110
View File
@@ -242,19 +242,7 @@ responsibility of downstream applications.</p>
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/sdk.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-419">419</a></span>
<span class="normal"><a href="#__codelineno-0-420">420</a></span>
<span class="normal"><a href="#__codelineno-0-421">421</a></span>
<span class="normal"><a href="#__codelineno-0-422">422</a></span>
<span class="normal"><a href="#__codelineno-0-423">423</a></span>
<span class="normal"><a href="#__codelineno-0-424">424</a></span>
<span class="normal"><a href="#__codelineno-0-425">425</a></span>
<span class="normal"><a href="#__codelineno-0-426">426</a></span>
<span class="normal"><a href="#__codelineno-0-427">427</a></span>
<span class="normal"><a href="#__codelineno-0-428">428</a></span>
<span class="normal"><a href="#__codelineno-0-429">429</a></span>
<span class="normal"><a href="#__codelineno-0-430">430</a></span>
<span class="normal"><a href="#__codelineno-0-431">431</a></span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-431">431</a></span>
<span class="normal"><a href="#__codelineno-0-432">432</a></span>
<span class="normal"><a href="#__codelineno-0-433">433</a></span>
<span class="normal"><a href="#__codelineno-0-434">434</a></span>
@@ -277,42 +265,54 @@ responsibility of downstream applications.</p>
<span class="normal"><a href="#__codelineno-0-451">451</a></span>
<span class="normal"><a href="#__codelineno-0-452">452</a></span>
<span class="normal"><a href="#__codelineno-0-453">453</a></span>
<span class="normal"><a href="#__codelineno-0-454">454</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-419" name="__codelineno-0-419"></a><span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
<a id="__codelineno-0-420" name="__codelineno-0-420"></a> <span class="bp">self</span><span class="p">,</span>
<a id="__codelineno-0-421" name="__codelineno-0-421"></a> <span class="o">*</span><span class="p">,</span>
<a id="__codelineno-0-422" name="__codelineno-0-422"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-423" name="__codelineno-0-423"></a> <span class="n">login</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-424" name="__codelineno-0-424"></a> <span class="n">password</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-425" name="__codelineno-0-425"></a> <span class="n">server</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-426" name="__codelineno-0-426"></a> <span class="n">timeout</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-427" name="__codelineno-0-427"></a> <span class="n">retry_count</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span>
<a id="__codelineno-0-428" name="__codelineno-0-428"></a> <span class="n">config</span><span class="p">:</span> <span class="n">Mt5Config</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-429" name="__codelineno-0-429"></a> <span class="n">client</span><span class="p">:</span> <span class="n">Mt5DataClient</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-430" name="__codelineno-0-430"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-431" name="__codelineno-0-431"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Initialize the SDK client.</span>
<a id="__codelineno-0-432" name="__codelineno-0-432"></a>
<a id="__codelineno-0-433" name="__codelineno-0-433"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-434" name="__codelineno-0-434"></a><span class="sd"> path: Path to MetaTrader5 terminal EXE file.</span>
<a id="__codelineno-0-435" name="__codelineno-0-435"></a><span class="sd"> login: Trading account login.</span>
<a id="__codelineno-0-436" name="__codelineno-0-436"></a><span class="sd"> password: Trading account password.</span>
<a id="__codelineno-0-437" name="__codelineno-0-437"></a><span class="sd"> server: Trading server name.</span>
<a id="__codelineno-0-438" name="__codelineno-0-438"></a><span class="sd"> timeout: Connection timeout in milliseconds.</span>
<a id="__codelineno-0-439" name="__codelineno-0-439"></a><span class="sd"> retry_count: Number of MT5 initialization retries for sessions</span>
<a id="__codelineno-0-440" name="__codelineno-0-440"></a><span class="sd"> opened by this client.</span>
<a id="__codelineno-0-441" name="__codelineno-0-441"></a><span class="sd"> config: Optional pre-built ``Mt5Config`` (overrides other args).</span>
<a id="__codelineno-0-442" name="__codelineno-0-442"></a><span class="sd"> client: Optional already-connected ``Mt5DataClient``. Injected</span>
<a id="__codelineno-0-443" name="__codelineno-0-443"></a><span class="sd"> clients are reused as-is and are not initialized or shut down.</span>
<a id="__codelineno-0-444" name="__codelineno-0-444"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-445" name="__codelineno-0-445"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_config</span> <span class="o">=</span> <span class="n">config</span> <span class="ow">or</span> <span class="n">build_config</span><span class="p">(</span>
<a id="__codelineno-0-446" name="__codelineno-0-446"></a> <span class="n">path</span><span class="o">=</span><span class="n">path</span><span class="p">,</span>
<a id="__codelineno-0-447" name="__codelineno-0-447"></a> <span class="n">login</span><span class="o">=</span><span class="n">login</span><span class="p">,</span>
<a id="__codelineno-0-448" name="__codelineno-0-448"></a> <span class="n">password</span><span class="o">=</span><span class="n">password</span><span class="p">,</span>
<a id="__codelineno-0-449" name="__codelineno-0-449"></a> <span class="n">server</span><span class="o">=</span><span class="n">server</span><span class="p">,</span>
<a id="__codelineno-0-450" name="__codelineno-0-450"></a> <span class="n">timeout</span><span class="o">=</span><span class="n">timeout</span><span class="p">,</span>
<a id="__codelineno-0-451" name="__codelineno-0-451"></a> <span class="p">)</span>
<a id="__codelineno-0-452" name="__codelineno-0-452"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_retry_count</span> <span class="o">=</span> <span class="n">retry_count</span>
<a id="__codelineno-0-453" name="__codelineno-0-453"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_client</span> <span class="o">=</span> <span class="n">client</span>
<a id="__codelineno-0-454" name="__codelineno-0-454"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_owns_client</span> <span class="o">=</span> <span class="n">client</span> <span class="ow">is</span> <span class="kc">None</span>
<span class="normal"><a href="#__codelineno-0-454">454</a></span>
<span class="normal"><a href="#__codelineno-0-455">455</a></span>
<span class="normal"><a href="#__codelineno-0-456">456</a></span>
<span class="normal"><a href="#__codelineno-0-457">457</a></span>
<span class="normal"><a href="#__codelineno-0-458">458</a></span>
<span class="normal"><a href="#__codelineno-0-459">459</a></span>
<span class="normal"><a href="#__codelineno-0-460">460</a></span>
<span class="normal"><a href="#__codelineno-0-461">461</a></span>
<span class="normal"><a href="#__codelineno-0-462">462</a></span>
<span class="normal"><a href="#__codelineno-0-463">463</a></span>
<span class="normal"><a href="#__codelineno-0-464">464</a></span>
<span class="normal"><a href="#__codelineno-0-465">465</a></span>
<span class="normal"><a href="#__codelineno-0-466">466</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-431" name="__codelineno-0-431"></a><span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
<a id="__codelineno-0-432" name="__codelineno-0-432"></a> <span class="bp">self</span><span class="p">,</span>
<a id="__codelineno-0-433" name="__codelineno-0-433"></a> <span class="o">*</span><span class="p">,</span>
<a id="__codelineno-0-434" name="__codelineno-0-434"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-435" name="__codelineno-0-435"></a> <span class="n">login</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-436" name="__codelineno-0-436"></a> <span class="n">password</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-437" name="__codelineno-0-437"></a> <span class="n">server</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-438" name="__codelineno-0-438"></a> <span class="n">timeout</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-439" name="__codelineno-0-439"></a> <span class="n">retry_count</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span>
<a id="__codelineno-0-440" name="__codelineno-0-440"></a> <span class="n">config</span><span class="p">:</span> <span class="n">Mt5Config</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-441" name="__codelineno-0-441"></a> <span class="n">client</span><span class="p">:</span> <span class="n">Mt5DataClient</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-442" name="__codelineno-0-442"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-443" name="__codelineno-0-443"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Initialize the SDK client.</span>
<a id="__codelineno-0-444" name="__codelineno-0-444"></a>
<a id="__codelineno-0-445" name="__codelineno-0-445"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-446" name="__codelineno-0-446"></a><span class="sd"> path: Path to MetaTrader5 terminal EXE file.</span>
<a id="__codelineno-0-447" name="__codelineno-0-447"></a><span class="sd"> login: Trading account login.</span>
<a id="__codelineno-0-448" name="__codelineno-0-448"></a><span class="sd"> password: Trading account password.</span>
<a id="__codelineno-0-449" name="__codelineno-0-449"></a><span class="sd"> server: Trading server name.</span>
<a id="__codelineno-0-450" name="__codelineno-0-450"></a><span class="sd"> timeout: Connection timeout in milliseconds.</span>
<a id="__codelineno-0-451" name="__codelineno-0-451"></a><span class="sd"> retry_count: Number of MT5 initialization retries for sessions</span>
<a id="__codelineno-0-452" name="__codelineno-0-452"></a><span class="sd"> opened by this client.</span>
<a id="__codelineno-0-453" name="__codelineno-0-453"></a><span class="sd"> config: Optional pre-built ``Mt5Config`` (overrides other args).</span>
<a id="__codelineno-0-454" name="__codelineno-0-454"></a><span class="sd"> client: Optional already-connected ``Mt5DataClient``. Injected</span>
<a id="__codelineno-0-455" name="__codelineno-0-455"></a><span class="sd"> clients are reused as-is and are not initialized or shut down.</span>
<a id="__codelineno-0-456" name="__codelineno-0-456"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-457" name="__codelineno-0-457"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_config</span> <span class="o">=</span> <span class="n">config</span> <span class="ow">or</span> <span class="n">build_config</span><span class="p">(</span>
<a id="__codelineno-0-458" name="__codelineno-0-458"></a> <span class="n">path</span><span class="o">=</span><span class="n">path</span><span class="p">,</span>
<a id="__codelineno-0-459" name="__codelineno-0-459"></a> <span class="n">login</span><span class="o">=</span><span class="n">login</span><span class="p">,</span>
<a id="__codelineno-0-460" name="__codelineno-0-460"></a> <span class="n">password</span><span class="o">=</span><span class="n">password</span><span class="p">,</span>
<a id="__codelineno-0-461" name="__codelineno-0-461"></a> <span class="n">server</span><span class="o">=</span><span class="n">server</span><span class="p">,</span>
<a id="__codelineno-0-462" name="__codelineno-0-462"></a> <span class="n">timeout</span><span class="o">=</span><span class="n">timeout</span><span class="p">,</span>
<a id="__codelineno-0-463" name="__codelineno-0-463"></a> <span class="p">)</span>
<a id="__codelineno-0-464" name="__codelineno-0-464"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_retry_count</span> <span class="o">=</span> <span class="n">retry_count</span>
<a id="__codelineno-0-465" name="__codelineno-0-465"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_client</span> <span class="o">=</span> <span class="n">client</span>
<a id="__codelineno-0-466" name="__codelineno-0-466"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_owns_client</span> <span class="o">=</span> <span class="n">client</span> <span class="ow">is</span> <span class="kc">None</span>
</code></pre></div></td></tr></table></div>
</details>
@@ -789,19 +789,7 @@ to <code>path</code>, <code>login</code>, <code>password</code>, and <code>serve
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/sdk.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-311">311</a></span>
<span class="normal"><a href="#__codelineno-0-312">312</a></span>
<span class="normal"><a href="#__codelineno-0-313">313</a></span>
<span class="normal"><a href="#__codelineno-0-314">314</a></span>
<span class="normal"><a href="#__codelineno-0-315">315</a></span>
<span class="normal"><a href="#__codelineno-0-316">316</a></span>
<span class="normal"><a href="#__codelineno-0-317">317</a></span>
<span class="normal"><a href="#__codelineno-0-318">318</a></span>
<span class="normal"><a href="#__codelineno-0-319">319</a></span>
<span class="normal"><a href="#__codelineno-0-320">320</a></span>
<span class="normal"><a href="#__codelineno-0-321">321</a></span>
<span class="normal"><a href="#__codelineno-0-322">322</a></span>
<span class="normal"><a href="#__codelineno-0-323">323</a></span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-323">323</a></span>
<span class="normal"><a href="#__codelineno-0-324">324</a></span>
<span class="normal"><a href="#__codelineno-0-325">325</a></span>
<span class="normal"><a href="#__codelineno-0-326">326</a></span>
@@ -836,54 +824,66 @@ to <code>path</code>, <code>login</code>, <code>password</code>, and <code>serve
<span class="normal"><a href="#__codelineno-0-355">355</a></span>
<span class="normal"><a href="#__codelineno-0-356">356</a></span>
<span class="normal"><a href="#__codelineno-0-357">357</a></span>
<span class="normal"><a href="#__codelineno-0-358">358</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-311" name="__codelineno-0-311"></a><span class="k">def</span><span class="w"> </span><span class="nf">build_config</span><span class="p">(</span>
<a id="__codelineno-0-312" name="__codelineno-0-312"></a> <span class="o">*</span><span class="p">,</span>
<a id="__codelineno-0-313" name="__codelineno-0-313"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-314" name="__codelineno-0-314"></a> <span class="n">login</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-315" name="__codelineno-0-315"></a> <span class="n">password</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-316" name="__codelineno-0-316"></a> <span class="n">server</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-317" name="__codelineno-0-317"></a> <span class="n">timeout</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-318" name="__codelineno-0-318"></a> <span class="n">allow_whole_dollar_env</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
<a id="__codelineno-0-319" name="__codelineno-0-319"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Mt5Config</span><span class="p">:</span>
<a id="__codelineno-0-320" name="__codelineno-0-320"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Build an ``Mt5Config`` from optional connection parameters.</span>
<a id="__codelineno-0-321" name="__codelineno-0-321"></a>
<a id="__codelineno-0-322" name="__codelineno-0-322"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-323" name="__codelineno-0-323"></a><span class="sd"> path: Optional terminal executable path.</span>
<a id="__codelineno-0-324" name="__codelineno-0-324"></a><span class="sd"> login: Optional trading account login. Integers are preserved. String</span>
<a id="__codelineno-0-325" name="__codelineno-0-325"></a><span class="sd"> values are coerced: empty or whitespace-only strings become</span>
<a id="__codelineno-0-326" name="__codelineno-0-326"></a><span class="sd"> ``None``; numeric strings such as ``&quot;12345&quot;`` are converted to</span>
<a id="__codelineno-0-327" name="__codelineno-0-327"></a><span class="sd"> ``int``; non-numeric strings raise ``ValueError``. When</span>
<a id="__codelineno-0-328" name="__codelineno-0-328"></a><span class="sd"> ``allow_whole_dollar_env=True``, ``$ENV_NAME`` and</span>
<a id="__codelineno-0-329" name="__codelineno-0-329"></a><span class="sd"> ``${ENV_NAME}`` placeholders are expanded before coercion.</span>
<a id="__codelineno-0-330" name="__codelineno-0-330"></a><span class="sd"> password: Optional trading account password.</span>
<a id="__codelineno-0-331" name="__codelineno-0-331"></a><span class="sd"> server: Optional trading server name.</span>
<a id="__codelineno-0-332" name="__codelineno-0-332"></a><span class="sd"> timeout: Optional connection timeout in milliseconds.</span>
<a id="__codelineno-0-333" name="__codelineno-0-333"></a><span class="sd"> allow_whole_dollar_env: When ``True``, string parameters that are</span>
<a id="__codelineno-0-334" name="__codelineno-0-334"></a><span class="sd"> exactly ``$ENV_NAME`` are expanded from the environment. Applies</span>
<a id="__codelineno-0-335" name="__codelineno-0-335"></a><span class="sd"> to ``path``, ``login``, ``password``, and ``server``. Default</span>
<a id="__codelineno-0-336" name="__codelineno-0-336"></a><span class="sd"> ``False`` preserves existing behavior.</span>
<a id="__codelineno-0-337" name="__codelineno-0-337"></a>
<a id="__codelineno-0-338" name="__codelineno-0-338"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-339" name="__codelineno-0-339"></a><span class="sd"> Configured ``Mt5Config`` instance.</span>
<a id="__codelineno-0-340" name="__codelineno-0-340"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-341" name="__codelineno-0-341"></a> <span class="k">if</span> <span class="n">allow_whole_dollar_env</span><span class="p">:</span>
<a id="__codelineno-0-342" name="__codelineno-0-342"></a> <span class="k">if</span> <span class="n">path</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-343" name="__codelineno-0-343"></a> <span class="n">path</span> <span class="o">=</span> <span class="n">substitute_env_placeholders</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">allow_whole_dollar_env</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<a id="__codelineno-0-344" name="__codelineno-0-344"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">login</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<a id="__codelineno-0-345" name="__codelineno-0-345"></a> <span class="n">login</span> <span class="o">=</span> <span class="n">substitute_env_placeholders</span><span class="p">(</span><span class="n">login</span><span class="p">,</span> <span class="n">allow_whole_dollar_env</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<a id="__codelineno-0-346" name="__codelineno-0-346"></a> <span class="k">if</span> <span class="n">password</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-347" name="__codelineno-0-347"></a> <span class="n">password</span> <span class="o">=</span> <span class="n">substitute_env_placeholders</span><span class="p">(</span>
<a id="__codelineno-0-348" name="__codelineno-0-348"></a> <span class="n">password</span><span class="p">,</span> <span class="n">allow_whole_dollar_env</span><span class="o">=</span><span class="kc">True</span>
<a id="__codelineno-0-349" name="__codelineno-0-349"></a> <span class="p">)</span>
<a id="__codelineno-0-350" name="__codelineno-0-350"></a> <span class="k">if</span> <span class="n">server</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-351" name="__codelineno-0-351"></a> <span class="n">server</span> <span class="o">=</span> <span class="n">substitute_env_placeholders</span><span class="p">(</span><span class="n">server</span><span class="p">,</span> <span class="n">allow_whole_dollar_env</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<a id="__codelineno-0-352" name="__codelineno-0-352"></a> <span class="k">return</span> <span class="n">Mt5Config</span><span class="p">(</span>
<a id="__codelineno-0-353" name="__codelineno-0-353"></a> <span class="n">path</span><span class="o">=</span><span class="n">path</span><span class="p">,</span>
<a id="__codelineno-0-354" name="__codelineno-0-354"></a> <span class="n">login</span><span class="o">=</span><span class="n">_coerce_login</span><span class="p">(</span><span class="n">login</span><span class="p">),</span>
<a id="__codelineno-0-355" name="__codelineno-0-355"></a> <span class="n">password</span><span class="o">=</span><span class="n">password</span><span class="p">,</span>
<a id="__codelineno-0-356" name="__codelineno-0-356"></a> <span class="n">server</span><span class="o">=</span><span class="n">server</span><span class="p">,</span>
<a id="__codelineno-0-357" name="__codelineno-0-357"></a> <span class="n">timeout</span><span class="o">=</span><span class="n">timeout</span><span class="p">,</span>
<a id="__codelineno-0-358" name="__codelineno-0-358"></a> <span class="p">)</span>
<span class="normal"><a href="#__codelineno-0-358">358</a></span>
<span class="normal"><a href="#__codelineno-0-359">359</a></span>
<span class="normal"><a href="#__codelineno-0-360">360</a></span>
<span class="normal"><a href="#__codelineno-0-361">361</a></span>
<span class="normal"><a href="#__codelineno-0-362">362</a></span>
<span class="normal"><a href="#__codelineno-0-363">363</a></span>
<span class="normal"><a href="#__codelineno-0-364">364</a></span>
<span class="normal"><a href="#__codelineno-0-365">365</a></span>
<span class="normal"><a href="#__codelineno-0-366">366</a></span>
<span class="normal"><a href="#__codelineno-0-367">367</a></span>
<span class="normal"><a href="#__codelineno-0-368">368</a></span>
<span class="normal"><a href="#__codelineno-0-369">369</a></span>
<span class="normal"><a href="#__codelineno-0-370">370</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-323" name="__codelineno-0-323"></a><span class="k">def</span><span class="w"> </span><span class="nf">build_config</span><span class="p">(</span>
<a id="__codelineno-0-324" name="__codelineno-0-324"></a> <span class="o">*</span><span class="p">,</span>
<a id="__codelineno-0-325" name="__codelineno-0-325"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-326" name="__codelineno-0-326"></a> <span class="n">login</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-327" name="__codelineno-0-327"></a> <span class="n">password</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-328" name="__codelineno-0-328"></a> <span class="n">server</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-329" name="__codelineno-0-329"></a> <span class="n">timeout</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-330" name="__codelineno-0-330"></a> <span class="n">allow_whole_dollar_env</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
<a id="__codelineno-0-331" name="__codelineno-0-331"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Mt5Config</span><span class="p">:</span>
<a id="__codelineno-0-332" name="__codelineno-0-332"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Build an ``Mt5Config`` from optional connection parameters.</span>
<a id="__codelineno-0-333" name="__codelineno-0-333"></a>
<a id="__codelineno-0-334" name="__codelineno-0-334"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-335" name="__codelineno-0-335"></a><span class="sd"> path: Optional terminal executable path.</span>
<a id="__codelineno-0-336" name="__codelineno-0-336"></a><span class="sd"> login: Optional trading account login. Integers are preserved. String</span>
<a id="__codelineno-0-337" name="__codelineno-0-337"></a><span class="sd"> values are coerced: empty or whitespace-only strings become</span>
<a id="__codelineno-0-338" name="__codelineno-0-338"></a><span class="sd"> ``None``; numeric strings such as ``&quot;12345&quot;`` are converted to</span>
<a id="__codelineno-0-339" name="__codelineno-0-339"></a><span class="sd"> ``int``; non-numeric strings raise ``ValueError``. When</span>
<a id="__codelineno-0-340" name="__codelineno-0-340"></a><span class="sd"> ``allow_whole_dollar_env=True``, ``$ENV_NAME`` and</span>
<a id="__codelineno-0-341" name="__codelineno-0-341"></a><span class="sd"> ``${ENV_NAME}`` placeholders are expanded before coercion.</span>
<a id="__codelineno-0-342" name="__codelineno-0-342"></a><span class="sd"> password: Optional trading account password.</span>
<a id="__codelineno-0-343" name="__codelineno-0-343"></a><span class="sd"> server: Optional trading server name.</span>
<a id="__codelineno-0-344" name="__codelineno-0-344"></a><span class="sd"> timeout: Optional connection timeout in milliseconds.</span>
<a id="__codelineno-0-345" name="__codelineno-0-345"></a><span class="sd"> allow_whole_dollar_env: When ``True``, string parameters that are</span>
<a id="__codelineno-0-346" name="__codelineno-0-346"></a><span class="sd"> exactly ``$ENV_NAME`` are expanded from the environment. Applies</span>
<a id="__codelineno-0-347" name="__codelineno-0-347"></a><span class="sd"> to ``path``, ``login``, ``password``, and ``server``. Default</span>
<a id="__codelineno-0-348" name="__codelineno-0-348"></a><span class="sd"> ``False`` preserves existing behavior.</span>
<a id="__codelineno-0-349" name="__codelineno-0-349"></a>
<a id="__codelineno-0-350" name="__codelineno-0-350"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-351" name="__codelineno-0-351"></a><span class="sd"> Configured ``Mt5Config`` instance.</span>
<a id="__codelineno-0-352" name="__codelineno-0-352"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-353" name="__codelineno-0-353"></a> <span class="k">if</span> <span class="n">allow_whole_dollar_env</span><span class="p">:</span>
<a id="__codelineno-0-354" name="__codelineno-0-354"></a> <span class="k">if</span> <span class="n">path</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-355" name="__codelineno-0-355"></a> <span class="n">path</span> <span class="o">=</span> <span class="n">substitute_env_placeholders</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">allow_whole_dollar_env</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<a id="__codelineno-0-356" name="__codelineno-0-356"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">login</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<a id="__codelineno-0-357" name="__codelineno-0-357"></a> <span class="n">login</span> <span class="o">=</span> <span class="n">substitute_env_placeholders</span><span class="p">(</span><span class="n">login</span><span class="p">,</span> <span class="n">allow_whole_dollar_env</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<a id="__codelineno-0-358" name="__codelineno-0-358"></a> <span class="k">if</span> <span class="n">password</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-359" name="__codelineno-0-359"></a> <span class="n">password</span> <span class="o">=</span> <span class="n">substitute_env_placeholders</span><span class="p">(</span>
<a id="__codelineno-0-360" name="__codelineno-0-360"></a> <span class="n">password</span><span class="p">,</span> <span class="n">allow_whole_dollar_env</span><span class="o">=</span><span class="kc">True</span>
<a id="__codelineno-0-361" name="__codelineno-0-361"></a> <span class="p">)</span>
<a id="__codelineno-0-362" name="__codelineno-0-362"></a> <span class="k">if</span> <span class="n">server</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-363" name="__codelineno-0-363"></a> <span class="n">server</span> <span class="o">=</span> <span class="n">substitute_env_placeholders</span><span class="p">(</span><span class="n">server</span><span class="p">,</span> <span class="n">allow_whole_dollar_env</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<a id="__codelineno-0-364" name="__codelineno-0-364"></a> <span class="k">return</span> <span class="n">Mt5Config</span><span class="p">(</span>
<a id="__codelineno-0-365" name="__codelineno-0-365"></a> <span class="n">path</span><span class="o">=</span><span class="n">path</span><span class="p">,</span>
<a id="__codelineno-0-366" name="__codelineno-0-366"></a> <span class="n">login</span><span class="o">=</span><span class="n">_coerce_login</span><span class="p">(</span><span class="n">login</span><span class="p">),</span>
<a id="__codelineno-0-367" name="__codelineno-0-367"></a> <span class="n">password</span><span class="o">=</span><span class="n">password</span><span class="p">,</span>
<a id="__codelineno-0-368" name="__codelineno-0-368"></a> <span class="n">server</span><span class="o">=</span><span class="n">server</span><span class="p">,</span>
<a id="__codelineno-0-369" name="__codelineno-0-369"></a> <span class="n">timeout</span><span class="o">=</span><span class="n">timeout</span><span class="p">,</span>
<a id="__codelineno-0-370" name="__codelineno-0-370"></a> <span class="p">)</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
+71 -71
View File
@@ -938,8 +938,7 @@ suffixes (for example <code>XAUUSDm</code>, <code>US500.cash</code>, or <code>EU
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/utils.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-350">350</a></span>
<span class="normal"><a href="#__codelineno-0-351">351</a></span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-351">351</a></span>
<span class="normal"><a href="#__codelineno-0-352">352</a></span>
<span class="normal"><a href="#__codelineno-0-353">353</a></span>
<span class="normal"><a href="#__codelineno-0-354">354</a></span>
@@ -958,27 +957,28 @@ suffixes (for example <code>XAUUSDm</code>, <code>US500.cash</code>, or <code>EU
<span class="normal"><a href="#__codelineno-0-367">367</a></span>
<span class="normal"><a href="#__codelineno-0-368">368</a></span>
<span class="normal"><a href="#__codelineno-0-369">369</a></span>
<span class="normal"><a href="#__codelineno-0-370">370</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-350" name="__codelineno-0-350"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_datetime</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">datetime</span><span class="p">:</span>
<a id="__codelineno-0-351" name="__codelineno-0-351"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse an ISO 8601 datetime string to a timezone-aware datetime.</span>
<a id="__codelineno-0-352" name="__codelineno-0-352"></a>
<a id="__codelineno-0-353" name="__codelineno-0-353"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-354" name="__codelineno-0-354"></a><span class="sd"> value: ISO 8601 datetime string (e.g., &#39;2024-01-01&#39; or</span>
<a id="__codelineno-0-355" name="__codelineno-0-355"></a><span class="sd"> &#39;2024-01-01T12:00:00+00:00&#39;).</span>
<a id="__codelineno-0-356" name="__codelineno-0-356"></a>
<a id="__codelineno-0-357" name="__codelineno-0-357"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-358" name="__codelineno-0-358"></a><span class="sd"> Parsed datetime with UTC timezone if no timezone is specified.</span>
<a id="__codelineno-0-359" name="__codelineno-0-359"></a>
<a id="__codelineno-0-360" name="__codelineno-0-360"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-361" name="__codelineno-0-361"></a><span class="sd"> ValueError: If the string cannot be parsed.</span>
<a id="__codelineno-0-362" name="__codelineno-0-362"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-363" name="__codelineno-0-363"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-364" name="__codelineno-0-364"></a> <span class="n">dt</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-365" name="__codelineno-0-365"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<a id="__codelineno-0-366" name="__codelineno-0-366"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Invalid datetime format: &#39;</span><span class="si">{</span><span class="n">value</span><span class="si">}</span><span class="s2">&#39;. Use ISO 8601 format.&quot;</span>
<a id="__codelineno-0-367" name="__codelineno-0-367"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
<a id="__codelineno-0-368" name="__codelineno-0-368"></a> <span class="k">if</span> <span class="n">dt</span><span class="o">.</span><span class="n">tzinfo</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-369" name="__codelineno-0-369"></a> <span class="n">dt</span> <span class="o">=</span> <span class="n">dt</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">tzinfo</span><span class="o">=</span><span class="n">UTC</span><span class="p">)</span>
<a id="__codelineno-0-370" name="__codelineno-0-370"></a> <span class="k">return</span> <span class="n">dt</span>
<span class="normal"><a href="#__codelineno-0-370">370</a></span>
<span class="normal"><a href="#__codelineno-0-371">371</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-351" name="__codelineno-0-351"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_datetime</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">datetime</span><span class="p">:</span>
<a id="__codelineno-0-352" name="__codelineno-0-352"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse an ISO 8601 datetime string to a timezone-aware datetime.</span>
<a id="__codelineno-0-353" name="__codelineno-0-353"></a>
<a id="__codelineno-0-354" name="__codelineno-0-354"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-355" name="__codelineno-0-355"></a><span class="sd"> value: ISO 8601 datetime string (e.g., &#39;2024-01-01&#39; or</span>
<a id="__codelineno-0-356" name="__codelineno-0-356"></a><span class="sd"> &#39;2024-01-01T12:00:00+00:00&#39;).</span>
<a id="__codelineno-0-357" name="__codelineno-0-357"></a>
<a id="__codelineno-0-358" name="__codelineno-0-358"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-359" name="__codelineno-0-359"></a><span class="sd"> Parsed datetime with UTC timezone if no timezone is specified.</span>
<a id="__codelineno-0-360" name="__codelineno-0-360"></a>
<a id="__codelineno-0-361" name="__codelineno-0-361"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-362" name="__codelineno-0-362"></a><span class="sd"> ValueError: If the string cannot be parsed.</span>
<a id="__codelineno-0-363" name="__codelineno-0-363"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-364" name="__codelineno-0-364"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-365" name="__codelineno-0-365"></a> <span class="n">dt</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-366" name="__codelineno-0-366"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<a id="__codelineno-0-367" name="__codelineno-0-367"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Invalid datetime format: &#39;</span><span class="si">{</span><span class="n">value</span><span class="si">}</span><span class="s2">&#39;. Use ISO 8601 format.&quot;</span>
<a id="__codelineno-0-368" name="__codelineno-0-368"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
<a id="__codelineno-0-369" name="__codelineno-0-369"></a> <span class="k">if</span> <span class="n">dt</span><span class="o">.</span><span class="n">tzinfo</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-370" name="__codelineno-0-370"></a> <span class="n">dt</span> <span class="o">=</span> <span class="n">dt</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">tzinfo</span><span class="o">=</span><span class="n">UTC</span><span class="p">)</span>
<a id="__codelineno-0-371" name="__codelineno-0-371"></a> <span class="k">return</span> <span class="n">dt</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
@@ -1080,8 +1080,7 @@ suffixes (for example <code>XAUUSDm</code>, <code>US500.cash</code>, or <code>EU
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/utils.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-397">397</a></span>
<span class="normal"><a href="#__codelineno-0-398">398</a></span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-398">398</a></span>
<span class="normal"><a href="#__codelineno-0-399">399</a></span>
<span class="normal"><a href="#__codelineno-0-400">400</a></span>
<span class="normal"><a href="#__codelineno-0-401">401</a></span>
@@ -1101,28 +1100,29 @@ suffixes (for example <code>XAUUSDm</code>, <code>US500.cash</code>, or <code>EU
<span class="normal"><a href="#__codelineno-0-415">415</a></span>
<span class="normal"><a href="#__codelineno-0-416">416</a></span>
<span class="normal"><a href="#__codelineno-0-417">417</a></span>
<span class="normal"><a href="#__codelineno-0-418">418</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-397" name="__codelineno-0-397"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_tick_flags</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">object</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-0-398" name="__codelineno-0-398"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse tick flags string or integer value.</span>
<a id="__codelineno-0-399" name="__codelineno-0-399"></a>
<a id="__codelineno-0-400" name="__codelineno-0-400"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-401" name="__codelineno-0-401"></a><span class="sd"> value: Tick flag name (ALL, INFO, TRADE, COPY_TICKS_*) or integer value.</span>
<a id="__codelineno-0-402" name="__codelineno-0-402"></a>
<a id="__codelineno-0-403" name="__codelineno-0-403"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-404" name="__codelineno-0-404"></a><span class="sd"> Integer tick flag value compatible with MetaTrader 5 ``COPY_TICKS_*``.</span>
<a id="__codelineno-0-405" name="__codelineno-0-405"></a>
<a id="__codelineno-0-406" name="__codelineno-0-406"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-407" name="__codelineno-0-407"></a><span class="sd"> ValueError: If the flag is invalid.</span>
<a id="__codelineno-0-408" name="__codelineno-0-408"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-409" name="__codelineno-0-409"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-410" name="__codelineno-0-410"></a> <span class="k">return</span> <span class="n">_parse_copy_ticks</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-411" name="__codelineno-0-411"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<a id="__codelineno-0-412" name="__codelineno-0-412"></a> <span class="n">display</span> <span class="o">=</span> <span class="n">value</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="nb">repr</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-413" name="__codelineno-0-413"></a> <span class="n">valid</span> <span class="o">=</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">_TICK_FLAG_NAMES</span><span class="p">)</span>
<a id="__codelineno-0-414" name="__codelineno-0-414"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-415" name="__codelineno-0-415"></a> <span class="sa">f</span><span class="s2">&quot;Invalid tick flags: &#39;</span><span class="si">{</span><span class="n">display</span><span class="si">}</span><span class="s2">&#39;. &quot;</span>
<a id="__codelineno-0-416" name="__codelineno-0-416"></a> <span class="sa">f</span><span class="s2">&quot;Use one of: </span><span class="si">{</span><span class="n">valid</span><span class="si">}</span><span class="s2">, or a supported integer.&quot;</span>
<a id="__codelineno-0-417" name="__codelineno-0-417"></a> <span class="p">)</span>
<a id="__codelineno-0-418" name="__codelineno-0-418"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
<span class="normal"><a href="#__codelineno-0-418">418</a></span>
<span class="normal"><a href="#__codelineno-0-419">419</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-398" name="__codelineno-0-398"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_tick_flags</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">object</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-0-399" name="__codelineno-0-399"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse tick flags string or integer value.</span>
<a id="__codelineno-0-400" name="__codelineno-0-400"></a>
<a id="__codelineno-0-401" name="__codelineno-0-401"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-402" name="__codelineno-0-402"></a><span class="sd"> value: Tick flag name (ALL, INFO, TRADE, COPY_TICKS_*) or integer value.</span>
<a id="__codelineno-0-403" name="__codelineno-0-403"></a>
<a id="__codelineno-0-404" name="__codelineno-0-404"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-405" name="__codelineno-0-405"></a><span class="sd"> Integer tick flag value compatible with MetaTrader 5 ``COPY_TICKS_*``.</span>
<a id="__codelineno-0-406" name="__codelineno-0-406"></a>
<a id="__codelineno-0-407" name="__codelineno-0-407"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-408" name="__codelineno-0-408"></a><span class="sd"> ValueError: If the flag is invalid.</span>
<a id="__codelineno-0-409" name="__codelineno-0-409"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-410" name="__codelineno-0-410"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-411" name="__codelineno-0-411"></a> <span class="k">return</span> <span class="n">_parse_copy_ticks</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-412" name="__codelineno-0-412"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<a id="__codelineno-0-413" name="__codelineno-0-413"></a> <span class="n">display</span> <span class="o">=</span> <span class="n">value</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="nb">repr</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-414" name="__codelineno-0-414"></a> <span class="n">valid</span> <span class="o">=</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">_TICK_FLAG_NAMES</span><span class="p">)</span>
<a id="__codelineno-0-415" name="__codelineno-0-415"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-416" name="__codelineno-0-416"></a> <span class="sa">f</span><span class="s2">&quot;Invalid tick flags: &#39;</span><span class="si">{</span><span class="n">display</span><span class="si">}</span><span class="s2">&#39;. &quot;</span>
<a id="__codelineno-0-417" name="__codelineno-0-417"></a> <span class="sa">f</span><span class="s2">&quot;Use one of: </span><span class="si">{</span><span class="n">valid</span><span class="si">}</span><span class="s2">, or a supported integer.&quot;</span>
<a id="__codelineno-0-418" name="__codelineno-0-418"></a> <span class="p">)</span>
<a id="__codelineno-0-419" name="__codelineno-0-419"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
@@ -1224,8 +1224,7 @@ suffixes (for example <code>XAUUSDm</code>, <code>US500.cash</code>, or <code>EU
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/utils.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-373">373</a></span>
<span class="normal"><a href="#__codelineno-0-374">374</a></span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-374">374</a></span>
<span class="normal"><a href="#__codelineno-0-375">375</a></span>
<span class="normal"><a href="#__codelineno-0-376">376</a></span>
<span class="normal"><a href="#__codelineno-0-377">377</a></span>
@@ -1245,28 +1244,29 @@ suffixes (for example <code>XAUUSDm</code>, <code>US500.cash</code>, or <code>EU
<span class="normal"><a href="#__codelineno-0-391">391</a></span>
<span class="normal"><a href="#__codelineno-0-392">392</a></span>
<span class="normal"><a href="#__codelineno-0-393">393</a></span>
<span class="normal"><a href="#__codelineno-0-394">394</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-373" name="__codelineno-0-373"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_timeframe</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">object</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-0-374" name="__codelineno-0-374"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse a timeframe string or integer value.</span>
<a id="__codelineno-0-375" name="__codelineno-0-375"></a>
<a id="__codelineno-0-376" name="__codelineno-0-376"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-377" name="__codelineno-0-377"></a><span class="sd"> value: Timeframe name (e.g., &#39;M1&#39;, &#39;H1&#39;, &#39;D1&#39;) or integer value.</span>
<a id="__codelineno-0-378" name="__codelineno-0-378"></a>
<a id="__codelineno-0-379" name="__codelineno-0-379"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-380" name="__codelineno-0-380"></a><span class="sd"> Integer timeframe value.</span>
<a id="__codelineno-0-381" name="__codelineno-0-381"></a>
<a id="__codelineno-0-382" name="__codelineno-0-382"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-383" name="__codelineno-0-383"></a><span class="sd"> ValueError: If the timeframe is invalid.</span>
<a id="__codelineno-0-384" name="__codelineno-0-384"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-385" name="__codelineno-0-385"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-386" name="__codelineno-0-386"></a> <span class="k">return</span> <span class="n">_parse_timeframe</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-387" name="__codelineno-0-387"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<a id="__codelineno-0-388" name="__codelineno-0-388"></a> <span class="n">display</span> <span class="o">=</span> <span class="n">value</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="nb">repr</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-389" name="__codelineno-0-389"></a> <span class="n">valid</span> <span class="o">=</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">TIMEFRAME_NAMES</span><span class="p">)</span>
<a id="__codelineno-0-390" name="__codelineno-0-390"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-391" name="__codelineno-0-391"></a> <span class="sa">f</span><span class="s2">&quot;Invalid timeframe: &#39;</span><span class="si">{</span><span class="n">display</span><span class="si">}</span><span class="s2">&#39;. &quot;</span>
<a id="__codelineno-0-392" name="__codelineno-0-392"></a> <span class="sa">f</span><span class="s2">&quot;Use one of: </span><span class="si">{</span><span class="n">valid</span><span class="si">}</span><span class="s2">, or a supported integer.&quot;</span>
<a id="__codelineno-0-393" name="__codelineno-0-393"></a> <span class="p">)</span>
<a id="__codelineno-0-394" name="__codelineno-0-394"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
<span class="normal"><a href="#__codelineno-0-394">394</a></span>
<span class="normal"><a href="#__codelineno-0-395">395</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-374" name="__codelineno-0-374"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_timeframe</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">object</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-0-375" name="__codelineno-0-375"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse a timeframe string or integer value.</span>
<a id="__codelineno-0-376" name="__codelineno-0-376"></a>
<a id="__codelineno-0-377" name="__codelineno-0-377"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-378" name="__codelineno-0-378"></a><span class="sd"> value: Timeframe name (e.g., &#39;M1&#39;, &#39;H1&#39;, &#39;D1&#39;) or integer value.</span>
<a id="__codelineno-0-379" name="__codelineno-0-379"></a>
<a id="__codelineno-0-380" name="__codelineno-0-380"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-381" name="__codelineno-0-381"></a><span class="sd"> Integer timeframe value.</span>
<a id="__codelineno-0-382" name="__codelineno-0-382"></a>
<a id="__codelineno-0-383" name="__codelineno-0-383"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-384" name="__codelineno-0-384"></a><span class="sd"> ValueError: If the timeframe is invalid.</span>
<a id="__codelineno-0-385" name="__codelineno-0-385"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-386" name="__codelineno-0-386"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-387" name="__codelineno-0-387"></a> <span class="k">return</span> <span class="n">_parse_timeframe</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-388" name="__codelineno-0-388"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<a id="__codelineno-0-389" name="__codelineno-0-389"></a> <span class="n">display</span> <span class="o">=</span> <span class="n">value</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="nb">repr</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-390" name="__codelineno-0-390"></a> <span class="n">valid</span> <span class="o">=</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">TIMEFRAME_NAMES</span><span class="p">)</span>
<a id="__codelineno-0-391" name="__codelineno-0-391"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-392" name="__codelineno-0-392"></a> <span class="sa">f</span><span class="s2">&quot;Invalid timeframe: &#39;</span><span class="si">{</span><span class="n">display</span><span class="si">}</span><span class="s2">&#39;. &quot;</span>
<a id="__codelineno-0-393" name="__codelineno-0-393"></a> <span class="sa">f</span><span class="s2">&quot;Use one of: </span><span class="si">{</span><span class="n">valid</span><span class="si">}</span><span class="s2">, or a supported integer.&quot;</span>
<a id="__codelineno-0-394" name="__codelineno-0-394"></a> <span class="p">)</span>
<a id="__codelineno-0-395" name="__codelineno-0-395"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
+149
View File
@@ -422,6 +422,144 @@ after price movement and does not inspect <code>trade_freeze_level</code>. Live
sending requests. Failed, malformed, or unknown broker retcodes are fail-closed
and returned as <code>status="failed"</code> with normalized <code>request</code> / <code>response</code> details;
<code>dry_run=True</code> never calls <code>ensure_symbol_selected()</code> or <code>order_send()</code>.</p>
<h3 id="grafana-observability-sqlite-read-model">Grafana observability (SQLite read model)<a class="headerlink" href="#grafana-observability-sqlite-read-model" title="Permanent link">&para;</a></h3>
<p>These helpers prepare a SQLite database as a Grafana datasource. All DDL is
idempotent (<code>CREATE TABLE IF NOT EXISTS</code>, <code>DROP VIEW IF EXISTS</code> + <code>CREATE
VIEW</code>, <code>CREATE INDEX IF NOT EXISTS</code>). Missing source tables are skipped with a
warning rather than raising an error.</p>
<table>
<thead>
<tr>
<th>Symbol</th>
<th>Role</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>update_observability</code></td>
<td>Append one timestamped snapshot row per data type; accepts an already-connected <code>Mt5DataClient</code></td>
</tr>
<tr>
<td><code>update_observability_with_config</code></td>
<td>Standalone wrapper: opens/closes MT5 connection automatically around <code>update_observability</code></td>
</tr>
</tbody>
</table>
<p>Both functions write to the SQLite path given by <code>output=</code>. The optional
<code>symbols</code> parameter filters <code>positions_get</code> / <code>orders_get</code> by symbol.
<code>with_grafana_schema=False</code> (default) skips Grafana view/index setup; run
<code>grafana-schema</code> once to set up the schema, then call <code>snapshot</code> repeatedly
without this flag.</p>
<p><strong>Snapshot tables</strong> (created by <code>create_snapshot_tables</code> in <code>mt5cli.grafana</code>):</p>
<table>
<thead>
<tr>
<th>Table</th>
<th>Content</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>account_snapshots</code></td>
<td>Balance, equity, margin, free-margin, P&amp;L</td>
</tr>
<tr>
<td><code>position_snapshots</code></td>
<td>Open positions: symbol, volume, profit, …</td>
</tr>
<tr>
<td><code>order_snapshots</code></td>
<td>Active orders: symbol, type, price, …</td>
</tr>
<tr>
<td><code>terminal_snapshots</code></td>
<td>Terminal connectivity and build info</td>
</tr>
<tr>
<td><code>snapshot_runs</code></td>
<td>Per-run status (<code>ok</code> / <code>error</code>) timestamp</td>
</tr>
</tbody>
</table>
<p><strong>Grafana time-series views</strong> (integer epoch-second <code>time</code> column; snapshot views also expose <code>run_id</code>):</p>
<table>
<thead>
<tr>
<th>View</th>
<th>Source</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>grafana_rates</code></td>
<td><code>rates</code> table</td>
</tr>
<tr>
<td><code>grafana_ticks</code></td>
<td><code>ticks</code> table</td>
</tr>
<tr>
<td><code>grafana_history_deals</code></td>
<td><code>history_deals</code></td>
</tr>
<tr>
<td><code>grafana_history_orders</code></td>
<td><code>history_orders</code></td>
</tr>
<tr>
<td><code>grafana_trade_deals</code></td>
<td><code>history_deals</code> trade types only</td>
</tr>
<tr>
<td><code>grafana_cash_events</code></td>
<td><code>history_deals</code> non-trade events</td>
</tr>
<tr>
<td><code>grafana_symbol_pnl</code></td>
<td>Per-close-deal P&amp;L per symbol</td>
</tr>
<tr>
<td><code>grafana_account_snapshots</code></td>
<td><code>account_snapshots</code></td>
</tr>
<tr>
<td><code>grafana_position_snapshots</code></td>
<td><code>position_snapshots</code></td>
</tr>
<tr>
<td><code>grafana_order_snapshots</code></td>
<td><code>order_snapshots</code></td>
</tr>
<tr>
<td><code>grafana_terminal_snapshots</code></td>
<td><code>terminal_snapshots</code></td>
</tr>
</tbody>
</table>
<p><strong>Grafana static summary views</strong> (no <code>time</code> column; use for table/stat panels, not time-series):</p>
<table>
<thead>
<tr>
<th>View</th>
<th>Source</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>grafana_realized_pnl</code></td>
<td>Cumulative realized PnL per symbol</td>
</tr>
<tr>
<td><code>grafana_trade_stats</code></td>
<td>Win/loss counts and profit per symbol</td>
</tr>
</tbody>
</table>
<p>Lower-level helpers (<code>ensure_grafana_schema</code>, <code>create_grafana_views</code>,
<code>create_grafana_indexes</code>, <code>create_snapshot_tables</code>, <code>start_snapshot_run</code>,
<code>insert_account_snapshot</code>, <code>insert_position_snapshots</code>, <code>insert_order_snapshots</code>,
<code>insert_terminal_snapshot</code>, <code>record_snapshot_run</code>) are available directly from
<code>mt5cli.grafana</code> and are not part of the package-root stable surface.</p>
<h3 id="errors">Errors<a class="headerlink" href="#errors" title="Permanent link">&para;</a></h3>
<table>
<thead>
@@ -449,6 +587,10 @@ of the package-root stable surface. Import them directly when needed:</p>
</thead>
<tbody>
<tr>
<td><code>mt5cli.grafana</code></td>
<td><code>ensure_grafana_schema</code>, <code>create_grafana_views</code>, <code>create_grafana_indexes</code>, <code>create_snapshot_tables</code>, <code>start_snapshot_run</code>, <code>insert_account_snapshot</code>, <code>record_snapshot_run</code></td>
</tr>
<tr>
<td><code>mt5cli.history</code></td>
<td><code>resolve_rate_view_name</code>, <code>resolve_rate_tables</code>, <code>load_rate_data</code>, <code>build_rate_view_name</code></td>
</tr>
@@ -484,6 +626,13 @@ of the package-root stable surface. Import them directly when needed:</p>
<li>Delegate to the same Python APIs described here; they are not duplicated
business logic.</li>
</ul>
<p><code>grafana-schema</code> initializes Grafana views, indexes, and snapshot tables in the
target SQLite database without connecting to MT5. It is idempotent and safe to
run repeatedly.</p>
<p><code>snapshot</code> appends one timestamped row per enabled data type
(<code>--with-account</code>, <code>--with-positions</code>, <code>--with-orders</code>, <code>--with-terminal</code>) and
never places orders or modifies trading state. Both commands require
<code>-o/--output</code> to point at a <code>.db</code> / SQLite file.</p>
<p><code>order-send</code> is the expert raw-request path; it requires <code>--yes</code> and a fully
constructed request payload. <code>close-positions</code> is the safer high-level helper
that closes open positions by <code>--symbol</code> or <code>--ticket</code> using
+2797 -2246
View File
File diff suppressed because it is too large Load Diff
+240 -240
View File
@@ -893,8 +893,7 @@
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/utils.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-242">242</a></span>
<span class="normal"><a href="#__codelineno-0-243">243</a></span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-243">243</a></span>
<span class="normal"><a href="#__codelineno-0-244">244</a></span>
<span class="normal"><a href="#__codelineno-0-245">245</a></span>
<span class="normal"><a href="#__codelineno-0-246">246</a></span>
@@ -904,18 +903,19 @@
<span class="normal"><a href="#__codelineno-0-250">250</a></span>
<span class="normal"><a href="#__codelineno-0-251">251</a></span>
<span class="normal"><a href="#__codelineno-0-252">252</a></span>
<span class="normal"><a href="#__codelineno-0-253">253</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-242" name="__codelineno-0-242"></a><span class="k">def</span><span class="w"> </span><span class="nf">coerce_login</span><span class="p">(</span><span class="n">login</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-243" name="__codelineno-0-243"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Coerce a login value to int, treating empty strings as unset.</span>
<a id="__codelineno-0-244" name="__codelineno-0-244"></a>
<a id="__codelineno-0-245" name="__codelineno-0-245"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-246" name="__codelineno-0-246"></a><span class="sd"> Integer login, or None when unset or an empty string.</span>
<a id="__codelineno-0-247" name="__codelineno-0-247"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="k">if</span> <span class="n">login</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">login</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
<a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="k">return</span> <span class="n">login</span>
<a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="n">text</span> <span class="o">=</span> <span class="n">login</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">text</span><span class="p">:</span>
<a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="k">return</span> <span class="kc">None</span>
<a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
<span class="normal"><a href="#__codelineno-0-253">253</a></span>
<span class="normal"><a href="#__codelineno-0-254">254</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-243" name="__codelineno-0-243"></a><span class="k">def</span><span class="w"> </span><span class="nf">coerce_login</span><span class="p">(</span><span class="n">login</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-244" name="__codelineno-0-244"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Coerce a login value to int, treating empty strings as unset.</span>
<a id="__codelineno-0-245" name="__codelineno-0-245"></a>
<a id="__codelineno-0-246" name="__codelineno-0-246"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-247" name="__codelineno-0-247"></a><span class="sd"> Integer login, or None when unset or an empty string.</span>
<a id="__codelineno-0-248" name="__codelineno-0-248"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="k">if</span> <span class="n">login</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">login</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
<a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="k">return</span> <span class="n">login</span>
<a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="n">text</span> <span class="o">=</span> <span class="n">login</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">text</span><span class="p">:</span>
<a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="k">return</span> <span class="kc">None</span>
<a id="__codelineno-0-254" name="__codelineno-0-254"></a> <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
@@ -1035,8 +1035,7 @@
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/utils.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-214">214</a></span>
<span class="normal"><a href="#__codelineno-0-215">215</a></span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-215">215</a></span>
<span class="normal"><a href="#__codelineno-0-216">216</a></span>
<span class="normal"><a href="#__codelineno-0-217">217</a></span>
<span class="normal"><a href="#__codelineno-0-218">218</a></span>
@@ -1060,32 +1059,33 @@
<span class="normal"><a href="#__codelineno-0-236">236</a></span>
<span class="normal"><a href="#__codelineno-0-237">237</a></span>
<span class="normal"><a href="#__codelineno-0-238">238</a></span>
<span class="normal"><a href="#__codelineno-0-239">239</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-214" name="__codelineno-0-214"></a><span class="k">def</span><span class="w"> </span><span class="nf">detect_format</span><span class="p">(</span>
<a id="__codelineno-0-215" name="__codelineno-0-215"></a> <span class="n">output_path</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
<a id="__codelineno-0-216" name="__codelineno-0-216"></a> <span class="n">explicit_format</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-217" name="__codelineno-0-217"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<a id="__codelineno-0-218" name="__codelineno-0-218"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Detect the output format from a file extension or explicit format string.</span>
<a id="__codelineno-0-219" name="__codelineno-0-219"></a>
<a id="__codelineno-0-220" name="__codelineno-0-220"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-221" name="__codelineno-0-221"></a><span class="sd"> output_path: Path to the output file.</span>
<a id="__codelineno-0-222" name="__codelineno-0-222"></a><span class="sd"> explicit_format: Explicitly specified format, if any.</span>
<a id="__codelineno-0-223" name="__codelineno-0-223"></a>
<a id="__codelineno-0-224" name="__codelineno-0-224"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-225" name="__codelineno-0-225"></a><span class="sd"> The detected format string.</span>
<a id="__codelineno-0-226" name="__codelineno-0-226"></a>
<a id="__codelineno-0-227" name="__codelineno-0-227"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-228" name="__codelineno-0-228"></a><span class="sd"> ValueError: If the format cannot be determined.</span>
<a id="__codelineno-0-229" name="__codelineno-0-229"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-230" name="__codelineno-0-230"></a> <span class="k">if</span> <span class="n">explicit_format</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-231" name="__codelineno-0-231"></a> <span class="k">return</span> <span class="n">explicit_format</span>
<a id="__codelineno-0-232" name="__codelineno-0-232"></a> <span class="n">suffix</span> <span class="o">=</span> <span class="n">output_path</span><span class="o">.</span><span class="n">suffix</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<a id="__codelineno-0-233" name="__codelineno-0-233"></a> <span class="k">if</span> <span class="n">suffix</span> <span class="ow">in</span> <span class="n">_FORMAT_EXTENSIONS</span><span class="p">:</span>
<a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="k">return</span> <span class="n">_FORMAT_EXTENSIONS</span><span class="p">[</span><span class="n">suffix</span><span class="p">]</span>
<a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="sa">f</span><span class="s2">&quot;Cannot detect format from extension &#39;</span><span class="si">{</span><span class="n">suffix</span><span class="si">}</span><span class="s2">&#39;.&quot;</span>
<a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="s2">&quot; Use --format to specify the output format.&quot;</span>
<a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="p">)</span>
<a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="normal"><a href="#__codelineno-0-239">239</a></span>
<span class="normal"><a href="#__codelineno-0-240">240</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-215" name="__codelineno-0-215"></a><span class="k">def</span><span class="w"> </span><span class="nf">detect_format</span><span class="p">(</span>
<a id="__codelineno-0-216" name="__codelineno-0-216"></a> <span class="n">output_path</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
<a id="__codelineno-0-217" name="__codelineno-0-217"></a> <span class="n">explicit_format</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-218" name="__codelineno-0-218"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<a id="__codelineno-0-219" name="__codelineno-0-219"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Detect the output format from a file extension or explicit format string.</span>
<a id="__codelineno-0-220" name="__codelineno-0-220"></a>
<a id="__codelineno-0-221" name="__codelineno-0-221"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-222" name="__codelineno-0-222"></a><span class="sd"> output_path: Path to the output file.</span>
<a id="__codelineno-0-223" name="__codelineno-0-223"></a><span class="sd"> explicit_format: Explicitly specified format, if any.</span>
<a id="__codelineno-0-224" name="__codelineno-0-224"></a>
<a id="__codelineno-0-225" name="__codelineno-0-225"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-226" name="__codelineno-0-226"></a><span class="sd"> The detected format string.</span>
<a id="__codelineno-0-227" name="__codelineno-0-227"></a>
<a id="__codelineno-0-228" name="__codelineno-0-228"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-229" name="__codelineno-0-229"></a><span class="sd"> ValueError: If the format cannot be determined.</span>
<a id="__codelineno-0-230" name="__codelineno-0-230"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-231" name="__codelineno-0-231"></a> <span class="k">if</span> <span class="n">explicit_format</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-232" name="__codelineno-0-232"></a> <span class="k">return</span> <span class="n">explicit_format</span>
<a id="__codelineno-0-233" name="__codelineno-0-233"></a> <span class="n">suffix</span> <span class="o">=</span> <span class="n">output_path</span><span class="o">.</span><span class="n">suffix</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="k">if</span> <span class="n">suffix</span> <span class="ow">in</span> <span class="n">_FORMAT_EXTENSIONS</span><span class="p">:</span>
<a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="k">return</span> <span class="n">_FORMAT_EXTENSIONS</span><span class="p">[</span><span class="n">suffix</span><span class="p">]</span>
<a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="sa">f</span><span class="s2">&quot;Cannot detect format from extension &#39;</span><span class="si">{</span><span class="n">suffix</span><span class="si">}</span><span class="s2">&#39;.&quot;</span>
<a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="s2">&quot; Use --format to specify the output format.&quot;</span>
<a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="p">)</span>
<a id="__codelineno-0-240" name="__codelineno-0-240"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
@@ -1227,8 +1227,7 @@
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/utils.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-300">300</a></span>
<span class="normal"><a href="#__codelineno-0-301">301</a></span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-301">301</a></span>
<span class="normal"><a href="#__codelineno-0-302">302</a></span>
<span class="normal"><a href="#__codelineno-0-303">303</a></span>
<span class="normal"><a href="#__codelineno-0-304">304</a></span>
@@ -1274,54 +1273,55 @@
<span class="normal"><a href="#__codelineno-0-344">344</a></span>
<span class="normal"><a href="#__codelineno-0-345">345</a></span>
<span class="normal"><a href="#__codelineno-0-346">346</a></span>
<span class="normal"><a href="#__codelineno-0-347">347</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-300" name="__codelineno-0-300"></a><span class="k">def</span><span class="w"> </span><span class="nf">export_dataframe</span><span class="p">(</span>
<a id="__codelineno-0-301" name="__codelineno-0-301"></a> <span class="n">df</span><span class="p">:</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">,</span>
<a id="__codelineno-0-302" name="__codelineno-0-302"></a> <span class="n">output_path</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
<a id="__codelineno-0-303" name="__codelineno-0-303"></a> <span class="n">output_format</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
<a id="__codelineno-0-304" name="__codelineno-0-304"></a> <span class="n">table_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;data&quot;</span><span class="p">,</span>
<a id="__codelineno-0-305" name="__codelineno-0-305"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-306" name="__codelineno-0-306"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Export a pandas DataFrame to the specified file format.</span>
<a id="__codelineno-0-307" name="__codelineno-0-307"></a>
<a id="__codelineno-0-308" name="__codelineno-0-308"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-309" name="__codelineno-0-309"></a><span class="sd"> df: DataFrame to export.</span>
<a id="__codelineno-0-310" name="__codelineno-0-310"></a><span class="sd"> output_path: Path to the output file.</span>
<a id="__codelineno-0-311" name="__codelineno-0-311"></a><span class="sd"> output_format: Output format (csv, json, parquet, or sqlite3).</span>
<a id="__codelineno-0-312" name="__codelineno-0-312"></a><span class="sd"> table_name: Table name for SQLite3 output.</span>
<a id="__codelineno-0-313" name="__codelineno-0-313"></a>
<a id="__codelineno-0-314" name="__codelineno-0-314"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-315" name="__codelineno-0-315"></a><span class="sd"> ImportError: If the parquet format is requested but pyarrow is not installed.</span>
<a id="__codelineno-0-316" name="__codelineno-0-316"></a><span class="sd"> ValueError: If the output format is not supported.</span>
<a id="__codelineno-0-317" name="__codelineno-0-317"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-318" name="__codelineno-0-318"></a> <span class="k">if</span> <span class="n">output_format</span> <span class="o">==</span> <span class="s2">&quot;csv&quot;</span><span class="p">:</span>
<a id="__codelineno-0-319" name="__codelineno-0-319"></a> <span class="n">df</span><span class="o">.</span><span class="n">to_csv</span><span class="p">(</span><span class="n">output_path</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<a id="__codelineno-0-320" name="__codelineno-0-320"></a> <span class="k">elif</span> <span class="n">output_format</span> <span class="o">==</span> <span class="s2">&quot;json&quot;</span><span class="p">:</span>
<a id="__codelineno-0-321" name="__codelineno-0-321"></a> <span class="n">df</span><span class="o">.</span><span class="n">to_json</span><span class="p">(</span>
<a id="__codelineno-0-322" name="__codelineno-0-322"></a> <span class="n">output_path</span><span class="p">,</span>
<a id="__codelineno-0-323" name="__codelineno-0-323"></a> <span class="n">orient</span><span class="o">=</span><span class="s2">&quot;records&quot;</span><span class="p">,</span>
<a id="__codelineno-0-324" name="__codelineno-0-324"></a> <span class="n">date_format</span><span class="o">=</span><span class="s2">&quot;iso&quot;</span><span class="p">,</span>
<a id="__codelineno-0-325" name="__codelineno-0-325"></a> <span class="n">indent</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span>
<a id="__codelineno-0-326" name="__codelineno-0-326"></a> <span class="p">)</span>
<a id="__codelineno-0-327" name="__codelineno-0-327"></a> <span class="k">elif</span> <span class="n">output_format</span> <span class="o">==</span> <span class="s2">&quot;parquet&quot;</span><span class="p">:</span>
<a id="__codelineno-0-328" name="__codelineno-0-328"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-329" name="__codelineno-0-329"></a> <span class="nb">__import__</span><span class="p">(</span><span class="s2">&quot;pyarrow&quot;</span><span class="p">)</span>
<a id="__codelineno-0-330" name="__codelineno-0-330"></a> <span class="k">except</span> <span class="ne">ImportError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
<a id="__codelineno-0-331" name="__codelineno-0-331"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-332" name="__codelineno-0-332"></a> <span class="s2">&quot;Parquet export requires the optional dependency pyarrow. &quot;</span>
<a id="__codelineno-0-333" name="__codelineno-0-333"></a> <span class="s1">&#39;Install it with: pip install &quot;mt5cli[parquet]&quot;&#39;</span>
<a id="__codelineno-0-334" name="__codelineno-0-334"></a> <span class="p">)</span>
<a id="__codelineno-0-335" name="__codelineno-0-335"></a> <span class="k">raise</span> <span class="ne">ImportError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">exc</span>
<a id="__codelineno-0-336" name="__codelineno-0-336"></a> <span class="n">df</span><span class="o">.</span><span class="n">to_parquet</span><span class="p">(</span><span class="n">output_path</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<a id="__codelineno-0-337" name="__codelineno-0-337"></a> <span class="k">elif</span> <span class="n">output_format</span> <span class="o">==</span> <span class="s2">&quot;sqlite3&quot;</span><span class="p">:</span>
<a id="__codelineno-0-338" name="__codelineno-0-338"></a> <span class="n">export_dataframe_to_sqlite</span><span class="p">(</span>
<a id="__codelineno-0-339" name="__codelineno-0-339"></a> <span class="n">df</span><span class="p">,</span>
<a id="__codelineno-0-340" name="__codelineno-0-340"></a> <span class="n">output_path</span><span class="p">,</span>
<a id="__codelineno-0-341" name="__codelineno-0-341"></a> <span class="n">table_name</span><span class="p">,</span>
<a id="__codelineno-0-342" name="__codelineno-0-342"></a> <span class="n">if_exists</span><span class="o">=</span><span class="n">IfExists</span><span class="o">.</span><span class="n">REPLACE</span><span class="p">,</span>
<a id="__codelineno-0-343" name="__codelineno-0-343"></a> <span class="n">index</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<a id="__codelineno-0-344" name="__codelineno-0-344"></a> <span class="p">)</span>
<a id="__codelineno-0-345" name="__codelineno-0-345"></a> <span class="k">else</span><span class="p">:</span>
<a id="__codelineno-0-346" name="__codelineno-0-346"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Unsupported output format: </span><span class="si">{</span><span class="n">output_format</span><span class="si">}</span><span class="s2">&quot;</span>
<a id="__codelineno-0-347" name="__codelineno-0-347"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="normal"><a href="#__codelineno-0-347">347</a></span>
<span class="normal"><a href="#__codelineno-0-348">348</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-301" name="__codelineno-0-301"></a><span class="k">def</span><span class="w"> </span><span class="nf">export_dataframe</span><span class="p">(</span>
<a id="__codelineno-0-302" name="__codelineno-0-302"></a> <span class="n">df</span><span class="p">:</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">,</span>
<a id="__codelineno-0-303" name="__codelineno-0-303"></a> <span class="n">output_path</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
<a id="__codelineno-0-304" name="__codelineno-0-304"></a> <span class="n">output_format</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
<a id="__codelineno-0-305" name="__codelineno-0-305"></a> <span class="n">table_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;data&quot;</span><span class="p">,</span>
<a id="__codelineno-0-306" name="__codelineno-0-306"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-307" name="__codelineno-0-307"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Export a pandas DataFrame to the specified file format.</span>
<a id="__codelineno-0-308" name="__codelineno-0-308"></a>
<a id="__codelineno-0-309" name="__codelineno-0-309"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-310" name="__codelineno-0-310"></a><span class="sd"> df: DataFrame to export.</span>
<a id="__codelineno-0-311" name="__codelineno-0-311"></a><span class="sd"> output_path: Path to the output file.</span>
<a id="__codelineno-0-312" name="__codelineno-0-312"></a><span class="sd"> output_format: Output format (csv, json, parquet, or sqlite3).</span>
<a id="__codelineno-0-313" name="__codelineno-0-313"></a><span class="sd"> table_name: Table name for SQLite3 output.</span>
<a id="__codelineno-0-314" name="__codelineno-0-314"></a>
<a id="__codelineno-0-315" name="__codelineno-0-315"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-316" name="__codelineno-0-316"></a><span class="sd"> ImportError: If the parquet format is requested but pyarrow is not installed.</span>
<a id="__codelineno-0-317" name="__codelineno-0-317"></a><span class="sd"> ValueError: If the output format is not supported.</span>
<a id="__codelineno-0-318" name="__codelineno-0-318"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-319" name="__codelineno-0-319"></a> <span class="k">if</span> <span class="n">output_format</span> <span class="o">==</span> <span class="s2">&quot;csv&quot;</span><span class="p">:</span>
<a id="__codelineno-0-320" name="__codelineno-0-320"></a> <span class="n">df</span><span class="o">.</span><span class="n">to_csv</span><span class="p">(</span><span class="n">output_path</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<a id="__codelineno-0-321" name="__codelineno-0-321"></a> <span class="k">elif</span> <span class="n">output_format</span> <span class="o">==</span> <span class="s2">&quot;json&quot;</span><span class="p">:</span>
<a id="__codelineno-0-322" name="__codelineno-0-322"></a> <span class="n">df</span><span class="o">.</span><span class="n">to_json</span><span class="p">(</span>
<a id="__codelineno-0-323" name="__codelineno-0-323"></a> <span class="n">output_path</span><span class="p">,</span>
<a id="__codelineno-0-324" name="__codelineno-0-324"></a> <span class="n">orient</span><span class="o">=</span><span class="s2">&quot;records&quot;</span><span class="p">,</span>
<a id="__codelineno-0-325" name="__codelineno-0-325"></a> <span class="n">date_format</span><span class="o">=</span><span class="s2">&quot;iso&quot;</span><span class="p">,</span>
<a id="__codelineno-0-326" name="__codelineno-0-326"></a> <span class="n">indent</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span>
<a id="__codelineno-0-327" name="__codelineno-0-327"></a> <span class="p">)</span>
<a id="__codelineno-0-328" name="__codelineno-0-328"></a> <span class="k">elif</span> <span class="n">output_format</span> <span class="o">==</span> <span class="s2">&quot;parquet&quot;</span><span class="p">:</span>
<a id="__codelineno-0-329" name="__codelineno-0-329"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-330" name="__codelineno-0-330"></a> <span class="nb">__import__</span><span class="p">(</span><span class="s2">&quot;pyarrow&quot;</span><span class="p">)</span>
<a id="__codelineno-0-331" name="__codelineno-0-331"></a> <span class="k">except</span> <span class="ne">ImportError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
<a id="__codelineno-0-332" name="__codelineno-0-332"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-333" name="__codelineno-0-333"></a> <span class="s2">&quot;Parquet export requires the optional dependency pyarrow. &quot;</span>
<a id="__codelineno-0-334" name="__codelineno-0-334"></a> <span class="s1">&#39;Install it with: pip install &quot;mt5cli[parquet]&quot;&#39;</span>
<a id="__codelineno-0-335" name="__codelineno-0-335"></a> <span class="p">)</span>
<a id="__codelineno-0-336" name="__codelineno-0-336"></a> <span class="k">raise</span> <span class="ne">ImportError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">exc</span>
<a id="__codelineno-0-337" name="__codelineno-0-337"></a> <span class="n">df</span><span class="o">.</span><span class="n">to_parquet</span><span class="p">(</span><span class="n">output_path</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<a id="__codelineno-0-338" name="__codelineno-0-338"></a> <span class="k">elif</span> <span class="n">output_format</span> <span class="o">==</span> <span class="s2">&quot;sqlite3&quot;</span><span class="p">:</span>
<a id="__codelineno-0-339" name="__codelineno-0-339"></a> <span class="n">export_dataframe_to_sqlite</span><span class="p">(</span>
<a id="__codelineno-0-340" name="__codelineno-0-340"></a> <span class="n">df</span><span class="p">,</span>
<a id="__codelineno-0-341" name="__codelineno-0-341"></a> <span class="n">output_path</span><span class="p">,</span>
<a id="__codelineno-0-342" name="__codelineno-0-342"></a> <span class="n">table_name</span><span class="p">,</span>
<a id="__codelineno-0-343" name="__codelineno-0-343"></a> <span class="n">if_exists</span><span class="o">=</span><span class="n">IfExists</span><span class="o">.</span><span class="n">REPLACE</span><span class="p">,</span>
<a id="__codelineno-0-344" name="__codelineno-0-344"></a> <span class="n">index</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<a id="__codelineno-0-345" name="__codelineno-0-345"></a> <span class="p">)</span>
<a id="__codelineno-0-346" name="__codelineno-0-346"></a> <span class="k">else</span><span class="p">:</span>
<a id="__codelineno-0-347" name="__codelineno-0-347"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Unsupported output format: </span><span class="si">{</span><span class="n">output_format</span><span class="si">}</span><span class="s2">&quot;</span>
<a id="__codelineno-0-348" name="__codelineno-0-348"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
@@ -1497,8 +1497,7 @@ columns when appending frequently.</p>
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/utils.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-256">256</a></span>
<span class="normal"><a href="#__codelineno-0-257">257</a></span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-257">257</a></span>
<span class="normal"><a href="#__codelineno-0-258">258</a></span>
<span class="normal"><a href="#__codelineno-0-259">259</a></span>
<span class="normal"><a href="#__codelineno-0-260">260</a></span>
@@ -1538,48 +1537,49 @@ columns when appending frequently.</p>
<span class="normal"><a href="#__codelineno-0-294">294</a></span>
<span class="normal"><a href="#__codelineno-0-295">295</a></span>
<span class="normal"><a href="#__codelineno-0-296">296</a></span>
<span class="normal"><a href="#__codelineno-0-297">297</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-256" name="__codelineno-0-256"></a><span class="k">def</span><span class="w"> </span><span class="nf">export_dataframe_to_sqlite</span><span class="p">(</span>
<a id="__codelineno-0-257" name="__codelineno-0-257"></a> <span class="n">df</span><span class="p">:</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">,</span>
<a id="__codelineno-0-258" name="__codelineno-0-258"></a> <span class="n">output_path</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
<a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="n">table_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;data&quot;</span><span class="p">,</span>
<a id="__codelineno-0-260" name="__codelineno-0-260"></a> <span class="o">*</span><span class="p">,</span>
<a id="__codelineno-0-261" name="__codelineno-0-261"></a> <span class="n">if_exists</span><span class="p">:</span> <span class="n">IfExists</span> <span class="o">=</span> <span class="n">IfExists</span><span class="o">.</span><span class="n">APPEND</span><span class="p">,</span>
<a id="__codelineno-0-262" name="__codelineno-0-262"></a> <span class="n">index</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
<a id="__codelineno-0-263" name="__codelineno-0-263"></a> <span class="n">index_label</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-264" name="__codelineno-0-264"></a> <span class="n">deduplicate_on</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-265" name="__codelineno-0-265"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-266" name="__codelineno-0-266"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Write a DataFrame to SQLite with configurable append and deduplication.</span>
<a id="__codelineno-0-267" name="__codelineno-0-267"></a>
<a id="__codelineno-0-268" name="__codelineno-0-268"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-269" name="__codelineno-0-269"></a><span class="sd"> df: DataFrame to export.</span>
<a id="__codelineno-0-270" name="__codelineno-0-270"></a><span class="sd"> output_path: SQLite database path.</span>
<a id="__codelineno-0-271" name="__codelineno-0-271"></a><span class="sd"> table_name: Target table name.</span>
<a id="__codelineno-0-272" name="__codelineno-0-272"></a><span class="sd"> if_exists: Conflict behavior when the table already exists.</span>
<a id="__codelineno-0-273" name="__codelineno-0-273"></a><span class="sd"> index: Whether to write the DataFrame index as a column.</span>
<a id="__codelineno-0-274" name="__codelineno-0-274"></a><span class="sd"> index_label: Column name for the index when ``index=True``.</span>
<a id="__codelineno-0-275" name="__codelineno-0-275"></a><span class="sd"> deduplicate_on: Optional key columns to deduplicate after writing,</span>
<a id="__codelineno-0-276" name="__codelineno-0-276"></a><span class="sd"> keeping the latest ``ROWID`` per key group. Deduplication scans the</span>
<a id="__codelineno-0-277" name="__codelineno-0-277"></a><span class="sd"> full table, so repeated appends cost O(table size); index the key</span>
<a id="__codelineno-0-278" name="__codelineno-0-278"></a><span class="sd"> columns when appending frequently.</span>
<a id="__codelineno-0-279" name="__codelineno-0-279"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-280" name="__codelineno-0-280"></a> <span class="k">with</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">output_path</span><span class="p">)</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span>
<a id="__codelineno-0-281" name="__codelineno-0-281"></a> <span class="n">df</span><span class="o">.</span><span class="n">to_sql</span><span class="p">(</span> <span class="c1"># type: ignore[reportUnknownMemberType]</span>
<a id="__codelineno-0-282" name="__codelineno-0-282"></a> <span class="n">table_name</span><span class="p">,</span>
<a id="__codelineno-0-283" name="__codelineno-0-283"></a> <span class="n">conn</span><span class="p">,</span>
<a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="n">if_exists</span><span class="o">=</span><span class="n">if_exists</span><span class="o">.</span><span class="n">value</span><span class="p">,</span>
<a id="__codelineno-0-285" name="__codelineno-0-285"></a> <span class="n">index</span><span class="o">=</span><span class="n">index</span><span class="p">,</span>
<a id="__codelineno-0-286" name="__codelineno-0-286"></a> <span class="n">index_label</span><span class="o">=</span><span class="n">index_label</span><span class="p">,</span>
<a id="__codelineno-0-287" name="__codelineno-0-287"></a> <span class="p">)</span>
<a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="k">if</span> <span class="n">deduplicate_on</span><span class="p">:</span>
<a id="__codelineno-0-289" name="__codelineno-0-289"></a> <span class="kn">from</span><span class="w"> </span><span class="nn">.history</span><span class="w"> </span><span class="kn">import</span> <span class="n">drop_duplicates_in_table</span> <span class="c1"># noqa: PLC0415</span>
<a id="__codelineno-0-290" name="__codelineno-0-290"></a>
<a id="__codelineno-0-291" name="__codelineno-0-291"></a> <span class="n">drop_duplicates_in_table</span><span class="p">(</span>
<a id="__codelineno-0-292" name="__codelineno-0-292"></a> <span class="n">conn</span><span class="o">.</span><span class="n">cursor</span><span class="p">(),</span>
<a id="__codelineno-0-293" name="__codelineno-0-293"></a> <span class="n">table_name</span><span class="p">,</span>
<a id="__codelineno-0-294" name="__codelineno-0-294"></a> <span class="nb">list</span><span class="p">(</span><span class="n">deduplicate_on</span><span class="p">),</span>
<a id="__codelineno-0-295" name="__codelineno-0-295"></a> <span class="n">keep</span><span class="o">=</span><span class="s2">&quot;last&quot;</span><span class="p">,</span>
<a id="__codelineno-0-296" name="__codelineno-0-296"></a> <span class="p">)</span>
<a id="__codelineno-0-297" name="__codelineno-0-297"></a> <span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
<span class="normal"><a href="#__codelineno-0-297">297</a></span>
<span class="normal"><a href="#__codelineno-0-298">298</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-257" name="__codelineno-0-257"></a><span class="k">def</span><span class="w"> </span><span class="nf">export_dataframe_to_sqlite</span><span class="p">(</span>
<a id="__codelineno-0-258" name="__codelineno-0-258"></a> <span class="n">df</span><span class="p">:</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">,</span>
<a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="n">output_path</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
<a id="__codelineno-0-260" name="__codelineno-0-260"></a> <span class="n">table_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;data&quot;</span><span class="p">,</span>
<a id="__codelineno-0-261" name="__codelineno-0-261"></a> <span class="o">*</span><span class="p">,</span>
<a id="__codelineno-0-262" name="__codelineno-0-262"></a> <span class="n">if_exists</span><span class="p">:</span> <span class="n">IfExists</span> <span class="o">=</span> <span class="n">IfExists</span><span class="o">.</span><span class="n">APPEND</span><span class="p">,</span>
<a id="__codelineno-0-263" name="__codelineno-0-263"></a> <span class="n">index</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
<a id="__codelineno-0-264" name="__codelineno-0-264"></a> <span class="n">index_label</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-265" name="__codelineno-0-265"></a> <span class="n">deduplicate_on</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a id="__codelineno-0-266" name="__codelineno-0-266"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-267" name="__codelineno-0-267"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Write a DataFrame to SQLite with configurable append and deduplication.</span>
<a id="__codelineno-0-268" name="__codelineno-0-268"></a>
<a id="__codelineno-0-269" name="__codelineno-0-269"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-270" name="__codelineno-0-270"></a><span class="sd"> df: DataFrame to export.</span>
<a id="__codelineno-0-271" name="__codelineno-0-271"></a><span class="sd"> output_path: SQLite database path.</span>
<a id="__codelineno-0-272" name="__codelineno-0-272"></a><span class="sd"> table_name: Target table name.</span>
<a id="__codelineno-0-273" name="__codelineno-0-273"></a><span class="sd"> if_exists: Conflict behavior when the table already exists.</span>
<a id="__codelineno-0-274" name="__codelineno-0-274"></a><span class="sd"> index: Whether to write the DataFrame index as a column.</span>
<a id="__codelineno-0-275" name="__codelineno-0-275"></a><span class="sd"> index_label: Column name for the index when ``index=True``.</span>
<a id="__codelineno-0-276" name="__codelineno-0-276"></a><span class="sd"> deduplicate_on: Optional key columns to deduplicate after writing,</span>
<a id="__codelineno-0-277" name="__codelineno-0-277"></a><span class="sd"> keeping the latest ``ROWID`` per key group. Deduplication scans the</span>
<a id="__codelineno-0-278" name="__codelineno-0-278"></a><span class="sd"> full table, so repeated appends cost O(table size); index the key</span>
<a id="__codelineno-0-279" name="__codelineno-0-279"></a><span class="sd"> columns when appending frequently.</span>
<a id="__codelineno-0-280" name="__codelineno-0-280"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-281" name="__codelineno-0-281"></a> <span class="k">with</span> <span class="n">closing</span><span class="p">(</span><span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">output_path</span><span class="p">))</span> <span class="k">as</span> <span class="n">conn</span><span class="p">,</span> <span class="n">conn</span><span class="p">:</span>
<a id="__codelineno-0-282" name="__codelineno-0-282"></a> <span class="n">df</span><span class="o">.</span><span class="n">to_sql</span><span class="p">(</span> <span class="c1"># type: ignore[reportUnknownMemberType]</span>
<a id="__codelineno-0-283" name="__codelineno-0-283"></a> <span class="n">table_name</span><span class="p">,</span>
<a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="n">conn</span><span class="p">,</span>
<a id="__codelineno-0-285" name="__codelineno-0-285"></a> <span class="n">if_exists</span><span class="o">=</span><span class="n">if_exists</span><span class="o">.</span><span class="n">value</span><span class="p">,</span>
<a id="__codelineno-0-286" name="__codelineno-0-286"></a> <span class="n">index</span><span class="o">=</span><span class="n">index</span><span class="p">,</span>
<a id="__codelineno-0-287" name="__codelineno-0-287"></a> <span class="n">index_label</span><span class="o">=</span><span class="n">index_label</span><span class="p">,</span>
<a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="p">)</span>
<a id="__codelineno-0-289" name="__codelineno-0-289"></a> <span class="k">if</span> <span class="n">deduplicate_on</span><span class="p">:</span>
<a id="__codelineno-0-290" name="__codelineno-0-290"></a> <span class="kn">from</span><span class="w"> </span><span class="nn">.history</span><span class="w"> </span><span class="kn">import</span> <span class="n">drop_duplicates_in_table</span> <span class="c1"># noqa: PLC0415</span>
<a id="__codelineno-0-291" name="__codelineno-0-291"></a>
<a id="__codelineno-0-292" name="__codelineno-0-292"></a> <span class="n">drop_duplicates_in_table</span><span class="p">(</span>
<a id="__codelineno-0-293" name="__codelineno-0-293"></a> <span class="n">conn</span><span class="o">.</span><span class="n">cursor</span><span class="p">(),</span>
<a id="__codelineno-0-294" name="__codelineno-0-294"></a> <span class="n">table_name</span><span class="p">,</span>
<a id="__codelineno-0-295" name="__codelineno-0-295"></a> <span class="nb">list</span><span class="p">(</span><span class="n">deduplicate_on</span><span class="p">),</span>
<a id="__codelineno-0-296" name="__codelineno-0-296"></a> <span class="n">keep</span><span class="o">=</span><span class="s2">&quot;last&quot;</span><span class="p">,</span>
<a id="__codelineno-0-297" name="__codelineno-0-297"></a> <span class="p">)</span>
<a id="__codelineno-0-298" name="__codelineno-0-298"></a> <span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
@@ -1682,8 +1682,7 @@ columns when appending frequently.</p>
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/utils.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-350">350</a></span>
<span class="normal"><a href="#__codelineno-0-351">351</a></span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-351">351</a></span>
<span class="normal"><a href="#__codelineno-0-352">352</a></span>
<span class="normal"><a href="#__codelineno-0-353">353</a></span>
<span class="normal"><a href="#__codelineno-0-354">354</a></span>
@@ -1702,27 +1701,28 @@ columns when appending frequently.</p>
<span class="normal"><a href="#__codelineno-0-367">367</a></span>
<span class="normal"><a href="#__codelineno-0-368">368</a></span>
<span class="normal"><a href="#__codelineno-0-369">369</a></span>
<span class="normal"><a href="#__codelineno-0-370">370</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-350" name="__codelineno-0-350"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_datetime</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">datetime</span><span class="p">:</span>
<a id="__codelineno-0-351" name="__codelineno-0-351"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse an ISO 8601 datetime string to a timezone-aware datetime.</span>
<a id="__codelineno-0-352" name="__codelineno-0-352"></a>
<a id="__codelineno-0-353" name="__codelineno-0-353"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-354" name="__codelineno-0-354"></a><span class="sd"> value: ISO 8601 datetime string (e.g., &#39;2024-01-01&#39; or</span>
<a id="__codelineno-0-355" name="__codelineno-0-355"></a><span class="sd"> &#39;2024-01-01T12:00:00+00:00&#39;).</span>
<a id="__codelineno-0-356" name="__codelineno-0-356"></a>
<a id="__codelineno-0-357" name="__codelineno-0-357"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-358" name="__codelineno-0-358"></a><span class="sd"> Parsed datetime with UTC timezone if no timezone is specified.</span>
<a id="__codelineno-0-359" name="__codelineno-0-359"></a>
<a id="__codelineno-0-360" name="__codelineno-0-360"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-361" name="__codelineno-0-361"></a><span class="sd"> ValueError: If the string cannot be parsed.</span>
<a id="__codelineno-0-362" name="__codelineno-0-362"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-363" name="__codelineno-0-363"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-364" name="__codelineno-0-364"></a> <span class="n">dt</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-365" name="__codelineno-0-365"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<a id="__codelineno-0-366" name="__codelineno-0-366"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Invalid datetime format: &#39;</span><span class="si">{</span><span class="n">value</span><span class="si">}</span><span class="s2">&#39;. Use ISO 8601 format.&quot;</span>
<a id="__codelineno-0-367" name="__codelineno-0-367"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
<a id="__codelineno-0-368" name="__codelineno-0-368"></a> <span class="k">if</span> <span class="n">dt</span><span class="o">.</span><span class="n">tzinfo</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-369" name="__codelineno-0-369"></a> <span class="n">dt</span> <span class="o">=</span> <span class="n">dt</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">tzinfo</span><span class="o">=</span><span class="n">UTC</span><span class="p">)</span>
<a id="__codelineno-0-370" name="__codelineno-0-370"></a> <span class="k">return</span> <span class="n">dt</span>
<span class="normal"><a href="#__codelineno-0-370">370</a></span>
<span class="normal"><a href="#__codelineno-0-371">371</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-351" name="__codelineno-0-351"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_datetime</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">datetime</span><span class="p">:</span>
<a id="__codelineno-0-352" name="__codelineno-0-352"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse an ISO 8601 datetime string to a timezone-aware datetime.</span>
<a id="__codelineno-0-353" name="__codelineno-0-353"></a>
<a id="__codelineno-0-354" name="__codelineno-0-354"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-355" name="__codelineno-0-355"></a><span class="sd"> value: ISO 8601 datetime string (e.g., &#39;2024-01-01&#39; or</span>
<a id="__codelineno-0-356" name="__codelineno-0-356"></a><span class="sd"> &#39;2024-01-01T12:00:00+00:00&#39;).</span>
<a id="__codelineno-0-357" name="__codelineno-0-357"></a>
<a id="__codelineno-0-358" name="__codelineno-0-358"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-359" name="__codelineno-0-359"></a><span class="sd"> Parsed datetime with UTC timezone if no timezone is specified.</span>
<a id="__codelineno-0-360" name="__codelineno-0-360"></a>
<a id="__codelineno-0-361" name="__codelineno-0-361"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-362" name="__codelineno-0-362"></a><span class="sd"> ValueError: If the string cannot be parsed.</span>
<a id="__codelineno-0-363" name="__codelineno-0-363"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-364" name="__codelineno-0-364"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-365" name="__codelineno-0-365"></a> <span class="n">dt</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-366" name="__codelineno-0-366"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<a id="__codelineno-0-367" name="__codelineno-0-367"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Invalid datetime format: &#39;</span><span class="si">{</span><span class="n">value</span><span class="si">}</span><span class="s2">&#39;. Use ISO 8601 format.&quot;</span>
<a id="__codelineno-0-368" name="__codelineno-0-368"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
<a id="__codelineno-0-369" name="__codelineno-0-369"></a> <span class="k">if</span> <span class="n">dt</span><span class="o">.</span><span class="n">tzinfo</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-0-370" name="__codelineno-0-370"></a> <span class="n">dt</span> <span class="o">=</span> <span class="n">dt</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">tzinfo</span><span class="o">=</span><span class="n">UTC</span><span class="p">)</span>
<a id="__codelineno-0-371" name="__codelineno-0-371"></a> <span class="k">return</span> <span class="n">dt</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
@@ -1825,8 +1825,7 @@ JSON object.</p>
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/utils.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-425">425</a></span>
<span class="normal"><a href="#__codelineno-0-426">426</a></span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-426">426</a></span>
<span class="normal"><a href="#__codelineno-0-427">427</a></span>
<span class="normal"><a href="#__codelineno-0-428">428</a></span>
<span class="normal"><a href="#__codelineno-0-429">429</a></span>
@@ -1855,37 +1854,38 @@ JSON object.</p>
<span class="normal"><a href="#__codelineno-0-452">452</a></span>
<span class="normal"><a href="#__codelineno-0-453">453</a></span>
<span class="normal"><a href="#__codelineno-0-454">454</a></span>
<span class="normal"><a href="#__codelineno-0-455">455</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-425" name="__codelineno-0-425"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_request</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
<a id="__codelineno-0-426" name="__codelineno-0-426"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse a JSON-formatted order request string or file reference.</span>
<a id="__codelineno-0-427" name="__codelineno-0-427"></a>
<a id="__codelineno-0-428" name="__codelineno-0-428"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-429" name="__codelineno-0-429"></a><span class="sd"> value: JSON object string, or &#39;@path&#39; to read JSON from a file.</span>
<a id="__codelineno-0-430" name="__codelineno-0-430"></a>
<a id="__codelineno-0-431" name="__codelineno-0-431"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-432" name="__codelineno-0-432"></a><span class="sd"> Parsed request dictionary.</span>
<a id="__codelineno-0-433" name="__codelineno-0-433"></a>
<a id="__codelineno-0-434" name="__codelineno-0-434"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-435" name="__codelineno-0-435"></a><span class="sd"> ValueError: If the request file cannot be read or the value is not a</span>
<a id="__codelineno-0-436" name="__codelineno-0-436"></a><span class="sd"> JSON object.</span>
<a id="__codelineno-0-437" name="__codelineno-0-437"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-438" name="__codelineno-0-438"></a> <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;@&quot;</span><span class="p">):</span>
<a id="__codelineno-0-439" name="__codelineno-0-439"></a> <span class="n">path</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">value</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<a id="__codelineno-0-440" name="__codelineno-0-440"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-441" name="__codelineno-0-441"></a> <span class="n">text</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">read_text</span><span class="p">(</span><span class="n">encoding</span><span class="o">=</span><span class="s2">&quot;utf-8&quot;</span><span class="p">)</span>
<a id="__codelineno-0-442" name="__codelineno-0-442"></a> <span class="k">except</span> <span class="p">(</span><span class="ne">OSError</span><span class="p">,</span> <span class="ne">UnicodeDecodeError</span><span class="p">)</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
<a id="__codelineno-0-443" name="__codelineno-0-443"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Failed to read JSON request file &#39;</span><span class="si">{</span><span class="n">path</span><span class="si">}</span><span class="s2">&#39;: </span><span class="si">{</span><span class="n">exc</span><span class="si">}</span><span class="s2">&quot;</span>
<a id="__codelineno-0-444" name="__codelineno-0-444"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">exc</span>
<a id="__codelineno-0-445" name="__codelineno-0-445"></a> <span class="k">else</span><span class="p">:</span>
<a id="__codelineno-0-446" name="__codelineno-0-446"></a> <span class="n">text</span> <span class="o">=</span> <span class="n">value</span>
<a id="__codelineno-0-447" name="__codelineno-0-447"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-448" name="__codelineno-0-448"></a> <span class="n">parsed</span><span class="p">:</span> <span class="nb">object</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
<a id="__codelineno-0-449" name="__codelineno-0-449"></a> <span class="k">except</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONDecodeError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
<a id="__codelineno-0-450" name="__codelineno-0-450"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Invalid JSON request: </span><span class="si">{</span><span class="n">exc</span><span class="si">}</span><span class="s2">&quot;</span>
<a id="__codelineno-0-451" name="__codelineno-0-451"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">exc</span>
<a id="__codelineno-0-452" name="__codelineno-0-452"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">_is_request_dict</span><span class="p">(</span><span class="n">parsed</span><span class="p">):</span>
<a id="__codelineno-0-453" name="__codelineno-0-453"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">&quot;Order request must be a JSON object.&quot;</span>
<a id="__codelineno-0-454" name="__codelineno-0-454"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<a id="__codelineno-0-455" name="__codelineno-0-455"></a> <span class="k">return</span> <span class="n">parsed</span>
<span class="normal"><a href="#__codelineno-0-455">455</a></span>
<span class="normal"><a href="#__codelineno-0-456">456</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-426" name="__codelineno-0-426"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_request</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
<a id="__codelineno-0-427" name="__codelineno-0-427"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse a JSON-formatted order request string or file reference.</span>
<a id="__codelineno-0-428" name="__codelineno-0-428"></a>
<a id="__codelineno-0-429" name="__codelineno-0-429"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-430" name="__codelineno-0-430"></a><span class="sd"> value: JSON object string, or &#39;@path&#39; to read JSON from a file.</span>
<a id="__codelineno-0-431" name="__codelineno-0-431"></a>
<a id="__codelineno-0-432" name="__codelineno-0-432"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-433" name="__codelineno-0-433"></a><span class="sd"> Parsed request dictionary.</span>
<a id="__codelineno-0-434" name="__codelineno-0-434"></a>
<a id="__codelineno-0-435" name="__codelineno-0-435"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-436" name="__codelineno-0-436"></a><span class="sd"> ValueError: If the request file cannot be read or the value is not a</span>
<a id="__codelineno-0-437" name="__codelineno-0-437"></a><span class="sd"> JSON object.</span>
<a id="__codelineno-0-438" name="__codelineno-0-438"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-439" name="__codelineno-0-439"></a> <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;@&quot;</span><span class="p">):</span>
<a id="__codelineno-0-440" name="__codelineno-0-440"></a> <span class="n">path</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">value</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<a id="__codelineno-0-441" name="__codelineno-0-441"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-442" name="__codelineno-0-442"></a> <span class="n">text</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">read_text</span><span class="p">(</span><span class="n">encoding</span><span class="o">=</span><span class="s2">&quot;utf-8&quot;</span><span class="p">)</span>
<a id="__codelineno-0-443" name="__codelineno-0-443"></a> <span class="k">except</span> <span class="p">(</span><span class="ne">OSError</span><span class="p">,</span> <span class="ne">UnicodeDecodeError</span><span class="p">)</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
<a id="__codelineno-0-444" name="__codelineno-0-444"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Failed to read JSON request file &#39;</span><span class="si">{</span><span class="n">path</span><span class="si">}</span><span class="s2">&#39;: </span><span class="si">{</span><span class="n">exc</span><span class="si">}</span><span class="s2">&quot;</span>
<a id="__codelineno-0-445" name="__codelineno-0-445"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">exc</span>
<a id="__codelineno-0-446" name="__codelineno-0-446"></a> <span class="k">else</span><span class="p">:</span>
<a id="__codelineno-0-447" name="__codelineno-0-447"></a> <span class="n">text</span> <span class="o">=</span> <span class="n">value</span>
<a id="__codelineno-0-448" name="__codelineno-0-448"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-449" name="__codelineno-0-449"></a> <span class="n">parsed</span><span class="p">:</span> <span class="nb">object</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
<a id="__codelineno-0-450" name="__codelineno-0-450"></a> <span class="k">except</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONDecodeError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
<a id="__codelineno-0-451" name="__codelineno-0-451"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Invalid JSON request: </span><span class="si">{</span><span class="n">exc</span><span class="si">}</span><span class="s2">&quot;</span>
<a id="__codelineno-0-452" name="__codelineno-0-452"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">exc</span>
<a id="__codelineno-0-453" name="__codelineno-0-453"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">_is_request_dict</span><span class="p">(</span><span class="n">parsed</span><span class="p">):</span>
<a id="__codelineno-0-454" name="__codelineno-0-454"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">&quot;Order request must be a JSON object.&quot;</span>
<a id="__codelineno-0-455" name="__codelineno-0-455"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<a id="__codelineno-0-456" name="__codelineno-0-456"></a> <span class="k">return</span> <span class="n">parsed</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
@@ -1987,8 +1987,7 @@ JSON object.</p>
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/utils.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-397">397</a></span>
<span class="normal"><a href="#__codelineno-0-398">398</a></span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-398">398</a></span>
<span class="normal"><a href="#__codelineno-0-399">399</a></span>
<span class="normal"><a href="#__codelineno-0-400">400</a></span>
<span class="normal"><a href="#__codelineno-0-401">401</a></span>
@@ -2008,28 +2007,29 @@ JSON object.</p>
<span class="normal"><a href="#__codelineno-0-415">415</a></span>
<span class="normal"><a href="#__codelineno-0-416">416</a></span>
<span class="normal"><a href="#__codelineno-0-417">417</a></span>
<span class="normal"><a href="#__codelineno-0-418">418</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-397" name="__codelineno-0-397"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_tick_flags</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">object</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-0-398" name="__codelineno-0-398"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse tick flags string or integer value.</span>
<a id="__codelineno-0-399" name="__codelineno-0-399"></a>
<a id="__codelineno-0-400" name="__codelineno-0-400"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-401" name="__codelineno-0-401"></a><span class="sd"> value: Tick flag name (ALL, INFO, TRADE, COPY_TICKS_*) or integer value.</span>
<a id="__codelineno-0-402" name="__codelineno-0-402"></a>
<a id="__codelineno-0-403" name="__codelineno-0-403"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-404" name="__codelineno-0-404"></a><span class="sd"> Integer tick flag value compatible with MetaTrader 5 ``COPY_TICKS_*``.</span>
<a id="__codelineno-0-405" name="__codelineno-0-405"></a>
<a id="__codelineno-0-406" name="__codelineno-0-406"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-407" name="__codelineno-0-407"></a><span class="sd"> ValueError: If the flag is invalid.</span>
<a id="__codelineno-0-408" name="__codelineno-0-408"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-409" name="__codelineno-0-409"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-410" name="__codelineno-0-410"></a> <span class="k">return</span> <span class="n">_parse_copy_ticks</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-411" name="__codelineno-0-411"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<a id="__codelineno-0-412" name="__codelineno-0-412"></a> <span class="n">display</span> <span class="o">=</span> <span class="n">value</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="nb">repr</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-413" name="__codelineno-0-413"></a> <span class="n">valid</span> <span class="o">=</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">_TICK_FLAG_NAMES</span><span class="p">)</span>
<a id="__codelineno-0-414" name="__codelineno-0-414"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-415" name="__codelineno-0-415"></a> <span class="sa">f</span><span class="s2">&quot;Invalid tick flags: &#39;</span><span class="si">{</span><span class="n">display</span><span class="si">}</span><span class="s2">&#39;. &quot;</span>
<a id="__codelineno-0-416" name="__codelineno-0-416"></a> <span class="sa">f</span><span class="s2">&quot;Use one of: </span><span class="si">{</span><span class="n">valid</span><span class="si">}</span><span class="s2">, or a supported integer.&quot;</span>
<a id="__codelineno-0-417" name="__codelineno-0-417"></a> <span class="p">)</span>
<a id="__codelineno-0-418" name="__codelineno-0-418"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
<span class="normal"><a href="#__codelineno-0-418">418</a></span>
<span class="normal"><a href="#__codelineno-0-419">419</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-398" name="__codelineno-0-398"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_tick_flags</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">object</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-0-399" name="__codelineno-0-399"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse tick flags string or integer value.</span>
<a id="__codelineno-0-400" name="__codelineno-0-400"></a>
<a id="__codelineno-0-401" name="__codelineno-0-401"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-402" name="__codelineno-0-402"></a><span class="sd"> value: Tick flag name (ALL, INFO, TRADE, COPY_TICKS_*) or integer value.</span>
<a id="__codelineno-0-403" name="__codelineno-0-403"></a>
<a id="__codelineno-0-404" name="__codelineno-0-404"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-405" name="__codelineno-0-405"></a><span class="sd"> Integer tick flag value compatible with MetaTrader 5 ``COPY_TICKS_*``.</span>
<a id="__codelineno-0-406" name="__codelineno-0-406"></a>
<a id="__codelineno-0-407" name="__codelineno-0-407"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-408" name="__codelineno-0-408"></a><span class="sd"> ValueError: If the flag is invalid.</span>
<a id="__codelineno-0-409" name="__codelineno-0-409"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-410" name="__codelineno-0-410"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-411" name="__codelineno-0-411"></a> <span class="k">return</span> <span class="n">_parse_copy_ticks</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-412" name="__codelineno-0-412"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<a id="__codelineno-0-413" name="__codelineno-0-413"></a> <span class="n">display</span> <span class="o">=</span> <span class="n">value</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="nb">repr</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-414" name="__codelineno-0-414"></a> <span class="n">valid</span> <span class="o">=</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">_TICK_FLAG_NAMES</span><span class="p">)</span>
<a id="__codelineno-0-415" name="__codelineno-0-415"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-416" name="__codelineno-0-416"></a> <span class="sa">f</span><span class="s2">&quot;Invalid tick flags: &#39;</span><span class="si">{</span><span class="n">display</span><span class="si">}</span><span class="s2">&#39;. &quot;</span>
<a id="__codelineno-0-417" name="__codelineno-0-417"></a> <span class="sa">f</span><span class="s2">&quot;Use one of: </span><span class="si">{</span><span class="n">valid</span><span class="si">}</span><span class="s2">, or a supported integer.&quot;</span>
<a id="__codelineno-0-418" name="__codelineno-0-418"></a> <span class="p">)</span>
<a id="__codelineno-0-419" name="__codelineno-0-419"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
</code></pre></div></td></tr></table></div>
</details>
</div>
@@ -2131,8 +2131,7 @@ JSON object.</p>
<details class="mkdocstrings-source">
<summary>Source code in <code>mt5cli/utils.py</code></summary>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-373">373</a></span>
<span class="normal"><a href="#__codelineno-0-374">374</a></span>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-374">374</a></span>
<span class="normal"><a href="#__codelineno-0-375">375</a></span>
<span class="normal"><a href="#__codelineno-0-376">376</a></span>
<span class="normal"><a href="#__codelineno-0-377">377</a></span>
@@ -2152,28 +2151,29 @@ JSON object.</p>
<span class="normal"><a href="#__codelineno-0-391">391</a></span>
<span class="normal"><a href="#__codelineno-0-392">392</a></span>
<span class="normal"><a href="#__codelineno-0-393">393</a></span>
<span class="normal"><a href="#__codelineno-0-394">394</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-373" name="__codelineno-0-373"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_timeframe</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">object</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-0-374" name="__codelineno-0-374"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse a timeframe string or integer value.</span>
<a id="__codelineno-0-375" name="__codelineno-0-375"></a>
<a id="__codelineno-0-376" name="__codelineno-0-376"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-377" name="__codelineno-0-377"></a><span class="sd"> value: Timeframe name (e.g., &#39;M1&#39;, &#39;H1&#39;, &#39;D1&#39;) or integer value.</span>
<a id="__codelineno-0-378" name="__codelineno-0-378"></a>
<a id="__codelineno-0-379" name="__codelineno-0-379"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-380" name="__codelineno-0-380"></a><span class="sd"> Integer timeframe value.</span>
<a id="__codelineno-0-381" name="__codelineno-0-381"></a>
<a id="__codelineno-0-382" name="__codelineno-0-382"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-383" name="__codelineno-0-383"></a><span class="sd"> ValueError: If the timeframe is invalid.</span>
<a id="__codelineno-0-384" name="__codelineno-0-384"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-385" name="__codelineno-0-385"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-386" name="__codelineno-0-386"></a> <span class="k">return</span> <span class="n">_parse_timeframe</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-387" name="__codelineno-0-387"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<a id="__codelineno-0-388" name="__codelineno-0-388"></a> <span class="n">display</span> <span class="o">=</span> <span class="n">value</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="nb">repr</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-389" name="__codelineno-0-389"></a> <span class="n">valid</span> <span class="o">=</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">TIMEFRAME_NAMES</span><span class="p">)</span>
<a id="__codelineno-0-390" name="__codelineno-0-390"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-391" name="__codelineno-0-391"></a> <span class="sa">f</span><span class="s2">&quot;Invalid timeframe: &#39;</span><span class="si">{</span><span class="n">display</span><span class="si">}</span><span class="s2">&#39;. &quot;</span>
<a id="__codelineno-0-392" name="__codelineno-0-392"></a> <span class="sa">f</span><span class="s2">&quot;Use one of: </span><span class="si">{</span><span class="n">valid</span><span class="si">}</span><span class="s2">, or a supported integer.&quot;</span>
<a id="__codelineno-0-393" name="__codelineno-0-393"></a> <span class="p">)</span>
<a id="__codelineno-0-394" name="__codelineno-0-394"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
<span class="normal"><a href="#__codelineno-0-394">394</a></span>
<span class="normal"><a href="#__codelineno-0-395">395</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-374" name="__codelineno-0-374"></a><span class="k">def</span><span class="w"> </span><span class="nf">parse_timeframe</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">object</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-0-375" name="__codelineno-0-375"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Parse a timeframe string or integer value.</span>
<a id="__codelineno-0-376" name="__codelineno-0-376"></a>
<a id="__codelineno-0-377" name="__codelineno-0-377"></a><span class="sd"> Args:</span>
<a id="__codelineno-0-378" name="__codelineno-0-378"></a><span class="sd"> value: Timeframe name (e.g., &#39;M1&#39;, &#39;H1&#39;, &#39;D1&#39;) or integer value.</span>
<a id="__codelineno-0-379" name="__codelineno-0-379"></a>
<a id="__codelineno-0-380" name="__codelineno-0-380"></a><span class="sd"> Returns:</span>
<a id="__codelineno-0-381" name="__codelineno-0-381"></a><span class="sd"> Integer timeframe value.</span>
<a id="__codelineno-0-382" name="__codelineno-0-382"></a>
<a id="__codelineno-0-383" name="__codelineno-0-383"></a><span class="sd"> Raises:</span>
<a id="__codelineno-0-384" name="__codelineno-0-384"></a><span class="sd"> ValueError: If the timeframe is invalid.</span>
<a id="__codelineno-0-385" name="__codelineno-0-385"></a><span class="sd"> &quot;&quot;&quot;</span>
<a id="__codelineno-0-386" name="__codelineno-0-386"></a> <span class="k">try</span><span class="p">:</span>
<a id="__codelineno-0-387" name="__codelineno-0-387"></a> <span class="k">return</span> <span class="n">_parse_timeframe</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-388" name="__codelineno-0-388"></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<a id="__codelineno-0-389" name="__codelineno-0-389"></a> <span class="n">display</span> <span class="o">=</span> <span class="n">value</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="nb">repr</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<a id="__codelineno-0-390" name="__codelineno-0-390"></a> <span class="n">valid</span> <span class="o">=</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">TIMEFRAME_NAMES</span><span class="p">)</span>
<a id="__codelineno-0-391" name="__codelineno-0-391"></a> <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
<a id="__codelineno-0-392" name="__codelineno-0-392"></a> <span class="sa">f</span><span class="s2">&quot;Invalid timeframe: &#39;</span><span class="si">{</span><span class="n">display</span><span class="si">}</span><span class="s2">&#39;. &quot;</span>
<a id="__codelineno-0-393" name="__codelineno-0-393"></a> <span class="sa">f</span><span class="s2">&quot;Use one of: </span><span class="si">{</span><span class="n">valid</span><span class="si">}</span><span class="s2">, or a supported integer.&quot;</span>
<a id="__codelineno-0-394" name="__codelineno-0-394"></a> <span class="p">)</span>
<a id="__codelineno-0-395" name="__codelineno-0-395"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
</code></pre></div></td></tr></table></div>
</details>
</div>