<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[TaiwanQuant's Newsletter]]></title><description><![CDATA[Quant Infrastructure. Mid-Frequency Trading. Crypto. Not financial advice.]]></description><link>https://www.taiwanquant.dev</link><image><url>https://substackcdn.com/image/fetch/$s_!XaHe!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F558c03e4-21f0-444e-81ee-dd8ec63150a8_1280x1280.png</url><title>TaiwanQuant&apos;s Newsletter</title><link>https://www.taiwanquant.dev</link></image><generator>Substack</generator><lastBuildDate>Fri, 03 Apr 2026 17:52:31 GMT</lastBuildDate><atom:link href="https://www.taiwanquant.dev/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[TaiwanQuant]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[taiwanquant@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[taiwanquant@substack.com]]></itunes:email><itunes:name><![CDATA[TaiwanQuant]]></itunes:name></itunes:owner><itunes:author><![CDATA[TaiwanQuant]]></itunes:author><googleplay:owner><![CDATA[taiwanquant@substack.com]]></googleplay:owner><googleplay:email><![CDATA[taiwanquant@substack.com]]></googleplay:email><googleplay:author><![CDATA[TaiwanQuant]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Post-Mortem: Losing Money At 36k-Feet Above Sea Level & How Not To]]></title><description><![CDATA[An all-rounded guide to an independent Quant's loss-prevention, error management, logistics, DevOps, and related.]]></description><link>https://www.taiwanquant.dev/p/post-mortem-losing-money-at-36k-feet</link><guid isPermaLink="false">https://www.taiwanquant.dev/p/post-mortem-losing-money-at-36k-feet</guid><dc:creator><![CDATA[TaiwanQuant]]></dc:creator><pubDate>Sun, 13 Aug 2023 16:12:40 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/fa8f25ce-cfaa-4112-a275-5af340fa9d0d_1536x2048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Picture this: you're about to board a 10-hour flight. As you board the plane (or maybe some time waiting at the gate), a notification pops up in your pocket. You're busy with other things, so you ignore it and forget about it (in fact, you're used to ignoring notifications because you thought at one point that's the only healthy way to approach them). Y&#8230;</p>
      <p>
          <a href="https://www.taiwanquant.dev/p/post-mortem-losing-money-at-36k-feet">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Realistic Backtester for Perpetual Futures (Part 2/2) (With Code)]]></title><description><![CDATA[A guide to writing a realistic market simulator for Crypto perpetual futures.]]></description><link>https://www.taiwanquant.dev/p/backtester-part-22-with-code</link><guid isPermaLink="false">https://www.taiwanquant.dev/p/backtester-part-22-with-code</guid><dc:creator><![CDATA[TaiwanQuant]]></dc:creator><pubDate>Sat, 29 Jul 2023 09:41:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!84LA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3360240d-c213-4fd1-8690-e467c7fae3e5_822x528.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!84LA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3360240d-c213-4fd1-8690-e467c7fae3e5_822x528.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!84LA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3360240d-c213-4fd1-8690-e467c7fae3e5_822x528.png 424w, https://substackcdn.com/image/fetch/$s_!84LA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3360240d-c213-4fd1-8690-e467c7fae3e5_822x528.png 848w, https://substackcdn.com/image/fetch/$s_!84LA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3360240d-c213-4fd1-8690-e467c7fae3e5_822x528.png 1272w, https://substackcdn.com/image/fetch/$s_!84LA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3360240d-c213-4fd1-8690-e467c7fae3e5_822x528.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!84LA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3360240d-c213-4fd1-8690-e467c7fae3e5_822x528.png" width="822" height="528" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3360240d-c213-4fd1-8690-e467c7fae3e5_822x528.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:528,&quot;width&quot;:822,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!84LA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3360240d-c213-4fd1-8690-e467c7fae3e5_822x528.png 424w, https://substackcdn.com/image/fetch/$s_!84LA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3360240d-c213-4fd1-8690-e467c7fae3e5_822x528.png 848w, https://substackcdn.com/image/fetch/$s_!84LA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3360240d-c213-4fd1-8690-e467c7fae3e5_822x528.png 1272w, https://substackcdn.com/image/fetch/$s_!84LA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3360240d-c213-4fd1-8690-e467c7fae3e5_822x528.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>(Part 2)</em></p><p>In <a href="https://taiwanquant.substack.com/p/backtester-part-12-with-code">Part 1</a>, we wrote a basic event-driven simulator/backtester using candle data. In this Part 2, we extend it to make the simulator realistic by adding costs and funding. We also add support for simulating an arbitrary number of markets simultaneously.</p><h1>Table of Contents</h1><p>Part 1:</p><ul><li><p>Introduction</p></li><li><p>Simulator/backtester architecture</p></li><li><p>Preparing the data</p></li><li><p>Simulating a single market</p></li><li><p>Simulating market orders</p></li></ul><p>Part 2:</p><ul><li><p>Simulating trading costs</p></li><li><p>Simulating funding</p></li><li><p>Simulating many markets</p></li><li><p>Finish</p></li><li><p>Subscriber materials (source code)</p></li></ul><h1>Simulating Trading Costs</h1>
      <p>
          <a href="https://www.taiwanquant.dev/p/backtester-part-22-with-code">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Realistic Backtester for Perpetual Futures (Part 1/2) (With Code)]]></title><description><![CDATA[A guide to writing a realistic market simulator for Crypto perpetual futures.]]></description><link>https://www.taiwanquant.dev/p/backtester-part-12-with-code</link><guid isPermaLink="false">https://www.taiwanquant.dev/p/backtester-part-12-with-code</guid><dc:creator><![CDATA[TaiwanQuant]]></dc:creator><pubDate>Sat, 29 Jul 2023 09:39:13 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Ze3J!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F916d5ce7-1f33-481f-92ea-41cdcfc32e89_825x528.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ze3J!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F916d5ce7-1f33-481f-92ea-41cdcfc32e89_825x528.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ze3J!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F916d5ce7-1f33-481f-92ea-41cdcfc32e89_825x528.png 424w, https://substackcdn.com/image/fetch/$s_!Ze3J!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F916d5ce7-1f33-481f-92ea-41cdcfc32e89_825x528.png 848w, https://substackcdn.com/image/fetch/$s_!Ze3J!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F916d5ce7-1f33-481f-92ea-41cdcfc32e89_825x528.png 1272w, https://substackcdn.com/image/fetch/$s_!Ze3J!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F916d5ce7-1f33-481f-92ea-41cdcfc32e89_825x528.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ze3J!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F916d5ce7-1f33-481f-92ea-41cdcfc32e89_825x528.png" width="825" height="528" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/916d5ce7-1f33-481f-92ea-41cdcfc32e89_825x528.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:528,&quot;width&quot;:825,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:41160,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ze3J!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F916d5ce7-1f33-481f-92ea-41cdcfc32e89_825x528.png 424w, https://substackcdn.com/image/fetch/$s_!Ze3J!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F916d5ce7-1f33-481f-92ea-41cdcfc32e89_825x528.png 848w, https://substackcdn.com/image/fetch/$s_!Ze3J!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F916d5ce7-1f33-481f-92ea-41cdcfc32e89_825x528.png 1272w, https://substackcdn.com/image/fetch/$s_!Ze3J!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F916d5ce7-1f33-481f-92ea-41cdcfc32e89_825x528.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Table of Contents</h1><p>Part 1:</p><ul><li><p>Introduction</p></li><li><p>Simulator/backtester architecture</p></li><li><p>Preparing the data</p></li><li><p>Simulating a single market</p></li><li><p>Simulating market orders</p></li></ul><p>Part 2:</p><ul><li><p>Simulating trading costs</p></li><li><p>Simulating funding</p></li><li><p>Simulating many markets</p></li><li><p>Finish</p></li><li><p>Subscriber materials (source code)</p></li></ul><h1>Introduction</h1><p>In the last article, we looked at how markets work and at simulating them in theory.</p><p>Today we w&#8230;</p>
      <p>
          <a href="https://www.taiwanquant.dev/p/backtester-part-12-with-code">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Announcement & 20%-off This Week]]></title><description><![CDATA[Thank you for your reading and support!]]></description><link>https://www.taiwanquant.dev/p/announcement-and-20-off-this-week</link><guid isPermaLink="false">https://www.taiwanquant.dev/p/announcement-and-20-off-this-week</guid><dc:creator><![CDATA[TaiwanQuant]]></dc:creator><pubDate>Wed, 12 Jul 2023 11:20:46 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/2724b3da-c0a2-40c3-9669-12e66f5f209b_1536x2048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello, Reader!</p><p>First, I want to thank all 417 of you for reading and the support to date. It&#8217;s been almost 3 months since we started this publication on Quant Infrastructure.</p><p>In that time we have covered many topics including about 70%-ish of the trading part that I had in mind when I began writing the series from a cafe in Tokyo. Some highlights that you thought were particularly valuable (I&#8217;m basing this on views and likes) include:</p><ul><li><p><a href="https://taiwanquant.substack.com/p/quant-infrastructure-3-storage">An extremely fast Time-Series Storage System</a></p></li><li><p><a href="https://taiwanquant.substack.com/p/quant-infrastructure-4-keeping-track">An Inventory component for tracking inventory</a></p></li><li><p><a href="https://taiwanquant.substack.com/p/quant-infrastructure-5-order-executor">An Order Executor component for managing limit orders</a></p></li></ul><p>Most importantly, the publication is no longer the vaporware that it was when we had one article back then. In addition to the already covered topics, we continue to regularly publish new articles and tutorials for Quant Infrastructure.</p><p>To reflect the new value of the publication, the price will increase for <strong>new subscribers</strong>.</p><p><strong>The price will not change for existing subscribers, however. </strong>Everyone currently subscribed will keep their current, lower rate. This will continue to remain true in the indefinite future for everybody. Thank you, guys!</p><p>In addition, anyone who got left out and wishes to subscribe can still get a 20%-off within the next 7 days:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://taiwanquant.substack.com/subscribe?coupon=9ce80d5b&quot;,&quot;text&quot;:&quot;Get 20% off for 1 year&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://taiwanquant.substack.com/subscribe?coupon=9ce80d5b"><span>Get 20% off for 1 year</span></a></p><p>Okay, I also wanted to write a bit about what&#8217;s coming in the future. On the surface, we will continue with the series. Those of you who read the last article will know that we will write a market simulator/backtester next.</p><p>However, you may have noticed I experimented a bit with the format recently. I&#8217;m gradually learning and figuring out how to improve the publication. Some of you have DMd me questions and ideas on Twitter and I&#8217;ve been keeping a list of ideas for articles that occurred to me in the course of the daily grind. </p><p>I&#8217;m aware this is very vague, but, what I&#8217;m trying to say is to expect more high-quality (and improving!) content in the future.</p><p>Thank you all for your reading and support and wishing you successful trading.</p><p>Cheers!</p><p>-TaiwanQuant</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://taiwanquant.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share TaiwanQuant&#8217;s Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://taiwanquant.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share TaiwanQuant&#8217;s Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Quant Infrastructure #6 - Simulating Markets - An Introduction]]></title><description><![CDATA[An introduction to simulating and backtesting markets for MFT and HFT.]]></description><link>https://www.taiwanquant.dev/p/quant-infrastructure-6-simulating</link><guid isPermaLink="false">https://www.taiwanquant.dev/p/quant-infrastructure-6-simulating</guid><dc:creator><![CDATA[TaiwanQuant]]></dc:creator><pubDate>Wed, 12 Jul 2023 09:11:47 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/11238f49-2c16-41b2-8fa9-de83bc077ef5_1536x2048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Table of Contents</h1><ul><li><p>Introduction</p></li><li><p>An Event-Driven Market Simulator</p></li><li><p>Market Internals &amp; The Order Book</p></li><li><p>Simulating MFT</p><ul><li><p>Market Orders</p></li><li><p>Limit Orders</p></li></ul></li><li><p>Simulating HFT</p></li><li><p>Conclusion</p></li></ul><h1>Introduction</h1><p>In the last article, we built an OrderExecutor component and looked at robustly managing limit orders on the exchange. In this article, we introduce the reader to market simulation. Future articles will cover writing a complete, event-driven backtester from candle data.</p><p>The article will introduce the concepts relevant to market simulation and lay the groundwork for writing our own simulator in a future article.</p><p>This is a broad topic so we will limit ourselves to the event-driven simulator we intend to write.</p><p>We will begin with a brief overview to look at what simulators are useful for (in addition to backtesting), and how we will use ours with the infrastructure covered so far in the series.</p><p>We will then look at the market internals of CEX Crypto exchanges, crucially the order book, to inform our understanding and intuition of how markets work. We will do this with the goal of simulating markets well and in a way that corresponds to reality &#8212; in addition to gaining a better understanding generally.</p><p>In the main part of the article, we will look at simulating a market using candlestick data. We will look at the challenges posed by candles, which lack much desirable information, and how to overcome them. We will focus on simulating realistic fill prices and a cost model for achieving this.</p><p>The last section briefly addresses concepts relevant to simulating HFT such as latency and the order book's order queue.</p><p>Crucially, our end goals are:</p><ol><li><p>To produce a reliable simulator which we understand and can therefore trust and which will be useful in practice.</p></li><li><p>To improve our understanding of markets.</p></li></ol><blockquote><p>By proxy, I also wish to save the reader from dealing with any headaches stemming from an unreliable one.</p></blockquote><p>As usual, our focus is on simplicity, robustness and correctness.</p><p>This article is an introduction and contains no code, which will come in the future.</p><p>Let's begin! <a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p>
      <p>
          <a href="https://www.taiwanquant.dev/p/quant-infrastructure-6-simulating">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Quant Infrastructure #5 - Order Executor]]></title><description><![CDATA[A guide to robust order tracking in a trading infrastructure.]]></description><link>https://www.taiwanquant.dev/p/quant-infrastructure-5-order-executor</link><guid isPermaLink="false">https://www.taiwanquant.dev/p/quant-infrastructure-5-order-executor</guid><dc:creator><![CDATA[TaiwanQuant]]></dc:creator><pubDate>Sat, 24 Jun 2023 02:55:50 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e6a997bd-dbaf-41f0-8e92-e1be9ed42bac_1536x2048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the previous article of the main series, we looked at robustly tracking our trading inventory and built an Inventory component for our Quant Infrastructure.</p><p>In this article, we look at tracking and managing orders and build an OrderExecutor for this purpose. Orders require a different approach from the Inventory because we actively control them as opposed to passively taking information from the exchange.</p><p>The technique we will show is commonly known as orders-in-flight. The implementation we will build will be simple and robust to errors, both theoretical and those encountered in practice during real trading.</p><p>We will address common problems such as duplicate orders and ghost orders and ensure that our order tracking is consistent with our inventory &#8212; which we covered in the previous article from the Inventory component&#8217;s side.</p><blockquote><p>For consistency, I assume the Inventory component is similar to what we described in the previous part of the series.</p></blockquote><p>Today&#8217;s article is free to read. As per usual, the complete source code is attached at the end of the article for paying subscribers.</p><p>We will use straightforward Rust to allow readers using other languages to follow and adapt the code to their language of choice relatively easily if they wish.</p><p>The article is exchange-agnostic and the techniques shown work on most if not all CEX exchanges such as Binance, Bybit, etc. I have not tested them with any DEXes, however &#8212; though I suspect they work there just as well.</p><p>Let&#8217;s begin.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.taiwanquant.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">TaiwanQuant&#8217;s Substack is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>
      <p>
          <a href="https://www.taiwanquant.dev/p/quant-infrastructure-5-order-executor">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Interlude - Precise Decimals In Quant Systems (Part 2/2) ]]></title><description><![CDATA[How to implement an efficient fixed-point decimal for high-frequency market data.]]></description><link>https://www.taiwanquant.dev/p/interlude-precise-decimals-in-quant-e21</link><guid isPermaLink="false">https://www.taiwanquant.dev/p/interlude-precise-decimals-in-quant-e21</guid><dc:creator><![CDATA[TaiwanQuant]]></dc:creator><pubDate>Fri, 16 Jun 2023 18:13:36 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/65537417-759f-4ddf-8588-2b012d41b6e5_1536x2048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Last week we covered the role and different implementations of precise decimals in a Quant trading system.</p><p>In this article, we show how to implement an efficient fixed-point decimal on top of a native integer. This implementation will be suitable for handling and storage of market data, particularly high-frequency order book data.</p><p>The technique is attractive to us for the following reasons:</p><ol><li><p>It is just as performant as regular integers for many operations.</p></li><li><p>It uses the same space and representation as a regular integer, usually 64 or 128 bits, which makes it possible to store it as such.</p></li><li><p>It is portable across languages, in particular, we can use it directly from Python and R.</p></li><li><p>To the best of my knowledge, it is the simplest, fastest and most memory-efficient representation of precise decimals.</p></li></ol><p>Its caveat is that it is constrained by range:</p><ol><li><p>The 64-bit variant with 8 decimal digits is suitable for Crypto futures markets.</p></li><li><p>The 128-bit variant with 16 decimal digits is preferred to cover spot markets due extreme cheapness of certain shitcoins.</p></li></ol><p>Here we implement the 64-bit variant. The 128-bit variant can be implemented in an analogous way or at the same time via generics/codegen.</p><p>The complete source code was released early with Subscriber Materials for Part 1. We attach it to the end of this article again for the reader&#8217;s convenience.</p><p>Let&#8217;s dive in.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p>
      <p>
          <a href="https://www.taiwanquant.dev/p/interlude-precise-decimals-in-quant-e21">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Interlude - Precise Decimals In Quant Systems (Part 1/2)]]></title><description><![CDATA[Dealing with decimal quantities in MFT and HFT trading systems - a practical overview.]]></description><link>https://www.taiwanquant.dev/p/interlude-precise-decimals-in-quant</link><guid isPermaLink="false">https://www.taiwanquant.dev/p/interlude-precise-decimals-in-quant</guid><dc:creator><![CDATA[TaiwanQuant]]></dc:creator><pubDate>Tue, 13 Jun 2023 12:19:01 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/81b9a0e5-9015-409f-a439-87a024884978_1536x2048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>From The Author</h1><p>A lot of new readers subscribed this week. Welcome, guys! Happy to have you here and I hope to make this publication worth your time.</p><p>To give some context for new readers. We&#8217;re currently doing component-level discussions and guides for Quant Infrastructure. The most recent articles have gone and will continue like this:</p><ol><li><p><em>Inventory </em>&#8212; robust inventory tracking (completed).</p></li><li><p><em>OrderExecutor </em>&#8212; limit order submission and management via orders-in-flight.</p></li><li><p><em>InstrumentStore </em>&#8212; keeping track of instruments traded by the system.</p></li></ol><p>There are also articles on a (very) performant time series data store and an exchange client. I have things planned for after and may do a poll to see what readers would like to see in the future.</p><p>This article is an interlude to the main series and deals with different kinds of precise decimals &#8212; we postponed the topic in previous articles. It is the first time we write an interlude in this format.</p><p>I hope that you will find this publication useful and thank you for your reading!</p><p>-TaiwanQuant</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://taiwanquant.substack.com/subscribe?coupon=ae3cd4d3&quot;,&quot;text&quot;:&quot;Get 10% off for 1 year&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://taiwanquant.substack.com/subscribe?coupon=ae3cd4d3"><span>Get 10% off for 1 year</span></a></p><h1>Introduction</h1><p>In today's article, we discuss the topic of precise decimal numbers in quantitative trading systems and implement a fast precise-decimal type suitable for handling and storage of high-frequency data.</p><p>We will mention where, why and how precise decimals are used and discuss tradeoffs between three different implementations from the perspective of Quant Infrastructure: two big-decimal types and a fast fixed-point type.</p><p>We will implement our own type that is suitable for simulating, trading, and storage of high-frequency order book data and is widely used in HFT. It is likewise useful in MFT and generally for Quant and trading systems. </p><p>This article is an interlude to the main infrastructure series. It is written, aside from the implementation part, as a high-level overview rather than a low-level guide, which is a departure from the main series. We also break character by addressing a topic that is closer to HFT rather than MFT.</p><blockquote><p>The article is written mainly from the perspective of MFT as that is where most of my work and experience is in.</p></blockquote><p>I expect this to be most useful to those readers handling or wishing to handle high-frequency data such as order book updates or ticker updates, or other kinds of market data for which preserving discreteness is required and thus floats are unsuitable. We will discuss when this occurs and how to approach these cases.</p><p>It will also be relevant to those concerned with the performance and robustness of their infrastructures in both HFT and MFT, especially wrt. simulation times and data store performance.</p><p>The article&#8217;s purpose is (1) to serve as an introductory and high-level overview of handling precise decimal quantities in Quant trading systems, and (2) to add a useful tool to our Quant engineering toolbox.</p><p>It is split into two parts:</p><ul><li><p>In Part 1 (this one) we make address the topic at a high level. The majority of our discussion is here.</p></li><li><p>In Part 2 we implement a performant decimal type for high-frequency order book data for MFT and HFT for this article&#8217;s Subscriber Materials.</p></li></ul><p>Part 2 will release in a few days up to a week. After that, we will resume the main line with the <em>OrderExecutor</em> article.</p><p>Let&#8217;s dive in.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p>
      <p>
          <a href="https://www.taiwanquant.dev/p/interlude-precise-decimals-in-quant">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Quant Infrastructure #4 - Keeping Track of Inventory]]></title><description><![CDATA[How to stay in sync with an asynchronous exchange.]]></description><link>https://www.taiwanquant.dev/p/quant-infrastructure-4-keeping-track</link><guid isPermaLink="false">https://www.taiwanquant.dev/p/quant-infrastructure-4-keeping-track</guid><dc:creator><![CDATA[TaiwanQuant]]></dc:creator><pubDate>Tue, 30 May 2023 00:00:05 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/170a0a80-cbcf-4425-9f70-1877688b601a_1536x2048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Trading on an exchange requires us to keep track of the state of our account and markets in close to real-time. Our trading infrastructure and the exchange run asynchronously with each other and communicate over the network, which is at times unreliable and always carries some latency.</p><p>Today we write a robust Inventory component for our Quant Infrastructure to correctly and reliably track the traded inventory on the exchange. We will maintain a local copy of all wallet assets and open positions and make it available to other components. Our Inventory will be exchange-agnostic and suitable for trading live as well as backtesting without any code changes and within the same infrastructure.</p><p>We will also address reliability problems encountered in the course of trading live on Crypto exchanges, which, to my knowledge, has not been done anywhere previously.</p><p>This is the first article out of three that cover the three core components of the trading part of the infrastructure: <em>InstrumentStore</em>, <em>Inventory</em> and <em>OrderExecutor</em>. We will cover these in the next few articles and make an interlude for fixed-point numbers. The next article will introduce the idea of orders-in-flight and show how to neatly handle limit orders in our Quant Infrastructure.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.taiwanquant.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">TaiwanQuant&#8217;s Substack is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>A typical trading loop on a Crypto CEX will see us passively ingest events from the exchange &#8212; usually through a WebSocket connection&#8212; which will carry updates about the state of our account, orders, traded instruments, prices, the order book, etc., whilst we occasionally make requests to the exchange via an HTTP API.</p><p>Robust tracking of state on the exchange carries some nuance:</p><ol><li><p>The data feed itself can malfunction. Events can be skipped, delayed, or arrive out of order.</p></li><li><p>When related entities are updated separately &#8212; as is typically the case with inventory and orders &#8212; the tracked local state can become inconsistent and cause erroneous behaviour by our infrastructure.</p></li></ol><blockquote><p>An example of erroneus trading caused by orders-inventory inconsistency:</p><p>Suppose we want to buy 1 BTC. We post an order and obtain a fill. The event with the filled order arrives so naively we think we no longer have an order posted; but the event about the new inventory hasn&#8217;t arrived yet. Between those two events, we may mistakenly think we don&#8217;t have the desired amount of BTC and don&#8217;t have an order posted and may mistakenly post another order and so on.</p></blockquote><p>We will address these issues in the article.</p><p>We will begin by defining the exchange events which we will ingest, followed by the implementation of a simple inventory component as a base case. Then, we will make our inventory component robust to errors. Last, we will show how we can handle the orders-inventory inconsistency.</p><p>Today&#8217;s article is free to read. The complete source code is available for paying subscribers in the Subscriber Materials section at the end of the article as per usual.</p><p>Let&#8217;s dive in.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p>
      <p>
          <a href="https://www.taiwanquant.dev/p/quant-infrastructure-4-keeping-track">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Quant Infrastructure #3 - Performant Time-Series Storage]]></title><description><![CDATA[A guide to an extremally fast and lightweight time-series data store.]]></description><link>https://www.taiwanquant.dev/p/quant-infrastructure-3-storage</link><guid isPermaLink="false">https://www.taiwanquant.dev/p/quant-infrastructure-3-storage</guid><dc:creator><![CDATA[TaiwanQuant]]></dc:creator><pubDate>Thu, 18 May 2023 19:45:14 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/c67cec09-39bc-46e9-a00a-af69e2336023_1536x2048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Today we look at storing and processing historical data.</p><p>We show a data store implementation suitable for loading arbitrary amounts of time-series data instantly (at hardware performance limit) to Python and Rust. The technique can be adapted to other languages. The basic implementation is very short at around 150 lines of code and is suitable for independent practitioners and Quant teams alike.</p><p>Broadly, the data store has three roles:</p><ol><li><p>Destination/warehouse for historical data.</p></li><li><p>Data source for research/exploration.</p></li><li><p>Data source for simulations/backtests.</p></li></ol><p>A good implementation is valuable because performance and capacity gains here will tend to translate into (usually non-linear) gains everywhere else &#8212; most importantly in research and backtesting.</p><p>For example, ideally, we would like data access to have as little friction as possible &#8212; ideally, we would like it to be instant and not have a size constraint of how much data we can handle at once. We would also like our backtests to not be bottlenecked by the data feed or for the data feed to take computing resources from the backtest.</p><p>This can be hard because computing resources are finite and easily exhausted by market data &#8212; to the point where some ideas are impractical or impossible to research even on the most expensive AWS machines. To make them possible we have to be smart about how we manage data.</p><p>Most Quants will start by doing this wrong &#8212; typically by reaching for a third-party database or a columnar data file format. In practice, a much better solution requires barely 150 lines of code and no third-party system.</p><blockquote><p>The databases are inadequate for the data sizes we need to work with. For example, a naive select query on a SQL database with 1e6 records (small by Quant standards &#8212; e.g. 1-minute data for a single perp contract) can easily take minutes to complete and parse rows into usable data types. We expect to commonly deal with 1e9 and higher at any one time.</p><p>Columnar data storage file formats such as Apache Parquet are much better here though still complicated and very slow vis-a-vis theoretical limits and the solution we describe here.</p></blockquote><p>Instead, we show a technique that addresses all of the earlier points. Loading of most data is instant and hardware resource usage minimal. Our system is able to run within a few percent of the maximum disk throughput. It is also much simpler and orders of magnitude more performant than most (all?) third-party alternatives.</p><p>The method is portable across programming languages, here Rust and Python.</p><p>To give a demonstration of what is possible, the following Python code:</p><pre><code>%%time
