Spaces:
Running
Running
| <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">=></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">&end=</span><span class="hl-3">${</span><span class="hl-4">end</span><span class="hl-3">}</span><span class="hl-2">&mkt_id=</span><span class="hl-3">${</span><span class="hl-4">mktId</span><span class="hl-3">}</span><span class="hl-2">&page=</span><span class="hl-3">${</span><span class="hl-4">p</span><span class="hl-3">}</span><span class="hl-2">&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">"trades_page_1.html"</span><span class="hl-1">), </span><span class="hl-4">firstHtml</span><span class="hl-1">, </span><span class="hl-2">"utf8"</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"> <= </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">"utf8"</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"> /<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"><</span><span class="hl-13">\/</span><span class="hl-17">tr>/</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"> /<td</span><span class="hl-18">[^</span><span class="hl-17">></span><span class="hl-18">]</span><span class="hl-19">*</span><span class="hl-17">></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"><</span><span class="hl-13">\/</span><span class="hl-17">td>/</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"> /<</span><span class="hl-18">[^</span><span class="hl-17">></span><span class="hl-18">]</span><span class="hl-19">+</span><span class="hl-17">>/</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">" "</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">" "</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"> < </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">""</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">""</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">"sha1"</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">"hex"</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">=></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">"backtest-kit"</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">"../schema/Candle.schema"</span><span class="hl-1">;</span><br/><br/><span class="hl-5">import</span><span class="hl-1"> </span><span class="hl-2">"../config/setup"</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">"mongo-exchange"</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">=></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">=></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">"name"</span><span class="hl-1">: </span><span class="hl-2">"backtest-kit-project"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"version"</span><span class="hl-1">: </span><span class="hl-2">"1.0.0"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"description"</span><span class="hl-1">: </span><span class="hl-2">"Backtest Kit trading bot project"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"main"</span><span class="hl-1">: </span><span class="hl-2">"index.js"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"homepage"</span><span class="hl-1">: </span><span class="hl-2">"https://backtest-kit.github.io/documents/article_07_ai_news_trading_signals.html"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"scripts"</span><span class="hl-1">: {</span><br/><span class="hl-1"> </span><span class="hl-16">"start"</span><span class="hl-1">: </span><span class="hl-2">"node ./node_modules/@backtest-kit/cli/build/index.mjs --editor"</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-16">"keywords"</span><span class="hl-1">: [],</span><br/><span class="hl-1"> </span><span class="hl-16">"author"</span><span class="hl-1">: </span><span class="hl-2">""</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"license"</span><span class="hl-1">: </span><span class="hl-2">"ISC"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"type"</span><span class="hl-1">: </span><span class="hl-2">"commonjs"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"dependencies"</span><span class="hl-1">: {</span><br/><span class="hl-1"> </span><span class="hl-16">"@backtest-kit/cli"</span><span class="hl-1">: </span><span class="hl-2">"^7.1.0"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"@backtest-kit/graph"</span><span class="hl-1">: </span><span class="hl-2">"^7.1.0"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"@backtest-kit/pinets"</span><span class="hl-1">: </span><span class="hl-2">"^7.1.0"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"@backtest-kit/ui"</span><span class="hl-1">: </span><span class="hl-2">"^7.1.0"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"agent-swarm-kit"</span><span class="hl-1">: </span><span class="hl-2">"^2.5.1"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"backtest-kit"</span><span class="hl-1">: </span><span class="hl-2">"^7.1.0"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"functools-kit"</span><span class="hl-1">: </span><span class="hl-2">"^2.2.0"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"garch"</span><span class="hl-1">: </span><span class="hl-2">"^1.2.3"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"get-moment-stamp"</span><span class="hl-1">: </span><span class="hl-2">"^1.1.2"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"mongoose"</span><span class="hl-1">: </span><span class="hl-2">"^8.23.0"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"ollama"</span><span class="hl-1">: </span><span class="hl-2">"^0.6.3"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"playwright"</span><span class="hl-1">: </span><span class="hl-2">"^1.59.1"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-16">"volume-anomaly"</span><span class="hl-1">: </span><span class="hl-2">"^1.2.3"</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'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> | |