backtest-kit-docs / documents /article_09_pinescript_local_markets.html
tripolskypetr's picture
patch
615c2b5
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>article/09_pinescript_local_markets | backtest-kit</title><meta name="description" content="Documentation for backtest-kit"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">backtest-kit</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">backtest-kit</a></li><li><a href="article_09_pinescript_local_markets.html">article/09_pinescript_local_markets</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="🌲-running-pine-script-on-exchanges-without-tradingview" class="tsd-anchor"></a><h1 class="tsd-anchor-link">🌲 Running Pine Script on Exchanges Without TradingView<a href="#🌲-running-pine-script-on-exchanges-without-tradingview" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><blockquote>
<p>The source code discussed in this article is <a href="https://github.com/backtest-kit/uzse-backtest-app">published in this repository</a></p>
</blockquote>
<p><img src="../media/pine_markets_cover.jpg" alt=""></p>
<p>The Pine Script ecosystem contains a huge number of technical analysis tools. However, TradingView itself is not available everywhere. For example, regional stock exchanges of emerging markets that are simply not on TradingView at all — no data, no trading.</p>
<ul>
<li>MSE (Mongolia) — not available</li>
<li>UZSE (Uzbekistan) — not available</li>
<li>DSE (Dhaka, Bangladesh) — not available</li>
<li>GSE (Ghana) — not available</li>
<li>SGBV (Algeria) — not available</li>
<li>BSE (Botswana) — not available</li>
<li>ESE (Eswatini) — not available</li>
<li>MERJ (Seychelles) — not available</li>
</ul>
<a id="why-not-just-use-their-websites" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Why Not Just Use Their Websites?<a href="#why-not-just-use-their-websites" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>When instead of a clear price chart I see raw aggregate trades with the ability to download only one month in Excel (given a 6-hour trading day and constant holidays), I feel blind. The registration button leads nowhere.</p>
<p><img src="../media/pine_markets_raw_trades.png" alt=""></p>
<p>Beyond the price chart, to avoid being limited to standard Excel, I wanted to apply the full range of Open Source tools rather than reinventing the wheel.</p>
<p><img src="../media/pine_markets_excel.png" alt=""></p>
<a id="building-candles-from-executed-trades" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Building Candles from Executed Trades<a href="#building-candles-from-executed-trades" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>The first script downloads pages with trades. Excel could have been used, but it doesn't include minutes:</p>
<pre><code class="typescript"><span class="hl-3">async</span><span class="hl-1"> </span><span class="hl-3">function</span><span class="hl-1"> </span><span class="hl-0">main</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-0">buildUrl</span><span class="hl-1"> = (</span><span class="hl-4">p</span><span class="hl-1">: </span><span class="hl-11">number</span><span class="hl-1">) </span><span class="hl-3">=&gt;</span><br/><span class="hl-1"> </span><span class="hl-2">`https://uzse.uz/trade_results?begin=</span><span class="hl-3">${</span><span class="hl-4">begin</span><span class="hl-3">}</span><span class="hl-2">&amp;end=</span><span class="hl-3">${</span><span class="hl-4">end</span><span class="hl-3">}</span><span class="hl-2">&amp;mkt_id=</span><span class="hl-3">${</span><span class="hl-4">mktId</span><span class="hl-3">}</span><span class="hl-2">&amp;page=</span><span class="hl-3">${</span><span class="hl-4">p</span><span class="hl-3">}</span><span class="hl-2">&amp;search_key=</span><span class="hl-3">${</span><span class="hl-4">symbol</span><span class="hl-3">}</span><span class="hl-2">`</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">browser</span><span class="hl-1"> = </span><span class="hl-5">await</span><span class="hl-1"> </span><span class="hl-4">chromium</span><span class="hl-1">.</span><span class="hl-0">launch</span><span class="hl-1">({ </span><span class="hl-4">headless:</span><span class="hl-1"> </span><span class="hl-3">true</span><span class="hl-1"> });</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">page</span><span class="hl-1"> = </span><span class="hl-5">await</span><span class="hl-1"> </span><span class="hl-4">browser</span><span class="hl-1">.</span><span class="hl-0">newPage</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">firstHtml</span><span class="hl-1"> = </span><span class="hl-5">await</span><span class="hl-1"> </span><span class="hl-0">fetchPage</span><span class="hl-1">(</span><span class="hl-4">page</span><span class="hl-1">, </span><span class="hl-0">buildUrl</span><span class="hl-1">(</span><span class="hl-7">1</span><span class="hl-1">));</span><br/><span class="hl-1"> </span><span class="hl-4">fs</span><span class="hl-1">.</span><span class="hl-0">writeFileSync</span><span class="hl-1">(</span><span class="hl-4">path</span><span class="hl-1">.</span><span class="hl-0">join</span><span class="hl-1">(</span><span class="hl-8">TMP_DIR</span><span class="hl-1">, </span><span class="hl-2">&quot;trades_page_1.html&quot;</span><span class="hl-1">), </span><span class="hl-4">firstHtml</span><span class="hl-1">, </span><span class="hl-2">&quot;utf8&quot;</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">totalPages</span><span class="hl-1"> = </span><span class="hl-0">getLastPage</span><span class="hl-1">(</span><span class="hl-4">firstHtml</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`Total pages: </span><span class="hl-3">${</span><span class="hl-4">totalPages</span><span class="hl-3">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-5">for</span><span class="hl-1"> (</span><span class="hl-3">let</span><span class="hl-1"> </span><span class="hl-4">p</span><span class="hl-1"> = </span><span class="hl-7">2</span><span class="hl-1">; </span><span class="hl-4">p</span><span class="hl-1"> &lt;= </span><span class="hl-4">totalPages</span><span class="hl-1">; </span><span class="hl-4">p</span><span class="hl-1">++) {</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">html</span><span class="hl-1"> = </span><span class="hl-5">await</span><span class="hl-1"> </span><span class="hl-0">fetchPage</span><span class="hl-1">(</span><span class="hl-4">page</span><span class="hl-1">, </span><span class="hl-0">buildUrl</span><span class="hl-1">(</span><span class="hl-4">p</span><span class="hl-1">));</span><br/><span class="hl-1"> </span><span class="hl-4">fs</span><span class="hl-1">.</span><span class="hl-0">writeFileSync</span><span class="hl-1">(</span><span class="hl-4">path</span><span class="hl-1">.</span><span class="hl-0">join</span><span class="hl-1">(</span><span class="hl-8">TMP_DIR</span><span class="hl-1">, </span><span class="hl-2">`trades_page_</span><span class="hl-3">${</span><span class="hl-4">p</span><span class="hl-3">}</span><span class="hl-2">.html`</span><span class="hl-1">), </span><span class="hl-4">html</span><span class="hl-1">, </span><span class="hl-2">&quot;utf8&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`Downloaded page </span><span class="hl-3">${</span><span class="hl-4">p</span><span class="hl-3">}</span><span class="hl-2">/</span><span class="hl-3">${</span><span class="hl-4">totalPages</span><span class="hl-3">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-5">await</span><span class="hl-1"> </span><span class="hl-4">browser</span><span class="hl-1">.</span><span class="hl-0">close</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-4">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`Done. HTML saved to </span><span class="hl-3">${</span><span class="hl-8">TMP_DIR</span><span class="hl-3">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<p>The second script imports into MongoDB:</p>
<pre><code class="typescript"><span class="hl-3">function</span><span class="hl-1"> </span><span class="hl-0">parseHtmlTable</span><span class="hl-1">(</span><span class="hl-4">html</span><span class="hl-1">: </span><span class="hl-11">string</span><span class="hl-1">, </span><span class="hl-4">pageIndex</span><span class="hl-1">: </span><span class="hl-11">number</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">rows</span><span class="hl-1">: </span><span class="hl-11">object</span><span class="hl-1">[] = [];</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">trRegex</span><span class="hl-1"> =</span><span class="hl-17"> /&lt;tr</span><span class="hl-18">[</span><span class="hl-17">\s\S</span><span class="hl-18">]</span><span class="hl-19">*?</span><span class="hl-17">&lt;</span><span class="hl-13">\/</span><span class="hl-17">tr&gt;/</span><span class="hl-3">gi</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">tdRegex</span><span class="hl-1"> =</span><span class="hl-17"> /&lt;td</span><span class="hl-18">[^</span><span class="hl-17">&gt;</span><span class="hl-18">]</span><span class="hl-19">*</span><span class="hl-17">&gt;</span><span class="hl-18">([</span><span class="hl-17">\s\S</span><span class="hl-18">]</span><span class="hl-19">*?</span><span class="hl-18">)</span><span class="hl-17">&lt;</span><span class="hl-13">\/</span><span class="hl-17">td&gt;/</span><span class="hl-3">gi</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">tagRegex</span><span class="hl-1"> =</span><span class="hl-17"> /&lt;</span><span class="hl-18">[^</span><span class="hl-17">&gt;</span><span class="hl-18">]</span><span class="hl-19">+</span><span class="hl-17">&gt;/</span><span class="hl-3">g</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-3">let</span><span class="hl-1"> </span><span class="hl-4">rowIndex</span><span class="hl-1"> = </span><span class="hl-7">0</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">urlKey</span><span class="hl-1"> = </span><span class="hl-0">extractUrlKey</span><span class="hl-1">(</span><span class="hl-4">html</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-3">let</span><span class="hl-1"> </span><span class="hl-4">trMatch</span><span class="hl-1">: </span><span class="hl-11">RegExpExecArray</span><span class="hl-1"> | </span><span class="hl-11">null</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">while</span><span class="hl-1"> ((</span><span class="hl-4">trMatch</span><span class="hl-1"> = </span><span class="hl-4">trRegex</span><span class="hl-1">.</span><span class="hl-0">exec</span><span class="hl-1">(</span><span class="hl-4">html</span><span class="hl-1">)) !== </span><span class="hl-3">null</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">rowHtml</span><span class="hl-1"> = </span><span class="hl-4">trMatch</span><span class="hl-1">[</span><span class="hl-7">0</span><span class="hl-1">];</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">cells</span><span class="hl-1">: </span><span class="hl-11">string</span><span class="hl-1">[] = [];</span><br/><span class="hl-1"> </span><span class="hl-3">let</span><span class="hl-1"> </span><span class="hl-4">tdMatch</span><span class="hl-1">: </span><span class="hl-11">RegExpExecArray</span><span class="hl-1"> | </span><span class="hl-11">null</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-5">while</span><span class="hl-1"> ((</span><span class="hl-4">tdMatch</span><span class="hl-1"> = </span><span class="hl-4">tdRegex</span><span class="hl-1">.</span><span class="hl-0">exec</span><span class="hl-1">(</span><span class="hl-4">rowHtml</span><span class="hl-1">)) !== </span><span class="hl-3">null</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">cells</span><span class="hl-1">.</span><span class="hl-0">push</span><span class="hl-1">(</span><span class="hl-4">tdMatch</span><span class="hl-1">[</span><span class="hl-7">1</span><span class="hl-1">].</span><span class="hl-0">replace</span><span class="hl-1">(</span><span class="hl-4">tagRegex</span><span class="hl-1">, </span><span class="hl-2">&quot; &quot;</span><span class="hl-1">).</span><span class="hl-0">replace</span><span class="hl-1">(</span><span class="hl-17">/\s</span><span class="hl-19">+</span><span class="hl-17">/</span><span class="hl-3">g</span><span class="hl-1">, </span><span class="hl-2">&quot; &quot;</span><span class="hl-1">).</span><span class="hl-0">trim</span><span class="hl-1">());</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> </span><span class="hl-5">if</span><span class="hl-1"> (</span><span class="hl-4">cells</span><span class="hl-1">.</span><span class="hl-4">length</span><span class="hl-1"> &lt; </span><span class="hl-7">10</span><span class="hl-1">) </span><span class="hl-5">continue</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">symbolParts</span><span class="hl-1"> = </span><span class="hl-4">cells</span><span class="hl-1">[</span><span class="hl-7">2</span><span class="hl-1">].</span><span class="hl-0">split</span><span class="hl-1">(</span><span class="hl-17">/\s</span><span class="hl-19">+</span><span class="hl-17">/</span><span class="hl-1">).</span><span class="hl-0">filter</span><span class="hl-1">(</span><span class="hl-4">Boolean</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">volumeParts</span><span class="hl-1"> = </span><span class="hl-4">cells</span><span class="hl-1">[</span><span class="hl-7">9</span><span class="hl-1">].</span><span class="hl-0">split</span><span class="hl-1">(</span><span class="hl-17">/\s</span><span class="hl-19">+</span><span class="hl-17">/</span><span class="hl-1">).</span><span class="hl-0">filter</span><span class="hl-1">(</span><span class="hl-4">Boolean</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">time</span><span class="hl-1"> = </span><span class="hl-0">parseRuDate</span><span class="hl-1">(</span><span class="hl-4">cells</span><span class="hl-1">[</span><span class="hl-7">0</span><span class="hl-1">]);</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">symbol</span><span class="hl-1"> = </span><span class="hl-4">symbolParts</span><span class="hl-1">[</span><span class="hl-7">0</span><span class="hl-1">] ?? </span><span class="hl-2">&quot;&quot;</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">tradePrice</span><span class="hl-1"> = </span><span class="hl-0">parseNumber</span><span class="hl-1">(</span><span class="hl-4">cells</span><span class="hl-1">[</span><span class="hl-7">7</span><span class="hl-1">]);</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">quantity</span><span class="hl-1"> = </span><span class="hl-0">parseNumber</span><span class="hl-1">(</span><span class="hl-4">cells</span><span class="hl-1">[</span><span class="hl-7">8</span><span class="hl-1">]);</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">volume</span><span class="hl-1"> = </span><span class="hl-0">parseNumber</span><span class="hl-1">(</span><span class="hl-4">volumeParts</span><span class="hl-1">[</span><span class="hl-4">volumeParts</span><span class="hl-1">.</span><span class="hl-4">length</span><span class="hl-1"> - </span><span class="hl-7">1</span><span class="hl-1">] ?? </span><span class="hl-2">&quot;&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">hash</span><span class="hl-1"> = </span><span class="hl-4">crypto</span><br/><span class="hl-1"> .</span><span class="hl-0">createHash</span><span class="hl-1">(</span><span class="hl-2">&quot;sha1&quot;</span><span class="hl-1">)</span><br/><span class="hl-1"> .</span><span class="hl-0">update</span><span class="hl-1">(</span><span class="hl-2">`</span><span class="hl-3">${</span><span class="hl-4">symbol</span><span class="hl-3">}</span><span class="hl-2">|</span><span class="hl-3">${</span><span class="hl-4">time</span><span class="hl-9">?.</span><span class="hl-0">toISOString</span><span class="hl-9">()</span><span class="hl-3">}</span><span class="hl-2">|</span><span class="hl-3">${</span><span class="hl-4">tradePrice</span><span class="hl-3">}</span><span class="hl-2">|</span><span class="hl-3">${</span><span class="hl-4">quantity</span><span class="hl-3">}</span><span class="hl-2">|</span><span class="hl-3">${</span><span class="hl-4">volume</span><span class="hl-3">}</span><span class="hl-2">|</span><span class="hl-3">${</span><span class="hl-4">pageIndex</span><span class="hl-3">}</span><span class="hl-2">|</span><span class="hl-3">${</span><span class="hl-4">rowIndex</span><span class="hl-3">}</span><span class="hl-2">|</span><span class="hl-3">${</span><span class="hl-4">urlKey</span><span class="hl-3">}</span><span class="hl-2">`</span><span class="hl-1">)</span><br/><span class="hl-1"> .</span><span class="hl-0">digest</span><span class="hl-1">(</span><span class="hl-2">&quot;hex&quot;</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-4">rowIndex</span><span class="hl-1">++;</span><br/><span class="hl-1"> </span><span class="hl-4">rows</span><span class="hl-1">.</span><span class="hl-0">push</span><span class="hl-1">({ </span><span class="hl-4">time</span><span class="hl-1">, </span><span class="hl-4">symbol</span><span class="hl-1">, </span><span class="hl-4">issuer:</span><span class="hl-1"> </span><span class="hl-4">cells</span><span class="hl-1">[</span><span class="hl-7">3</span><span class="hl-1">], </span><span class="hl-4">securityType:</span><span class="hl-1"> </span><span class="hl-4">cells</span><span class="hl-1">[</span><span class="hl-7">4</span><span class="hl-1">], </span><span class="hl-4">market:</span><span class="hl-1"> </span><span class="hl-4">cells</span><span class="hl-1">[</span><span class="hl-7">5</span><span class="hl-1">], </span><span class="hl-4">platform:</span><span class="hl-1"> </span><span class="hl-4">cells</span><span class="hl-1">[</span><span class="hl-7">6</span><span class="hl-1">], </span><span class="hl-4">tradePrice</span><span class="hl-1">, </span><span class="hl-4">quantity</span><span class="hl-1">, </span><span class="hl-4">volume</span><span class="hl-1">, </span><span class="hl-4">hash</span><span class="hl-1"> });</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> </span><span class="hl-5">return</span><span class="hl-1"> </span><span class="hl-4">rows</span><span class="hl-1">.</span><span class="hl-0">filter</span><span class="hl-1">((</span><span class="hl-4">r</span><span class="hl-1">: </span><span class="hl-11">any</span><span class="hl-1">) </span><span class="hl-3">=&gt;</span><span class="hl-1"> </span><span class="hl-4">r</span><span class="hl-1">.</span><span class="hl-4">time</span><span class="hl-1"> !== </span><span class="hl-3">null</span><span class="hl-1">);</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<a id="seeing-the-chart" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Seeing the Chart<a href="#seeing-the-chart" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p><img src="../media/pine_markets_chart.jpg" alt=""></p>
<p><strong>Trading was halted for a week from 12.08.2023 to 21.08.2023</strong>. It looks alarming, so we ask Claude what happened during that period. We get a reasoned answer with references.</p>
<p><strong>Reason for the crash:</strong> an additional share issuance that tripled the authorized capital.</p>
<p>At the annual general meeting of shareholders on May 26, 2023, a decision was made to increase the bank's authorized capital from 107.77 billion soums to 323.32 billion soums — <strong>i.e. approximately 3x</strong> — through retained earnings. The new share issue was registered by the regulator on August 7, 2023.</p>
<p>The shares were placed through a private subscription among existing shareholders included in the register, formed on the 10th day from the date of state registration of the issue — meaning the register was fixed approximately <strong>on August 17, 2023</strong>.</p>
<p>The profit is not paid out in cash but is converted into shares.</p>
<a id="looking-at-technical-analysis" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Looking at Technical Analysis<a href="#looking-at-technical-analysis" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p><img src="../media/pine_markets_indicator.png" alt=""></p>
<p>I picked the first indicator I came across. <strong>It seems we sell at the red bearish line price and buy at the green bullish one</strong>. The important thing is that the complex visualization worked.</p>
<p><img src="../media/pine_markets_history.png" alt=""></p>
<p>You can also view the history. It is visible that the price moved far above <code>SMA(20)</code> several times. <strong>The same pattern: several days without trading before it.</strong> Looks like a <code>single-price auction day</code>.</p>
<a id="how-to-connect-candles" class="tsd-anchor"></a><h2 class="tsd-anchor-link">How to Connect Candles<a href="#how-to-connect-candles" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>File <code>./modules/editor.module.ts</code>:</p>
<pre><code class="typescript"><span class="hl-5">import</span><span class="hl-1"> { </span><span class="hl-4">addExchangeSchema</span><span class="hl-1"> } </span><span class="hl-5">from</span><span class="hl-1"> </span><span class="hl-2">&quot;backtest-kit&quot;</span><span class="hl-1">;</span><br/><span class="hl-5">import</span><span class="hl-1"> { </span><span class="hl-4">CandleModel</span><span class="hl-1"> } </span><span class="hl-5">from</span><span class="hl-1"> </span><span class="hl-2">&quot;../schema/Candle.schema&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-5">import</span><span class="hl-1"> </span><span class="hl-2">&quot;../config/setup&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-0">addExchangeSchema</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-4">exchangeName:</span><span class="hl-1"> </span><span class="hl-2">&quot;mongo-exchange&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">getCandles</span><span class="hl-4">:</span><span class="hl-1"> </span><span class="hl-3">async</span><span class="hl-1"> (</span><span class="hl-4">symbol</span><span class="hl-1">, </span><span class="hl-4">interval</span><span class="hl-1">, </span><span class="hl-4">since</span><span class="hl-1">, </span><span class="hl-4">limit</span><span class="hl-1">) </span><span class="hl-3">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-8">candles</span><span class="hl-1"> = </span><span class="hl-5">await</span><span class="hl-1"> </span><span class="hl-4">CandleModel</span><span class="hl-1">.</span><span class="hl-0">find</span><span class="hl-1">(</span><br/><span class="hl-1"> { </span><span class="hl-4">symbol</span><span class="hl-1">, </span><span class="hl-4">interval</span><span class="hl-1">, </span><span class="hl-4">timestamp:</span><span class="hl-1"> { </span><span class="hl-4">$gte:</span><span class="hl-1"> </span><span class="hl-4">since</span><span class="hl-1">.</span><span class="hl-0">getTime</span><span class="hl-1">() } },</span><br/><span class="hl-1"> { </span><span class="hl-4">timestamp:</span><span class="hl-1"> </span><span class="hl-7">1</span><span class="hl-1">, </span><span class="hl-4">open:</span><span class="hl-1"> </span><span class="hl-7">1</span><span class="hl-1">, </span><span class="hl-4">high:</span><span class="hl-1"> </span><span class="hl-7">1</span><span class="hl-1">, </span><span class="hl-4">low:</span><span class="hl-1"> </span><span class="hl-7">1</span><span class="hl-1">, </span><span class="hl-4">close:</span><span class="hl-1"> </span><span class="hl-7">1</span><span class="hl-1">, </span><span class="hl-4">volume:</span><span class="hl-1"> </span><span class="hl-7">1</span><span class="hl-1">, </span><span class="hl-4">_id:</span><span class="hl-1"> </span><span class="hl-7">0</span><span class="hl-1"> }</span><br/><span class="hl-1"> )</span><br/><span class="hl-1"> .</span><span class="hl-0">sort</span><span class="hl-1">({ </span><span class="hl-4">timestamp:</span><span class="hl-1"> </span><span class="hl-7">1</span><span class="hl-1"> })</span><br/><span class="hl-1"> .</span><span class="hl-0">limit</span><span class="hl-1">(</span><span class="hl-4">limit</span><span class="hl-1">)</span><br/><span class="hl-1"> .</span><span class="hl-0">lean</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-5">return</span><span class="hl-1"> </span><span class="hl-4">candles</span><span class="hl-1">.</span><span class="hl-0">map</span><span class="hl-1">(({ </span><span class="hl-4">timestamp</span><span class="hl-1">, </span><span class="hl-4">open</span><span class="hl-1">, </span><span class="hl-4">high</span><span class="hl-1">, </span><span class="hl-4">low</span><span class="hl-1">, </span><span class="hl-4">close</span><span class="hl-1">, </span><span class="hl-4">volume</span><span class="hl-1"> }) </span><span class="hl-3">=&gt;</span><span class="hl-1"> ({</span><br/><span class="hl-1"> </span><span class="hl-4">timestamp</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">open</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">high</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">low</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">close</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">volume</span><span class="hl-1">,</span><br/><span class="hl-1"> }));</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">});</span>
</code><button type="button">Copy</button></pre>
<a id="how-to-run" class="tsd-anchor"></a><h2 class="tsd-anchor-link">How to Run<a href="#how-to-run" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Via <code>npm start</code>:</p>
<pre><code class="json"><span class="hl-1">{</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;name&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;backtest-kit-project&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;version&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;1.0.0&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;description&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;Backtest Kit trading bot project&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;main&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;index.js&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;homepage&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;https://backtest-kit.github.io/documents/article_07_ai_news_trading_signals.html&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;scripts&quot;</span><span class="hl-1">: {</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;start&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;node ./node_modules/@backtest-kit/cli/build/index.mjs --editor&quot;</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;keywords&quot;</span><span class="hl-1">: [],</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;author&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;license&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;ISC&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;type&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;commonjs&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;dependencies&quot;</span><span class="hl-1">: {</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;@backtest-kit/cli&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;^7.1.0&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;@backtest-kit/graph&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;^7.1.0&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;@backtest-kit/pinets&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;^7.1.0&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;@backtest-kit/ui&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;^7.1.0&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;agent-swarm-kit&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;^2.5.1&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;backtest-kit&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;^7.1.0&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;functools-kit&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;^2.2.0&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;garch&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;^1.2.3&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;get-moment-stamp&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;^1.1.2&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;mongoose&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;^8.23.0&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;ollama&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;^0.6.3&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;playwright&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;^1.59.1&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">&quot;volume-anomaly&quot;</span><span class="hl-1">: </span><span class="hl-2">&quot;^1.2.3&quot;</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<a id="whats-interesting" class="tsd-anchor"></a><h2 class="tsd-anchor-link">What's Interesting<a href="#whats-interesting" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><ol>
<li>
<p><strong>Market participants cannot hire a Pine Script developer</strong></p>
<p>They are hard to find on the market and there is nowhere to place them: there is no TradingView infrastructure. Writing indicator visualizations is a technically complex task that AI will not solve — a human is needed.</p>
</li>
<li>
<p><strong>News sentiment does not affect stock prices</strong></p>
<p>An indicator is calibrated on historical data. Historical data becomes invalid if market sentiment has changed. <a href="https://www.gazeta.uz/ru/2026/04/17/ravshan-muhitdinov/">Uzbekistan news is not media-prominent</a>.</p>
</li>
<li>
<p><strong>Party policy is investment</strong></p>
<p>The only news source that affects sentiment is the president of the republic. He <a href="https://www.gazeta.uz/ru/2026/04/20/drugs/">called it a shared responsibility</a> of the entire international community to help such regions through investment in their economies and development.</p>
</li>
</ol>
<hr>
<p>You can read more <a href="article_07_ai_news_trading_signals.html">about the influence of news sentiment on the market</a>.</p>
<p><strong>This is exactly the reason why indicators stopped working on major markets: the new value of an indicator itself has become news.</strong></p>
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#🌲-running-pine-script-on-exchanges-without-tradingview"><span>🌲 <wbr/>Running <wbr/>Pine <wbr/>Script on <wbr/>Exchanges <wbr/>Without <wbr/>Trading<wbr/>View</span></a><ul><li><a href="#why-not-just-use-their-websites"><span>Why <wbr/>Not <wbr/>Just <wbr/>Use <wbr/>Their <wbr/>Websites?</span></a></li><li><a href="#building-candles-from-executed-trades"><span>Building <wbr/>Candles from <wbr/>Executed <wbr/>Trades</span></a></li><li><a href="#seeing-the-chart"><span>Seeing the <wbr/>Chart</span></a></li><li><a href="#looking-at-technical-analysis"><span>Looking at <wbr/>Technical <wbr/>Analysis</span></a></li><li><a href="#how-to-connect-candles"><span>How to <wbr/>Connect <wbr/>Candles</span></a></li><li><a href="#how-to-run"><span>How to <wbr/>Run</span></a></li><li><a href="#whats-interesting"><span>What&#39;s <wbr/>Interesting</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">backtest-kit</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
<!-- Yandex.Metrika counter -->
<script type="text/javascript">
(function(m,e,t,r,i,k,a){
m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)
})(window, document,'script','https://mc.yandex.ru/metrika/tag.js?id=105455585', 'ym');
ym(105455585, 'init', {ssr:true, webvisor:true, clickmap:true, ecommerce:"dataLayer", accurateTrackBounce:true, trackLinks:true});
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/105455585" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-3MQZEBBDDR"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-3MQZEBBDDR');
</script>