klines = read_klines('btc/usdt', 'futures', 'binance')
klines.shape</code></pre><p>takes this long to complete with the following result:</p><pre><code>CPU times: total: 0 ns
Wall time: 0 ns
(1926509,)</code></pre><p>Yes, that is 0 nanoseconds. The above code loads 1,926,509 1-minute candlesticks for Binance USD-stablecoin margined futures into a Numpy array in Python.</p><p>To show that our technique is fully usable, we compute the mean price and see again how long this takes:</p><pre><code><code>%%time
np.mean(klines['close'])</code></code></pre><p>results in:</p><pre><code>CPU times: total: 0 ns
Wall time: 10.3 ms
26704.60773270721</code></pre><p>This test was run on a mid-range computer from 3 years ago with an M.2 SSD.</p><p>We provide one more benchmark from Rust&#8217;s side, which is more relevant for backtesting. This time we load all BTC-quoted pairs from Binance Spot and compute an EWMA for each of them:</p><pre><code><code>EWMA all BTC pairs
---------------------------
Time       : 18.42 seconds
Klines     : 614098628
Throughput : 2798.56 MB/s
Klines/s   : 33346791.62 klines/s</code></code></pre><blockquote><p>I had redone the benchmark since the last article announcement after reminding myself that I had an Ethereum node syncing in the background and eating my I/O. The result is 2x the speed now compared to the last article&#8217;s announcement.</p></blockquote><p>As before, the complete source code is attached to the article for the reader&#8217;s benefit. The implementation is simple and takes around 150 lines of code.</p><p>The article itself is a commentary on architecture and a how-to guide. The reader should be able to easily extend the data store to support more data types based on his need, such as aggregated trades and order book updates. He should also be able to adapt the source code for his language of choice.</p><p>Let&#8217;s dive in.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p>
      <p>
          <a href="https://www.taiwanquant.dev/p/quant-infrastructure-3-storage">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Quant Infrastructure Series #2 - Exchange Client]]></title><description><![CDATA[A comprehensive guide to building a robust exchange client.]]></description><link>https://www.taiwanquant.dev/p/quant-infrastructure-series-2-exchange</link><guid isPermaLink="false">https://www.taiwanquant.dev/p/quant-infrastructure-series-2-exchange</guid><dc:creator><![CDATA[TaiwanQuant]]></dc:creator><pubDate>Sat, 06 May 2023 21:04:10 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/0fc66eb4-e957-4958-b0dc-3d10e3c02a0a_1536x2048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In today&#8217;s article, we build a robust API client for a CEX/hybrid exchange with the dual purpose of downloading historical data from it and &#8212; in the long term &#8212; trading. The method shown here is applicable across exchanges. We will use Binance Futures as an example.</p><p>This topic is a natural place to begin the series. As Quants, we need historical data to research and backtest ideas and exchanges expose large amounts of it via their APIs. Third-party clients often either do not exist or are subpar in one way or another.</p><p>The article is envisioned as a template/how-to guide for building an in-house client for exchanges that expose an HTTP API. This includes all common CEX and hybrid exchanges: Binance, Bybit, OKX, Kucoin, dYdX, etc.</p><p>For practical reasons, we seek to convey the idea rather than include every single line of code of the completed client.</p><p>The reader will be happy to learn that exchange APIs are very similar to each other such that being able to integrate Binance Futures means we are also able to integrate Bybit Spot and so on.</p><p>The article demonstrates how to write a client that is simple, understandable, robust to errors, and which we are able to trust, update, and fix when necessary. We think these properties are necessary if we want to use the client to trade real money, and if we value our time and want to stay maximally headache-free as Quants &#8212; at least on the infrastructure side.</p><p>We also lay the groundwork for the next article, which will show a performant storage system, which is the natural progression after a client used to download data.</p><p>In the long term, we plan to use the client to allow us to trade.</p><p>The complete source code in Rust will be available at the end of the article for paying subscribers.</p><blockquote><p>For completeness, other ways to acquire data include:</p><ol><li><p>Buy it from a vendor.</p></li><li><p>Record exchange&#8217;s live feeds. This method is rarely useful outside of HFT as the data needed usually spans years and so recording it is impractical for us.</p></li><li><p>Some exchanges will also make their data available for download outside the API. For example, here&#8217;s Binance&#8217;s <a href="https://www.binance.com/en/landing/data">public data catalogue</a> released recently.</p></li></ol></blockquote><p>Disclaimer: Trading is a risky endeavour and I am not responsible for any losses you may incur implementing ideas learnt through these articles.</p><p>Disclaimer: This is not financial advice.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://www.taiwanquant.dev/p/quant-infrastructure-series-2-exchange?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thank you for reading TaiwanQuant&#8217;s Substack. Share this post to support my work.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.taiwanquant.dev/p/quant-infrastructure-series-2-exchange?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.taiwanquant.dev/p/quant-infrastructure-series-2-exchange?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div>
      <p>
          <a href="https://www.taiwanquant.dev/p/quant-infrastructure-series-2-exchange">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Quant Infrastructure Series #1]]></title><description><![CDATA[An independent practicioner's introduction to building Quant Infrastructure.]]></description><link>https://www.taiwanquant.dev/p/quant-infrastructure-series-1</link><guid isPermaLink="false">https://www.taiwanquant.dev/p/quant-infrastructure-series-1</guid><dc:creator><![CDATA[TaiwanQuant]]></dc:creator><pubDate>Sun, 23 Apr 2023 07:29:45 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/af34ce4b-0445-4d66-afd2-1d1451c5607e_1536x2048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello reader. This is part 1 of a series on quant infrastructure. Before I get into the meat I want to talk briefly about what this series is, what it hopes to achieve for the reader, and also to introduce myself as I&#8217;m likely unknown to you.</p><p>This series will be a no-nonsense guide/walkaround to building your own quant infrastructure a.k.a. a trading bot for cryptocurrencies. It will be from a perspective of an independent practitioner. Independent, meaning our workflow is that of a person working alone. We like simplicity, robustness and flexibility. We dislike friction and spending time on maintenance preferring to use it on market research and exploration instead.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.taiwanquant.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading TaiwanQuant&#8217;s Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>The format will be that of a comprehensive discussion on the overall structure and then particular components. If the reader thinks he would prefer a step-by-step guide instead, he should not be overly discouraged as that may come in the future if it does not result directly from this discussion.</p><p>The goal is to become quickly useful to a motivated, intelligent person wishing to trade cryptocurrency (or other) markets without getting excessively bogged down in clerical programming work. Such a person should be able to use these articles to build robust quant infrastructure, and also to run and maintain it with relatively sparse time investment (thereby allowing more time to alpha (edge) research).</p><p>The infrastructure should be robust enough to allow for any mid-frequency (read: non-HFT) strategy regardless of the strategy&#8217;s particularities.</p><p>I also hope to supply the reader with insight on why certain components are the way they are and to save them from novice errors should they try to write a system without guidance or prior experience <strong>&#8212;</strong> something I&#8217;m guilty of and which has lost me both time and money in the past.</p><p>A prerequisite is that the reader is already competent in at least one programming language. Most code in these articles will be given in straightforward Rust with care taken to make it easily adaptable to other languages. Snippets related to research may also use Python.</p><p>I do not plan to discuss any currently profitable alphas (edges) in this series though we may discuss strategies for harnessing alphas and related topics.</p><blockquote><p>In summary this will be:</p><ol><li><p>A series of in-depth discussions on building quant infrastructure (a trading bot) from scratch.</p></li><li><p>From the perspective of an independent practicioner (see above).</p></li><li><p>We want a robust system that will allow us to trade any mid-frequency strategy without much additional effort.</p></li></ol></blockquote><p>Lastly to introduce myself: I&#8217;m an independent quant with a self-taught background, originally coming from software engineering. I&#8217;m active in cryptocurrency markets since mid-2021 and trading multiple alphas. Everything described here is a result of my learning and experience in this time and prior software engineering practice.</p><p>This is a good time to mention <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;HangukQuant&quot;,&quot;id&quot;:42788676,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/832ff818-a0d6-4be9-8e1e-acf6bb31cc52_5333x3000.jpeg&quot;,&quot;uuid&quot;:&quot;f9734290-a20b-47f9-a14f-84c80a175983&quot;}" data-component-name="MentionToDOM"></span> and <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Quant&#8217;s Substack&quot;,&quot;id&quot;:1392884,&quot;type&quot;:&quot;pub&quot;,&quot;url&quot;:&quot;https://open.substack.com/pub/quantarb&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/10d4d395-b09b-48b8-aac1-ce630d78e864_400x400.jpeg&quot;,&quot;uuid&quot;:&quot;a3ae37dc-a2fe-4741-ada9-0bdf468d3147&quot;}" data-component-name="MentionToDOM"></span> from whom I&#8217;ve learnt a lot and who are also the main inspiration behind these and hopefully future articles. If you somehow found me and did not find them, you should go look at them right now (or soon after finishing this article). They are top of their class and the best ones I know of when it comes to all things Quant.</p><p>Disclaimer: Trading is a risky endeavour and I am not responsible for any losses you may incur implementing ideas learnt through these articles.</p><p>Disclaimer: This is not financial advice.</p><h1>Bird&#8217;s Eye View of a Quant Infrastructure</h1><p>With the introductions behind us let&#8217;s look at what we&#8217;re getting into.</p><blockquote><p>Note from the author: we&#8217;re at the very first article and there&#8217;s a lot of room to experiment in terms of content, particularly based around reader interest. So if you, dear reader, have any requests or questions, you&#8217;re welcome to write them in a comment and I give you a reasonable chance it will be included.</p></blockquote><p>Today&#8217;s article will be a very broad one. I expect future articles should be much more specific.</p><p>As Quants, our work pipeline (unapologetically simplified) is generally speaking like so:</p><p>Research &#8594; Backtest &#8594; Trade</p><p>Here we&#8217;ll focus on the latter two steps and make appropriate references to Research when relevant. A good infrastructure should support our research and quickly allow us to test ideas and then trade them without any code changes.</p><p>To give an idea of what we&#8217;re aiming for at the end, below is a simplified (though still reasonably complete) structure for our bot. This is a bird&#8217;s eye view, we will go down into particular component-level details in future articles one by one.</p><p>To avoid overwhelming the reader at the very beginning, I stripped this down to basic components and assumed only one thread. In a production system, we do not want this so that exchange requests or other slow/fallible things don&#8217;t delay the processing of market events. For now, though, the simplified structure will suffice.</p><pre><code>// driver.rs

// Backtest and live trading is the same.

let instrument_store = ...;
let inventory = ...;
let order_executor = ...;
let statistics = ...;

// Notifications and commands for remote control. Here via Telegram.
let telegram = ...;

let strategy = PrintingFasterThanTheFed::new();

let feed = Feed::new();
let connector = ExchangeConnector::new(...);

connector.start_feed(feed);
connector.sync(instrument_store, inventory);

// An internal safety mechanism that will warn us if the system crashes.
let _on_quit = OnQuit(|| ...);

for event in feed {
  // Update state.
  instrument_store.on_event(event);
  inventory.on_event(event);
  order_executor.on_event(event);
  statistics.on_event(event);
  telegram.on_event(event);

  // Update strategy, potentially orders.
  strategy.on_event(event, instrument_store, inventory, ...);

  // Resync if we become out of sync with the exchange.
  if desync_detected {
    connector.sync(instrument_store, inventory);
  }

  // Do other updates such as fetching new instruments etc.
  ...
}</code></pre><p>So we&#8217;ll have the following components:</p><ul><li><p>Instrument store - this is what keeps track of traded instruments (coins)</p></li><li><p>Inventory - this is what keeps track of what positions and assets we currently have</p></li><li><p>Order executor - no explanation needed I think</p></li><li><p>Statistics - collects statistics</p></li><li><p>Telegram - handles notifications and commands on Telegram (you may use any other platform though Telegram is quite nice)</p></li><li><p>Connector - a connector to connect and translate our bot&#8217;s requests to and from the exchange</p></li></ul><p>Beyond that, we will need to write code to download and store historical data for our traded cryptocurrencies and exchanges. Then we&#8217;ll need to use it to simulate historical trading (aka. backtest). For this, we&#8217;ll also need two more components:</p><ul><li><p>Scraper</p></li><li><p>Storage</p></li></ul><p>Other common components include:</p><ul><li><p>Dashboard - for live visual information about our trading </p></li><li><p>Database - to record trades or historical event feed (.csv files tend to suffice)</p></li><li><p>Visualizer - for live visualization and exploration of data (an optional, standalone research tool)</p></li></ul><p>You&#8217;ve likely noticed we&#8217;re using an abstracted away <em>Connector</em> instead of a particular one for say Binance, Bybit or OKX. We want to start with this design in mind for three reasons:</p><ol><li><p>To allow us to trade any exchange we write a connector for (duh! obviously).</p></li><li><p>To avoid introducing idiosyncracies of any particular exchange throughout our infrastructure, which would make it difficult to add other exchanges.</p></li><li><p>Because of (2) we get to write a lot simpler code throughout pretty much all components as we can control the assumptions that we can make about our Connector.</p></li></ol><p>Okay, this will conclude today&#8217;s brief bird&#8217;s eye view of our Quant Trading System. It was short and frankly barely a sample.</p><p>In the next few articles, we will start building the foundation for our infrastructure. We will look at connecting to an exchange and scraping historical data from it. Binance is the obvious candidate. It also has a few quirks that we&#8217;ll cover.</p><p>After that, we will look at a Storage system that will allow for instant loading of historical data to Python or R for research and in Rust for backtesting. The code for this is simple, short and universally useful so I&#8217;ll likely write it as a package and release it for subscribers.</p><p>I invite the reader to leave questions, comments and/or requests for future articles.</p><h1>Announcement</h1><p>As I&#8217;m starting this Substack I do not know what to expect. Though important, infrastructure is rarely covered by existing online materials, possibly because it seems too base-level to write about for most quants/devs or perhaps because writing about research is more interesting.</p><p>Nevertheless, had I had access to good infrastructure information and tutorials when I started, it would&#8217;ve saved me years of experimentation and allowed me to commit more time to research (and do it more efficiently) ultimately leading to better alphas, greater profitability, fewer losses, etc. (or not, luck is a bitch, but you get the point).</p><p>As the Substack is new, my current aims are 1) to continue the series, 2) to understand if and how it is valuable to readers, and 3) to reach more readers.</p><p>With this in mind, future articles will likely rotate between paid-free every week and may include extras for subscribers such as implementation code. The specifics are very much up in the air.</p><p>That&#8217;s it for today!</p><p>Thank you for reading. I hope it was worth your time &#8212; or if it wasn&#8217;t yet, that it will be in the future!</p><p>Cheers!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.taiwanquant.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading TaiwanQuant&#8217;s Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item></channel></rss>