<?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[HangukQuant Research]]></title><description><![CDATA[Mathematics, Finance and Their Babies. 
quant research and quant dev.]]></description><link>https://www.research.hangukquant.com</link><image><url>https://substackcdn.com/image/fetch/$s_!LX9y!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png</url><title>HangukQuant Research</title><link>https://www.research.hangukquant.com</link></image><generator>Substack</generator><lastBuildDate>Thu, 01 Oct 2026 21:42:08 GMT</lastBuildDate><atom:link href="https://www.research.hangukquant.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[QUANTA GLOBAL PTE. LTD. 202328387H.]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[hangukquant@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[hangukquant@substack.com]]></itunes:email><itunes:name><![CDATA[HangukQuant]]></itunes:name></itunes:owner><itunes:author><![CDATA[HangukQuant]]></itunes:author><googleplay:owner><![CDATA[hangukquant@substack.com]]></googleplay:owner><googleplay:email><![CDATA[hangukquant@substack.com]]></googleplay:email><googleplay:author><![CDATA[HangukQuant]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Detailed Guide to Network Edge Optimisation (hft notes)]]></title><link>https://www.research.hangukquant.com/p/detailed-guide-to-network-edge-optimisation</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/detailed-guide-to-network-edge-optimisation</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Thu, 01 Oct 2026 16:29:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!94dG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fe94ca0-5b91-4868-8c72-32b42d6416a0_2160x1260.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the previous post - </p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;aa5bbb00-3e2a-4cfa-b84b-64d9f8891579&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Detailed Guide to Network Kernel Tuning - obtaining ~10us performance (hft notes) &quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-09-15T20:03:10.388Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!0t3N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/detailed-guide-to-network-kernel&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:215881396,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:7,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>we looked at how to do kernel tuning - where most of the time is spent on host t2t (typically in crypto infrastructures). Quoting from that article</p><blockquote><p><strong>Other than the network topology</strong>&#8230;high value work comes at the level of the kernel.</p></blockquote><p>This qualification is important - because network latency is order magnitudes more important to get right than software t2t - here is father El Jefe on that note:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zQv0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c04fd3-29dd-43e6-aa98-8425112d1a03_553x198.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zQv0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c04fd3-29dd-43e6-aa98-8425112d1a03_553x198.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zQv0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c04fd3-29dd-43e6-aa98-8425112d1a03_553x198.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zQv0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c04fd3-29dd-43e6-aa98-8425112d1a03_553x198.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zQv0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c04fd3-29dd-43e6-aa98-8425112d1a03_553x198.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zQv0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c04fd3-29dd-43e6-aa98-8425112d1a03_553x198.jpeg" width="553" height="198" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/55c04fd3-29dd-43e6-aa98-8425112d1a03_553x198.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:198,&quot;width&quot;:553,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:36755,&quot;alt&quot;:&quot;Image&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&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="Image" title="Image" srcset="https://substackcdn.com/image/fetch/$s_!zQv0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c04fd3-29dd-43e6-aa98-8425112d1a03_553x198.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zQv0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c04fd3-29dd-43e6-aa98-8425112d1a03_553x198.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zQv0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c04fd3-29dd-43e6-aa98-8425112d1a03_553x198.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zQv0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c04fd3-29dd-43e6-aa98-8425112d1a03_553x198.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>That is, optimising software t2t before working on network latencies is putting the cart before the horse. Missing the forest for the trees. Reading &#8220;how to pleasure your woman&#8221; without a first date.</p><p></p><p>In a previous post - </p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;6d8b746d-8a77-4fbb-9a1c-ef7fdc7e4216&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Crypto HFT - In Depth Guide to Optimisation (II)&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2025-12-28T13:41:38.295Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!ErGu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74c97db9-aef3-44cc-bc95-d15c07ae5231_1080x1099.jpeg&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/crypto-hft-in-depth-guide-to-optimisation&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:182749992,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:16,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>we talked about box placement strategies and how different azs, placement groups, instance families can play a part in network optimisation. We also talked about endpoint selection and ALBs.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;f2fb64af-35e8-4446-b3b4-bb725c992966&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Crypto HFT - In Depth Guide to Optimization (I)&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2025-12-22T18:51:51.154Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!PSqn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F395567fa-9f60-4663-8263-8043df63984c_974x594.jpeg&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/crypto-hft-in-depth-guide-to-optimization&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:182346782,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:16,&quot;comment_count&quot;:1,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>Here we will talk about single box network edge selection. It&#8217;s essentially the opposite side of the same coin in proximity search. Code examples are in the quantcplib repo. Link at the bottom.</p><p></p><h3>What Happens</h3><p>Let&#8217;s consider what happens, when we try to connect to say, </p><div class="callout-block" data-callout="true"><p><em>wss://fstream.binance.com/ws/btcusdt@bookTicker</em></p></div><p>The client presumably extracts the hostname <em>fstream.binance.com, </em>on port 443. This hostname must be translated into an IP address before we can open the TCP connection. The translation occurs via the libc function </p><div class="callout-block" data-callout="true"><p>::getaddrinfo(&#8221;fstream.binance.com&#8221;, &#8220;443&#8221;, &amp;hints, &amp;result)</p></div><p>This invokes the system&#8217;s configured name-resolution machinery. Depending on the <a href="https://man7.org/linux/man-pages/man5/nsswitch.conf.5.html">host lookup configuration</a>, the answer may come from a local hosts file, a resolver service or DNS. <em>getaddrinfo </em>gives us a linked list of socket addresses. The userspace network client then selects one of the addresses to connect to. Presumably, it walks the linked list and the first successful connection attempt is retained. The endpoint we use therefore depends on the addresses returned, their ordering and other less deliberate factors.</p><p>We can be more intentional about this edge resolution. For one, a wider set of candidates can be found via manual DNS querying than the heuristic set by the system resolver. Additionally, we are really interested in production-time market data latency, not arbitrary network latencies. We may question whether TCP handshake ranks translate to lower application layer ranks. We may also question whether such latency optimisations are persistent across time. And the answer will perhaps surprise.</p><h3>Experiment</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!94dG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fe94ca0-5b91-4868-8c72-32b42d6416a0_2160x1260.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!94dG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fe94ca0-5b91-4868-8c72-32b42d6416a0_2160x1260.png 424w, https://substackcdn.com/image/fetch/$s_!94dG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fe94ca0-5b91-4868-8c72-32b42d6416a0_2160x1260.png 848w, https://substackcdn.com/image/fetch/$s_!94dG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fe94ca0-5b91-4868-8c72-32b42d6416a0_2160x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!94dG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fe94ca0-5b91-4868-8c72-32b42d6416a0_2160x1260.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!94dG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fe94ca0-5b91-4868-8c72-32b42d6416a0_2160x1260.png" width="1456" height="849" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0fe94ca0-5b91-4868-8c72-32b42d6416a0_2160x1260.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:849,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:309304,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/218283282?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fe94ca0-5b91-4868-8c72-32b42d6416a0_2160x1260.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!94dG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fe94ca0-5b91-4868-8c72-32b42d6416a0_2160x1260.png 424w, https://substackcdn.com/image/fetch/$s_!94dG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fe94ca0-5b91-4868-8c72-32b42d6416a0_2160x1260.png 848w, https://substackcdn.com/image/fetch/$s_!94dG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fe94ca0-5b91-4868-8c72-32b42d6416a0_2160x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!94dG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fe94ca0-5b91-4868-8c72-32b42d6416a0_2160x1260.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>
          <a href="https://www.research.hangukquant.com/p/detailed-guide-to-network-edge-optimisation">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[QuantTerminal, for Quantitative Traders]]></title><link>https://www.research.hangukquant.com/p/quantterminal-for-quantitative-traders</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/quantterminal-for-quantitative-traders</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Thu, 24 Sep 2026 12:45:36 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/XGx9LVWQsdA" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Following up on the QuantTerminal - we now have integrated views into both live and historical <strong>private tick-data level actions.</strong></p><p><strong>Our focus remains on providing institutional grade analysis and tools for quantitative traders -</strong></p><p><a href="https://quantpylib.hangukquant.com/terminal/">https://quantpylib.hangukquant.com/terminal/</a></p><div id="youtube2-XGx9LVWQsdA" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;XGx9LVWQsdA&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/XGx9LVWQsdA?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>We continue to work on features in quantpylib, and will continue to serve by providing <strong>low latency access to the same ergonomic features through quantcplib in the future.</strong><br><br>In the last post, we talked about kernel tuning  - </p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;ae2db41f-e530-41b6-8fda-fbfb2fc945b8&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Detailed Guide to Network Kernel Tuning - obtaining ~10us performance (hft notes) &quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-09-15T20:03:10.388Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!0t3N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/detailed-guide-to-network-kernel&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:215881396,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:6,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>we will continue exploring network optimisations and &#8220;cloud based&#8221; engineering in the upcoming posts.<br><br>Cheers</p>]]></content:encoded></item><item><title><![CDATA[Detailed Guide to Network Kernel Tuning - obtaining ~10us performance (hft notes) ]]></title><description><![CDATA[from ENA hardware RX to WebSocket message-parse completion]]></description><link>https://www.research.hangukquant.com/p/detailed-guide-to-network-kernel</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/detailed-guide-to-network-kernel</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Tue, 15 Sep 2026 20:03:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!0t3N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In my series on nimble market making - we talked about how important it was to measure and profile: </p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;8afad2f7-8ecb-4dc7-90c9-e56a67345d8e&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Market Making - Tooling for Modelling Latency Requirements and Microstructural Behavior - I&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2025-12-04T12:02:09.795Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!4715!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc7eae4f-b86e-4058-95cd-568084135860_1253x680.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/market-making-tooling-for-modelling&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:180397944,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:15,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>This applies also critically to software optimisation. One of the most important things to do in a lean engineering/trading team is to operate on the pareto frontier between performance optimisations and strategy discovery. As an extension, one can spend all the wrong time focusing on micro-optimisations when there are significantly more problematic bottlenecks.</p><p>Other than the network topology, algorithmic design and architecture - one of the most high value work comes at the level of the kernel. More precisely, it is about getting the kernel and userspace programs to cooperate.</p><p>I previously wrote a broader (and simpler) <a href="https://www.research.hangukquant.com/p/hft-tuning-guide">Linux kernel tuning guide</a>. Here, we shall do something more concrete with the actual optimisations and code examples - do refer to the <strong>quantcplib</strong> repo for the actual scripts. </p><p>We will profile the ingress latency of a low-latency websocket client in quantcplib against a CPython implementation, measuring the latency between the AWS ENA RX hardware timestamp to a parsed WebSocket message. We will play around with different &#8220;settings&#8221; and discuss how they affect performance, with a soft, service level objective (SLO) of attaining ~10microseconds in ingress latency.</p><h2>A Short Userspace Description</h2><p>At a high level, in userspace, the receive path follows:</p><ol><li><p>A nonblocking TCP socket calls <code>recvmsg()</code>, receiving ciphertext and the ENA hardware-timestamp control message together.</p></li><li><p>A custom OpenSSL BIO reads directly into the destination supplied by OpenSSL.</p></li><li><p><code>SSL_read_ex()</code> writes plaintext into fixed application storage.</p></li><li><p>An incremental RFC 6455 <strong>frame parser consumes views</strong> over that storage.</p></li><li><p>An incremental message parser handles fragmentation and UTF-8 validation.</p></li><li><p>The message callback runs synchronously on the same network-owner core.</p></li></ol><p>ENA DMA-writes into driver-managed receive buffers and <code>recvmsg()</code> still copies bytes from the kernel into userspace. The custom BIO removes an <em>additional userspace ciphertext staging copy</em>: we do not receive into our own temporary buffer and then write the same ciphertext into an OpenSSL <code>MemoryBIO</code>. This is sometimes described as <strong>zero-copy</strong>. The timestamp is attributed to the ciphertext receive which enabled the completing plaintext chunk. This is the fastest path for a data packet where the kernel is still responsible for ip/tcp processing and tls is performed in userspace -</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6JOf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee5dc873-ce66-41cc-b549-8f8aa2fc7401_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6JOf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee5dc873-ce66-41cc-b549-8f8aa2fc7401_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!6JOf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee5dc873-ce66-41cc-b549-8f8aa2fc7401_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!6JOf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee5dc873-ce66-41cc-b549-8f8aa2fc7401_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!6JOf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee5dc873-ce66-41cc-b549-8f8aa2fc7401_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6JOf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee5dc873-ce66-41cc-b549-8f8aa2fc7401_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ee5dc873-ce66-41cc-b549-8f8aa2fc7401_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image preview&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image preview" title="Image preview" srcset="https://substackcdn.com/image/fetch/$s_!6JOf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee5dc873-ce66-41cc-b549-8f8aa2fc7401_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!6JOf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee5dc873-ce66-41cc-b549-8f8aa2fc7401_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!6JOf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee5dc873-ce66-41cc-b549-8f8aa2fc7401_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!6JOf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee5dc873-ce66-41cc-b549-8f8aa2fc7401_1672x941.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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><h2>Before Userspace</h2><p>Before the network runtime can parse a WebSocket frame, an Ethernet frame must travel from the ENA device into the TCP socket.</p><p>The first decision is receive steering. ENA calculates an RSS hash from the packet headers and uses its indirection table to select an RX queue. One TCP connection will normally remain on one queue: additional queues distribute different flows.</p><p>At this point, the driver has already populated that queue&#8217;s RX submission ring with descriptors pointing to host receive buffers. When the packet arrives, ENA DMA-writes the packet into one of those buffers and posts a completion descriptor to the corresponding completion queue. The payload is now in host memory, but TCP has not processed it.</p><p>On the ordinary path, the next step is an interrupt. Interrupt moderation determines how quickly ENA raises the queue pair&#8217;s MSI-X interrupt after completions arrive. Deferring the interrupt allows several packets to be handled together, amortising interrupt and driver work; it also makes the first packet wait for the batch. This is known as <strong>interrupt moderation</strong>. A fixed <code>rx-usecs</code> value sets this delay directly, while adaptive moderation changes it according to recent traffic.</p><p>When the MSI-X interrupt is delivered, ENA automatically masks the queue interrupt and the hard-IRQ handler schedules the queue&#8217;s NAPI instance. The handler does very little packet work itself. The NAPI poll is normally serviced through the <code>NET_RX</code> softirq and consumes RX completions until the queue is empty or its packet budget is exhausted.</p><p>For every completion, the driver identifies the posted receive buffer and constructs an <code>sk_buff</code>, the kernel&#8217;s packet representation. The driver then submits the skb through <code>napi_gro_receive()</code>. The <a href="https://docs.kernel.org/networking/device_drivers/ethernet/amazon/ena.html">ENA driver documentation</a> gives the concrete descriptor and skb path; the <a href="https://docs.kernel.org/networking/napi.html">Linux NAPI documentation</a> describes how the poll is scheduled and bounded.</p><p>GRO is the first important batching control inside that poll. When enabled, it can merge compatible packets from the same flow into a larger skb before the upper layers process them. This reduces repeated IP/TCP work and improves throughput, at the cost of batching and the bytes later observed by the application. With GRO disabled, packets proceed separately and the kernel pays more per-packet work.</p><p>The IP layer then processes the network packet, and TCP validates sequence state, handles reordering and makes contiguous stream bytes available on the socket receive queue. Once the socket becomes readable, the kernel wakes a task blocked in <code>epoll_wait()</code>. Epoll returns a readiness indication&#8212;not the bytes themselves&#8212;to the network runtime, which attempts a nonblocking <code>recvmsg()</code> and copies the available ciphertext, together with its ancillary timestamp data, into userspace.</p><p>Let&#8217;s highlight the available controls in this data path:</p><ul><li><p><strong>RSS and IRQ placement</strong> determine which queue receives the flow and which CPU handles its MSI-X interrupt and initial NAPI work.</p></li><li><p><strong>Interrupt moderation</strong> determines how long a completion may wait before that interrupt is delivered.</p></li><li><p><strong>The NAPI budget</strong> limits how many packets one poll cycle processes before yielding.</p></li><li><p><strong>GRO</strong> determines whether compatible receive packets are combined before IP/TCP processing.</p></li></ul><p>Two adjacent controls affect latency without changing this packet logic. Holding <code>/dev/cpu_dma_latency</code> open with a zero request constrains CPU idle-state exit latency through PM QoS; despite the name, it does not accelerate DMA. <code>mlockall()</code> and prefaulted buffers reduce disruptions from page faults and reclaim after the process is awake.</p><h3>An alternative path: NAPI busy polling</h3><p>An interrupt does not have to be the event which starts NAPI. With NAPI busy polling, an eligible socket read or readiness wait spends a bounded interval asking the kernel to poll the socket&#8217;s associated NAPI context before falling back to the MSI-X interrupt. If the completion arrives during that interval, packet processing can begin from the application&#8217;s syscall context without first paying the interrupt-delivery and task-wakeup path.</p><p>Everything after that entry point remains the ordinary kernel network stack. NAPI still consumes ENA completion descriptors, constructs skbs, passes them through GRO and IP/TCP, and places bytes on the socket receive queue. It changes how packet processing is initiated and which CPU performs it.</p><p><code>SO_BUSY_POLL</code> sets the polling window for a socket. <code>net.core.busy_read</code> supplies the system default for socket reads, while <code>net.core.busy_poll</code> controls the global polling window for <code>poll</code>, <code>select</code> and eligible epoll waits. A busy-poll budget limits packets processed in one polling episode.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!g9z7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F108d8f94-528f-4961-86b1-021918ba1026_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g9z7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F108d8f94-528f-4961-86b1-021918ba1026_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!g9z7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F108d8f94-528f-4961-86b1-021918ba1026_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!g9z7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F108d8f94-528f-4961-86b1-021918ba1026_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!g9z7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F108d8f94-528f-4961-86b1-021918ba1026_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g9z7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F108d8f94-528f-4961-86b1-021918ba1026_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/108d8f94-528f-4961-86b1-021918ba1026_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image preview&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image preview" title="Image preview" srcset="https://substackcdn.com/image/fetch/$s_!g9z7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F108d8f94-528f-4961-86b1-021918ba1026_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!g9z7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F108d8f94-528f-4961-86b1-021918ba1026_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!g9z7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F108d8f94-528f-4961-86b1-021918ba1026_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!g9z7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F108d8f94-528f-4961-86b1-021918ba1026_1672x941.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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><h2>Topology Matters</h2><p>We need to decide which RX queue receives flow, which CPU drains that queue, which CPU owns the socket and parser, and where the parsed event goes next.</p><p>For a small number of latency-sensitive WebSocket connections, each hot flow should land on a known RX queue and each queue should have one clear userspace owner. Two layouts are worth considering.</p><h3>locality-first: interrupt-driven receive</h3><p>For an <code>epoll</code>-driven client, one default is to place the RX queue&#8217;s MSI-X interrupt, its NAPI processing and the network-owner thread on the same logical CPU. The physical core should be reserved for the path: unrelated work should not run on that CPU or its SMT sibling.</p><pre><code><code>RSS -&gt; RX queue Q -&gt; MSI-X / NAPI / TCP on CPU A
                                      -&gt; epoll / recvmsg / TLS / parser on CPU A</code></code></pre><p>This layout follows the semantics of readiness-driven receive. While the owner sleeps in <code>epoll_wait()</code>, the interrupt is useful work: it drains the queue, advances TCP and makes the socket readable. The same CPU then wakes into <code>recvmsg()</code>, TLS and WebSocket parsing. We pay for an interrupt, but not for an additional inter-processor hand-off between the kernel receive path and the application.</p><p>The cost is interference. A new RX interrupt can pre-empt the parser while it is handling an earlier message, and sustained NAPI work competes with userspace for the same execution resources. Colocation is therefore the latency-first default only while that core has headroom.</p><p>If the combined kernel and userspace work approaches saturation, a deliberate split can buy pipeline capacity:</p><pre><code><code>RSS -&gt; RX queue Q -&gt; MSI-X / NAPI / TCP on CPU B
                                      -&gt; wake / recvmsg / TLS / parser on CPU A</code></code></pre><p>CPU A and CPU B should be different physical cores, preferably in the same last-level cache and NUMA node. This allows the kernel and parser to run concurrently, but it makes the socket hand-off and its cache traffic part of every packet&#8217;s path. Use the split when it improves the tail at the intended packet rate.</p><p>The controls need to express the same plan. RSS or hardware flow steering selects the queue; IRQ affinity selects where its interrupt and ordinary NAPI work run. <code>irqbalance</code> should be stopped.</p><p>We can verify this by generating traffic and verifing that the expected RX queue advances, that its MSI-X vector advances on the intended CPU in <code>/proc/interrupts</code>, and that network softirq activity appears where expected in <code>/proc/softirqs</code>.</p><h3>isolation-first: NAPI busy polling</h3><p>If the connection is continuously active and we are prepared to dedicate a core, NAPI busy polling changes the ownership boundary. The network owner on CPU A can run the queue&#8217;s NAPI poll from its receive or <code>epoll</code> path and consume the resulting socket data on the same CPU.</p><pre><code><code>                         +-&gt; busy-poll hit: NAPI / TCP / recvmsg / parser on CPU A
RSS -&gt; RX queue Q -------+
                         +-&gt; busy-poll miss: fallback MSI-X / NAPI on CPU A or CPU B</code></code></pre><p>Busy polling does not permanently eliminate interrupts, so fallback placement is a real tradeoff. Keeping the IRQ on CPU A preserves locality when polling misses, which is usually better for sparse or bursty traffic, but an interrupt may pre-empt the parser. Moving the IRQ to CPU B protects CPU A from that interruption, but a miss now executes the kernel receive path on B and wakes A across cores.</p><p><strong>There is no placement which simultaneously provides same-core fallback locality and freedom from interrupt interference.</strong></p><p>Busy polling is associated with a NAPI instance, not exclusively with one TCP connection. A hot polling socket should therefore not share its RX queue with arbitrary noisy traffic. If one <code>epoll</code> instance relies on busy polling for several sockets, those sockets should share a NAPI ID.</p><h3>place the consumer deliberately</h3><p>The same decision appears after WebSocket parsing. If the handler&#8217;s work is bounded, keep parsing and the immediate trading decision on CPU A. That removes another hand-off from tick-to-trade. If downstream work is large or variable, make one explicit SPSC hand-off to a second physical core, preferably in the same cache and NUMA domain.</p><p>Where the machine or guest exposes meaningful NUMA locality, keep the RX queue&#8217;s interrupt CPU, network owner and hot receive state on the NIC-local node. Reserve separate housekeeping capacity for unrelated IRQs, timers, kernel workqueues, logging and control-plane work.</p><h2>Comparing Implementations</h2><p>The quantcplib client is the userspace implementation described above. Its nonblocking, <code>epoll</code>-driven socket receives ciphertext and the ENA hardware timestamp through <code>recvmsg()</code>. A custom OpenSSL BIO reads directly into OpenSSL&#8217;s destination, <code>SSL_read_ex()</code> writes plaintext into fixed application storage, and the incremental WebSocket parser consumes views over that storage. Parse completion is the synchronous message-callback entry, after UTF-8 validation and before any handler copy or JSON deserialisation.</p><p>The CPython 3.9.25 implementation uses a raw socket in timeout mode and calls <code>recvmsg()</code> to retain the same hardware timestamp. It writes the ciphertext into an <code>ssl.MemoryBIO</code>, drains TLS plaintext into a receive buffer, waits for a complete frame payload, assembles continuation frames, validates and decodes UTF-8, and materialises the completed Python <code>str</code> or <code>bytes</code>. Its measurement ends before JSON deserialisation and does not include an asyncio event loop.</p><p>I ran the two implementations on the same <code>c8a.xlarge</code> under the vanilla host configuration. Kernel tuning is deliberately excluded here and measured separately in the next section.</p><p>Each implementation contains <em>five</em> runs of <em>3,000</em> measured messages after 1,000 warm-up messages, for 30,000 measured messages in total. ENA&#8217;s PHC disciplined the system clock; every run began and ended within 500ns of the PHC, with a largest observed correction or offset of 346ns. All 30,000 measurements had valid clock ordering. The table reports the median of the five per-run percentiles.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4XgP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b6d263d-1bb1-42e1-b1d4-283d81f58037_2408x238.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4XgP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b6d263d-1bb1-42e1-b1d4-283d81f58037_2408x238.png 424w, https://substackcdn.com/image/fetch/$s_!4XgP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b6d263d-1bb1-42e1-b1d4-283d81f58037_2408x238.png 848w, https://substackcdn.com/image/fetch/$s_!4XgP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b6d263d-1bb1-42e1-b1d4-283d81f58037_2408x238.png 1272w, https://substackcdn.com/image/fetch/$s_!4XgP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b6d263d-1bb1-42e1-b1d4-283d81f58037_2408x238.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4XgP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b6d263d-1bb1-42e1-b1d4-283d81f58037_2408x238.png" width="1456" height="144" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b6d263d-1bb1-42e1-b1d4-283d81f58037_2408x238.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:144,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:55761,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/215881396?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b6d263d-1bb1-42e1-b1d4-283d81f58037_2408x238.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4XgP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b6d263d-1bb1-42e1-b1d4-283d81f58037_2408x238.png 424w, https://substackcdn.com/image/fetch/$s_!4XgP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b6d263d-1bb1-42e1-b1d4-283d81f58037_2408x238.png 848w, https://substackcdn.com/image/fetch/$s_!4XgP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b6d263d-1bb1-42e1-b1d4-283d81f58037_2408x238.png 1272w, https://substackcdn.com/image/fetch/$s_!4XgP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b6d263d-1bb1-42e1-b1d4-283d81f58037_2408x238.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2sE0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f854faa-2e26-4ee8-bbc8-f8507d4462ea_2783x1163.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2sE0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f854faa-2e26-4ee8-bbc8-f8507d4462ea_2783x1163.png 424w, https://substackcdn.com/image/fetch/$s_!2sE0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f854faa-2e26-4ee8-bbc8-f8507d4462ea_2783x1163.png 848w, https://substackcdn.com/image/fetch/$s_!2sE0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f854faa-2e26-4ee8-bbc8-f8507d4462ea_2783x1163.png 1272w, https://substackcdn.com/image/fetch/$s_!2sE0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f854faa-2e26-4ee8-bbc8-f8507d4462ea_2783x1163.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2sE0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f854faa-2e26-4ee8-bbc8-f8507d4462ea_2783x1163.png" width="1456" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8f854faa-2e26-4ee8-bbc8-f8507d4462ea_2783x1163.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:608,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image preview&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image preview" title="Image preview" srcset="https://substackcdn.com/image/fetch/$s_!2sE0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f854faa-2e26-4ee8-bbc8-f8507d4462ea_2783x1163.png 424w, https://substackcdn.com/image/fetch/$s_!2sE0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f854faa-2e26-4ee8-bbc8-f8507d4462ea_2783x1163.png 848w, https://substackcdn.com/image/fetch/$s_!2sE0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f854faa-2e26-4ee8-bbc8-f8507d4462ea_2783x1163.png 1272w, https://substackcdn.com/image/fetch/$s_!2sE0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f854faa-2e26-4ee8-bbc8-f8507d4462ea_2783x1163.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>Both implementations inherit the vanilla host&#8217;s large receive-path tail. quantcplib reaches 11.326us at p50 and 260.045us at p99; CPython reaches 27.479us and 281.584us. At p99, the kernel-side tail has largely swamped the userspace difference.</p><p>The marginal p50 segments separate the implementation cost from that tail. ENA RX to post-<code>recvmsg()</code> takes 10.541us in quantcplib and 11.031us in CPython. From <code>recvmsg()</code> to TLS plaintext, the figures are 0.510us and 2.610us; from TLS plaintext to parsed message, they are 0.330us and 11.300us. The socket boundary is nearly identical. quantcplib then preserves it through its custom BIO, fixed storage and incremental view-based parser, while CPython spends another 13.91us in <code>MemoryBIO</code>, buffered frame completion, UTF-8 decoding and Python object materialisation.</p><h2>With Kernel Tuning</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0t3N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0t3N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png 424w, https://substackcdn.com/image/fetch/$s_!0t3N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png 848w, https://substackcdn.com/image/fetch/$s_!0t3N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!0t3N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0t3N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png" width="1456" height="562" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:562,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image preview&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image preview" title="Image preview" srcset="https://substackcdn.com/image/fetch/$s_!0t3N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png 424w, https://substackcdn.com/image/fetch/$s_!0t3N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png 848w, https://substackcdn.com/image/fetch/$s_!0t3N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!0t3N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae1f5b2-6991-4d9c-aa6f-f9df6cb06e29_2800x1080.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>We can now return to the earlier kernel experiment itself. How do we go about tuning the kernel based on the discussions above? The kernel matrix used the same Tokyo <code>c8a.xlarge</code> with four vCPUs presented as four separate AMD EPYC 9R45 cores, with SMT disabled, one NUMA node, Amazon Linux kernel <code>6.18.44-99.149</code>, and ENA driver <code>2.17.2g</code>. Five 3,000-message runs were retained for each configuration, with 1,000 warm-up messages per run: 165,000 measured observations. All eleven stages were run in five randomised complete blocks.</p>
      <p>
          <a href="https://www.research.hangukquant.com/p/detailed-guide-to-network-kernel">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Quantitative Trading - How I Made 1M - Documented, and Released.]]></title><link>https://www.research.hangukquant.com/p/quantitative-trading-how-i-made-1m</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/quantitative-trading-how-i-made-1m</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Sun, 06 Sep 2026 13:00:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!RVbu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dc075d6-4d80-4547-85ed-0e810375c072_2046x812.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>And now, for the grand finale, I present&#8230;the work behind this:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;08bb95f4-55c7-448e-953d-bc2fc77fd726&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;2 Years, 1M PnL and Life as a Solo Crypto Quant&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-04-10T16:15:21.296Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!Lvvp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e6fa10f-5aa8-4f78-89e1-1eae828b892e_1200x480.jpeg&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/2-years-1m-pnl-and-life-as-a-solo&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:193809007,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:66,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><h3><br><br>NEW QUANT LECTURES RELEASE</h3><p><a href="https://lectures.hangukquant.com/courses/digital-options-mm">https://lectures.hangukquant.com/courses/digital-options-mm</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RVbu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dc075d6-4d80-4547-85ed-0e810375c072_2046x812.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RVbu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dc075d6-4d80-4547-85ed-0e810375c072_2046x812.png 424w, https://substackcdn.com/image/fetch/$s_!RVbu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dc075d6-4d80-4547-85ed-0e810375c072_2046x812.png 848w, https://substackcdn.com/image/fetch/$s_!RVbu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dc075d6-4d80-4547-85ed-0e810375c072_2046x812.png 1272w, https://substackcdn.com/image/fetch/$s_!RVbu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dc075d6-4d80-4547-85ed-0e810375c072_2046x812.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RVbu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dc075d6-4d80-4547-85ed-0e810375c072_2046x812.png" width="1456" height="578" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9dc075d6-4d80-4547-85ed-0e810375c072_2046x812.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:578,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:173740,&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;:&quot;https://www.research.hangukquant.com/i/214413946?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dc075d6-4d80-4547-85ed-0e810375c072_2046x812.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RVbu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dc075d6-4d80-4547-85ed-0e810375c072_2046x812.png 424w, https://substackcdn.com/image/fetch/$s_!RVbu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dc075d6-4d80-4547-85ed-0e810375c072_2046x812.png 848w, https://substackcdn.com/image/fetch/$s_!RVbu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dc075d6-4d80-4547-85ed-0e810375c072_2046x812.png 1272w, https://substackcdn.com/image/fetch/$s_!RVbu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dc075d6-4d80-4547-85ed-0e810375c072_2046x812.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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><div id="youtube2-CnP7NbGbjHg" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;CnP7NbGbjHg&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/CnP7NbGbjHg?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>My first ever hft-series on the quant lectures platform - and it discusses in detail <strong>how I designed, implemented and deployed one of the most successful hft mm ops on crypto markets in Polymarket</strong>. </p><p>The lectures are <strong>information</strong> <strong>dense, </strong>and intense - <strong>50-part lecture series lasting for 12 hours.</strong> </p><p>It is intended for a more technical audience with experience in programming. The lectures are released over 4 weeks with a tiered pricing model. Each release has limited seats and <strong>enrolment is First Come First Serve.</strong> Each successive tier will price the lectures higher.<br><br>Some of the lectures have been marked as preview-able.<br></p><h4>Special Offers</h4><ul><li><p><strong>Annual and lifetime subscribers of</strong> <strong>research.hangukquant.com </strong>receive 500USD discount (the cost of an annual price plan) on the listed lecture.<br><br><strong>Monthly</strong> <strong>subscribers of</strong> <strong>research.hangukquant.com </strong>receive 100USD discount on the listed lecture.<br><br>These discount codes will be sent to you separately.<br></p></li><li><p><strong>Unsubscribed readers or monthly readers who want to upgrade</strong> may first obtain the lecture pass and then reach out to me for complimentary upgrade on research.hangukquant.com.<strong> </strong>Existing users should use the codes sent to them instead.<br></p></li><li><p><strong>Lifetime subscribers of</strong> <strong>lectures.hangukquant.com </strong>will immediately get assigned seats in the lectures promptly and no action is required.<br></p></li></ul><p>Lifetime pass is priced at <strong>2400 USD until end of September. We will increase cost to 4200 USD once promotional period ends.</strong></p><p><a href="https://lectures.hangukquant.com/courses/lifetime">https://lectures.hangukquant.com/courses/lifetime</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GcTk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7953e8b5-b79c-4f78-ba93-e1e3832b75da_1610x1140.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GcTk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7953e8b5-b79c-4f78-ba93-e1e3832b75da_1610x1140.png 424w, https://substackcdn.com/image/fetch/$s_!GcTk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7953e8b5-b79c-4f78-ba93-e1e3832b75da_1610x1140.png 848w, https://substackcdn.com/image/fetch/$s_!GcTk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7953e8b5-b79c-4f78-ba93-e1e3832b75da_1610x1140.png 1272w, https://substackcdn.com/image/fetch/$s_!GcTk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7953e8b5-b79c-4f78-ba93-e1e3832b75da_1610x1140.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GcTk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7953e8b5-b79c-4f78-ba93-e1e3832b75da_1610x1140.png" width="1456" height="1031" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7953e8b5-b79c-4f78-ba93-e1e3832b75da_1610x1140.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1031,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:126129,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/214413946?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7953e8b5-b79c-4f78-ba93-e1e3832b75da_1610x1140.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GcTk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7953e8b5-b79c-4f78-ba93-e1e3832b75da_1610x1140.png 424w, https://substackcdn.com/image/fetch/$s_!GcTk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7953e8b5-b79c-4f78-ba93-e1e3832b75da_1610x1140.png 848w, https://substackcdn.com/image/fetch/$s_!GcTk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7953e8b5-b79c-4f78-ba93-e1e3832b75da_1610x1140.png 1272w, https://substackcdn.com/image/fetch/$s_!GcTk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7953e8b5-b79c-4f78-ba93-e1e3832b75da_1610x1140.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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><strong><br></strong></p>]]></content:encoded></item><item><title><![CDATA[3 of my Biggest Quant Workflows and Market Making on a Shoestring Budget]]></title><description><![CDATA[Mathematics, Finance and Their Babies. 
quant research and quant dev.]]></description><link>https://www.research.hangukquant.com/p/3-of-my-biggest-quant-workflows-and</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/3-of-my-biggest-quant-workflows-and</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Tue, 01 Sep 2026 15:52:03 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!rDY_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdce22247-00e8-49c1-9351-f11b3d5ebf74_2596x862.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello folks, as you guys know, <strong><a href="https://quantpylib.hangukquant.com/">quantpylib</a></strong> has been seeing many updates to enable <strong>powerful tools for market making in production and research.</strong></p><p>I&#8217;ve made 3 new tutorials with fully functional Python code backing my own market making workflows, including</p><ol><li><p><strong>Quantitative tick data lake management.</strong></p><p>This is how I manage my own raw flat data archives of market data, with data provenance for seqnos, observed jitter, etc. This allows downstream backtesting to retain &#8220;playback fidelity&#8221;, and replicate performance concerns such as back-pressure and jitter.</p><p></p><p><a href="https://quantpylib.hangukquant.com/tutorials/tick_data_archival/">https://quantpylib.hangukquant.com/tutorials/tick_data_archival/</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mljD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5a60042-952f-40c2-9c03-68fd478f50a3_1456x799.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mljD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5a60042-952f-40c2-9c03-68fd478f50a3_1456x799.webp 424w, https://substackcdn.com/image/fetch/$s_!mljD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5a60042-952f-40c2-9c03-68fd478f50a3_1456x799.webp 848w, https://substackcdn.com/image/fetch/$s_!mljD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5a60042-952f-40c2-9c03-68fd478f50a3_1456x799.webp 1272w, https://substackcdn.com/image/fetch/$s_!mljD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5a60042-952f-40c2-9c03-68fd478f50a3_1456x799.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mljD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5a60042-952f-40c2-9c03-68fd478f50a3_1456x799.webp" width="1456" height="799" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f5a60042-952f-40c2-9c03-68fd478f50a3_1456x799.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:799,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:110680,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/213697947?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5a60042-952f-40c2-9c03-68fd478f50a3_1456x799.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mljD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5a60042-952f-40c2-9c03-68fd478f50a3_1456x799.webp 424w, https://substackcdn.com/image/fetch/$s_!mljD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5a60042-952f-40c2-9c03-68fd478f50a3_1456x799.webp 848w, https://substackcdn.com/image/fetch/$s_!mljD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5a60042-952f-40c2-9c03-68fd478f50a3_1456x799.webp 1272w, https://substackcdn.com/image/fetch/$s_!mljD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5a60042-952f-40c2-9c03-68fd478f50a3_1456x799.webp 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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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></p></li><li><p><strong>Quantitative tick data simulation and backtests using data lake.</strong></p><p>This is the infrastructure that uses tick data and event journals from step 1 to try and replicate live trading behavior and performance. The objective is bipartite - <strong>first, to get as &#8220;true&#8221; of simulation to the live journal and secondly, to use the &#8220;true&#8221; simulation to test price discovery hypothesis.</strong></p><p></p><p><a href="https://quantpylib.hangukquant.com/tutorials/market_making/">https://quantpylib.hangukquant.com/tutorials/market_making/</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wovh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf7d29dd-0d16-477b-9572-0716fb34e260_1456x819.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wovh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf7d29dd-0d16-477b-9572-0716fb34e260_1456x819.webp 424w, https://substackcdn.com/image/fetch/$s_!wovh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf7d29dd-0d16-477b-9572-0716fb34e260_1456x819.webp 848w, https://substackcdn.com/image/fetch/$s_!wovh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf7d29dd-0d16-477b-9572-0716fb34e260_1456x819.webp 1272w, https://substackcdn.com/image/fetch/$s_!wovh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf7d29dd-0d16-477b-9572-0716fb34e260_1456x819.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wovh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf7d29dd-0d16-477b-9572-0716fb34e260_1456x819.webp" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/af7d29dd-0d16-477b-9572-0716fb34e260_1456x819.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:67258,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/213697947?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf7d29dd-0d16-477b-9572-0716fb34e260_1456x819.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wovh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf7d29dd-0d16-477b-9572-0716fb34e260_1456x819.webp 424w, https://substackcdn.com/image/fetch/$s_!wovh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf7d29dd-0d16-477b-9572-0716fb34e260_1456x819.webp 848w, https://substackcdn.com/image/fetch/$s_!wovh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf7d29dd-0d16-477b-9572-0716fb34e260_1456x819.webp 1272w, https://substackcdn.com/image/fetch/$s_!wovh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf7d29dd-0d16-477b-9572-0716fb34e260_1456x819.webp 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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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></p></li><li><p><strong>Live Trading, Diagnosis and Calibration of the Backtest Models.</strong></p><p>This is an iterative live trading process backed by steps 1 and 2. The live market making code is &#8220;unified&#8221; with the backtesting code, and live trading generates an action journal.</p><p></p><p><a href="https://quantpylib.hangukquant.com/tutorials/market_making/">https://quantpylib.hangukquant.com/tutorials/market_making/</a></p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Zt-7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6785aea-84b0-40cc-9bb2-c46134609eec_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Zt-7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6785aea-84b0-40cc-9bb2-c46134609eec_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!Zt-7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6785aea-84b0-40cc-9bb2-c46134609eec_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!Zt-7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6785aea-84b0-40cc-9bb2-c46134609eec_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!Zt-7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6785aea-84b0-40cc-9bb2-c46134609eec_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Zt-7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6785aea-84b0-40cc-9bb2-c46134609eec_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f6785aea-84b0-40cc-9bb2-c46134609eec_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;In-memory order encoded as a binary QET trace&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="In-memory order encoded as a binary QET trace" title="In-memory order encoded as a binary QET trace" srcset="https://substackcdn.com/image/fetch/$s_!Zt-7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6785aea-84b0-40cc-9bb2-c46134609eec_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!Zt-7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6785aea-84b0-40cc-9bb2-c46134609eec_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!Zt-7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6785aea-84b0-40cc-9bb2-c46134609eec_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!Zt-7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6785aea-84b0-40cc-9bb2-c46134609eec_1672x941.png 1456w" sizes="100vw"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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></p><p>All together, a live market making system generates live pnl, as well as observed actions such as fills, orders and positions. The tick data lake keeps an archive of the system&#8217;s data states. Later, the same strategy code is backtested against this data lake to generate simulated actions. </p><p>The simulated actions are compared with observed actions to report on backtest fidelity and tune queue models and improve backtest accuracy.<br><br>Analytics then run against both market data and observed actions to diagnose shortfall. Shortfalls are targeted by dev-iterations. The iterated strategy is run against the calibrated backtest to validate correctness and improvements. The iteration is then taken live.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rDY_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdce22247-00e8-49c1-9351-f11b3d5ebf74_2596x862.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rDY_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdce22247-00e8-49c1-9351-f11b3d5ebf74_2596x862.png 424w, https://substackcdn.com/image/fetch/$s_!rDY_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdce22247-00e8-49c1-9351-f11b3d5ebf74_2596x862.png 848w, https://substackcdn.com/image/fetch/$s_!rDY_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdce22247-00e8-49c1-9351-f11b3d5ebf74_2596x862.png 1272w, https://substackcdn.com/image/fetch/$s_!rDY_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdce22247-00e8-49c1-9351-f11b3d5ebf74_2596x862.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rDY_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdce22247-00e8-49c1-9351-f11b3d5ebf74_2596x862.png" width="1456" height="483" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dce22247-00e8-49c1-9351-f11b3d5ebf74_2596x862.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:483,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:98481,&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;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/213697947?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdce22247-00e8-49c1-9351-f11b3d5ebf74_2596x862.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rDY_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdce22247-00e8-49c1-9351-f11b3d5ebf74_2596x862.png 424w, https://substackcdn.com/image/fetch/$s_!rDY_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdce22247-00e8-49c1-9351-f11b3d5ebf74_2596x862.png 848w, https://substackcdn.com/image/fetch/$s_!rDY_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdce22247-00e8-49c1-9351-f11b3d5ebf74_2596x862.png 1272w, https://substackcdn.com/image/fetch/$s_!rDY_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdce22247-00e8-49c1-9351-f11b3d5ebf74_2596x862.png 1456w" sizes="100vw"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>
          <a href="https://www.research.hangukquant.com/p/3-of-my-biggest-quant-workflows-and">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Quantitative Trading - Let’s Write a Stink Bidding MM System (in Python)]]></title><description><![CDATA[Mathematics, Finance and Their Babies. 
quant research and quant dev.]]></description><link>https://www.research.hangukquant.com/p/quantitative-trading-lets-write-a</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/quantitative-trading-lets-write-a</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Tue, 25 Aug 2026 13:03:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!lM3i!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d3681cc-ca5f-4c90-81bc-3cc2a216e573_1280x580.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the last post, we discussed diagnosing a live, hft trading system:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;c0efc648-b2ac-457c-90f5-30c908b484ad&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;lg&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Quantitative Trading - Diagnosing a Live-HFT Strategy&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-08-17T17:36:56.159Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!b96A!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F392325a5-2e6a-40d4-a101-750926b9bd0b_2540x1640.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/quantitative-trading-diagnosing-a&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:211576186,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:9,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>I did get some requests to do a demo for a fully functioning mm system. Since crypto vol is picking up, I thought we shall write some code for a stink bidding market maker that targets slippage-insensitive taker flow such as liquidation orders. Code is in Python.</p>
      <p>
          <a href="https://www.research.hangukquant.com/p/quantitative-trading-lets-write-a">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Quantitative Trading - Diagnosing a Live-HFT Strategy]]></title><description><![CDATA[Mathematics, Finance and Their Babies. 
quant research and quant dev.]]></description><link>https://www.research.hangukquant.com/p/quantitative-trading-diagnosing-a</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/quantitative-trading-diagnosing-a</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Mon, 17 Aug 2026 17:36:56 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!b96A!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F392325a5-2e6a-40d4-a101-750926b9bd0b_2540x1640.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Now this one&#8217;s gonna be a pretty interesting (and important) post, so take a cuppa and let&#8217;s get to it.</p>
      <p>
          <a href="https://www.research.hangukquant.com/p/quantitative-trading-diagnosing-a">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[HFT MM: Detailed Guide to Queue Modelling and Calibration]]></title><description><![CDATA[Mathematics, Finance and Their Babies. 
quant research and quant dev.]]></description><link>https://www.research.hangukquant.com/p/hft-mm-detailed-guide-to-queue-modelling</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/hft-mm-detailed-guide-to-queue-modelling</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Fri, 14 Aug 2026 15:54:04 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!AL7a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d5d24a7-67e9-4359-9f33-6c99f29172e0_1601x954.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_!VJtY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a35b9f7-850e-4a90-8fc7-fb75e184cde5_1610x920.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VJtY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a35b9f7-850e-4a90-8fc7-fb75e184cde5_1610x920.png 424w, https://substackcdn.com/image/fetch/$s_!VJtY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a35b9f7-850e-4a90-8fc7-fb75e184cde5_1610x920.png 848w, https://substackcdn.com/image/fetch/$s_!VJtY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a35b9f7-850e-4a90-8fc7-fb75e184cde5_1610x920.png 1272w, https://substackcdn.com/image/fetch/$s_!VJtY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a35b9f7-850e-4a90-8fc7-fb75e184cde5_1610x920.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VJtY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a35b9f7-850e-4a90-8fc7-fb75e184cde5_1610x920.png" width="1456" height="832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a35b9f7-850e-4a90-8fc7-fb75e184cde5_1610x920.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:832,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:203352,&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;:&quot;https://www.research.hangukquant.com/i/211191137?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a35b9f7-850e-4a90-8fc7-fb75e184cde5_1610x920.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VJtY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a35b9f7-850e-4a90-8fc7-fb75e184cde5_1610x920.png 424w, https://substackcdn.com/image/fetch/$s_!VJtY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a35b9f7-850e-4a90-8fc7-fb75e184cde5_1610x920.png 848w, https://substackcdn.com/image/fetch/$s_!VJtY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a35b9f7-850e-4a90-8fc7-fb75e184cde5_1610x920.png 1272w, https://substackcdn.com/image/fetch/$s_!VJtY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a35b9f7-850e-4a90-8fc7-fb75e184cde5_1610x920.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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><strong>Note that <a href="https://quantpylib.hangukquant.com/pricing/pricing/">terminal access pass</a> cost increases in 3 days.</strong></p><h2>Queue Modelling in HFT Simulations</h2><p>In HFT market making, running high-fidelity tick-data simulations is particularly challenging. It is easy to invent false artefacts around market microstructure which generate positive PnL but do not hold in practice. This is because we make assumptions around important considerations like latency, queue priority, market impact and so on.</p><p>At a high level, an execution simulation has to be concerned with:</p><ol><li><p>When our order lands on the order book.</p></li><li><p>When our cancellation lands on the order book.</p></li><li><p><strong>Our estimated queue position relative to exogenous market actions.</strong></p></li><li><p>The impact of other traders reacting to our orders.</p></li><li><p><strong>The endogenous impact of our orders on the simulated order book.</strong></p></li></ol><p>The first two are latency problems. Order-latency distributions may be backed out from our own order traces, with an appropriate sampling method. Similarly, an order remains live while its cancellation is in flight. Market events between these timestamps have to be applied against the correct exchange-side state.</p><p>The third is the usual queue-position problem: how much liquidity is ahead of us, and how does that quantity change as trades, submissions, modifications and cancellations occur?</p><p>The fourth is a much harder problem. Historical replay tells us how other participants behaved in the observed market. It does not tell us how they would have behaved had our simulated order been larger, smaller or absent. Modelling this properly requires an endogenous model of external order flow - we will leave that outside the scope of this post.</p><p>Our focus in this post is the theoretical basis of points 3 and 5. In particular, we will separate two ideas which are often mixed together under &#8220;queue modelling&#8221;:</p><ul><li><p><strong>Impact modelling:</strong> how should our order change the displayed and matchable liquidity inside the replay?</p></li><li><p><strong>Position modelling:</strong> where should our order sit, and how should exogenous events change the quantity ahead of it?</p></li></ul><p><strong>Given different choices to queue models, we also want to know how we may tune or calibrate them from a statistical framework.</strong></p><h3>MBO vs MBP</h3><p>When we have market-by-order data&#8212;MBO (L3)&#8212;queue reconstruction is relatively straightforward. The feed identifies individual order submissions, modifications and cancellations. Assuming price-time priority, we can reconstruct the orders at a level and insert our own order according to its exchange-arrival timestamp.</p><p>When an external order is cancelled, we know which order left the queue. We therefore know whether the cancellation occurred ahead of or behind us.</p><p>In crypto, we typically have market-by-price data&#8212;MBP (L2). <strong>The feed gives us aggregate quantity at each price but does not identify the orders making up that quantity.</strong></p><p>Consider a level displaying ten units. The level later falls to six. We know that four units have left, but the L2 update does not tell us where those units were in the queue. </p><p>If they were ahead of our order, our position has improved by four. If they were behind us, our position has not improved at all. <strong>This is the crux of estimating queue priority and building queue models.</strong></p><p>An optimistic model may remove it from ahead of us; a pessimistic model may remove it from behind us; a probabilistic model sits somewhere between the two.</p><p><strong>Before we get to this position problem, there is a lesser asked but equally important question.</strong></p><p>Suppose the historical L2 book displays ten units at a price and we submit a two-unit order. Should the simulated book now display twelve units, or should our two units be treated as part of the ten already observed?</p><p>There is no one-size-fits-all answer. It depends on our order size, the liquidity of the market and, importantly, whether we were already quoting on the book used to record the historical data. This is an orthogonal question to point 4&#8212;should our orders should be represented inside the public book?</p><p><strong>The good news is that we can answer such difficult questions by tuning our queue models and parameters and comparing them against empirical results, thereby reducing the dimensions of our problem.</strong> </p><p>In QuantPylib, the L2 and L3 order books are mapped through a common data structure. QuantPylib&#8217;s replay logic implements the discussed policies.</p><p><strong>We will discuss how synthetic L2 MBP data can be projected onto an L3 MBO book by separating liquidity into anonymous and private sizes, over which we may configure different queueing and impact policies.</strong></p><h2>Projecting L2 into an L3 State</h2><p>Consider a single price level displaying ten units of liquidity. Our two-unit order lands at the same price.</p><p>There are two ways to project the new state.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jVCi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6aa226-a3c8-4631-a240-777f878918db_1693x929.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jVCi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6aa226-a3c8-4631-a240-777f878918db_1693x929.png 424w, https://substackcdn.com/image/fetch/$s_!jVCi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6aa226-a3c8-4631-a240-777f878918db_1693x929.png 848w, https://substackcdn.com/image/fetch/$s_!jVCi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6aa226-a3c8-4631-a240-777f878918db_1693x929.png 1272w, https://substackcdn.com/image/fetch/$s_!jVCi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6aa226-a3c8-4631-a240-777f878918db_1693x929.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jVCi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6aa226-a3c8-4631-a240-777f878918db_1693x929.png" width="578" height="317.18543956043953" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6a6aa226-a3c8-4631-a240-777f878918db_1693x929.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:799,&quot;width&quot;:1456,&quot;resizeWidth&quot;:578,&quot;bytes&quot;:1168380,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/211191137?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6aa226-a3c8-4631-a240-777f878918db_1693x929.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jVCi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6aa226-a3c8-4631-a240-777f878918db_1693x929.png 424w, https://substackcdn.com/image/fetch/$s_!jVCi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6aa226-a3c8-4631-a240-777f878918db_1693x929.png 848w, https://substackcdn.com/image/fetch/$s_!jVCi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6aa226-a3c8-4631-a240-777f878918db_1693x929.png 1272w, https://substackcdn.com/image/fetch/$s_!jVCi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a6aa226-a3c8-4631-a240-777f878918db_1693x929.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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><h3>Additive Impact</h3><p>The additive model is simple. Historical public liquidity and our private liquidity are disjoint.</p><p>If the observed L2 quantity is <em>L</em> and our total private quantity is <em>O</em>, the matchable size is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;T=L+O&quot;,&quot;id&quot;:&quot;KIYRPYYLUT&quot;}" data-component-name="LatexBlockToDOM"></div><p>Our order is appended to the price level when it arrives. Subsequent L2 updates change the public quantity independently of our order. Cancelling our order removes its entire remaining size.</p><h3>Borrowed Impact</h3><p>The borrowed model is more challenging because public and private liquidity are no longer disjoint accounting buckets.</p><p>For one side and price, define:</p><ul><li><p><em>L</em>: public size reported by the historical L2 feed;</p></li><li><p><em>O</em>: total size of our active private orders;</p></li><li><p><em>B</em>: private size borrowed from&#8212;and therefore already counted in&#8212;the historical public size;</p></li><li><p><em>E</em>: anonymous external liquidity represented in the synthetic L3 book;</p></li><li><p><em>T</em>: total physical quantity available to the matcher.</p></li></ul><p>The following invariants must hold:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;E=L-B&quot;,&quot;id&quot;:&quot;PBXWOMKKXO&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;T=E+O=L+O-B&quot;,&quot;id&quot;:&quot;YGMFHEFEHX&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;0\\leq B\\leq\\min(L,O)&quot;,&quot;id&quot;:&quot;IMMBFPMTYJ&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>For a fully borrowed-impact model, we target:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;B=\\min(L,O)&quot;,&quot;id&quot;:&quot;FNCQCVCUFH&quot;}" data-component-name="LatexBlockToDOM"></div><p>and therefore:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;T=\\max(L,O)&quot;,&quot;id&quot;:&quot;MZCIXZEJAH&quot;}" data-component-name="LatexBlockToDOM"></div><p><br>Probably confusing, so let&#8217;s walk through some interesting cases.</p><h3>Private size exceeds the observed level</h3><p>Suppose the historical level displays three units and we submit an order for five:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;L=3,\\qquad O=5&quot;,&quot;id&quot;:&quot;BPOABJAZLN&quot;}" data-component-name="LatexBlockToDOM"></div><p>The private order can borrow only the three units available in the public observation:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;B=3,\\qquad E=0,\\qquad T=5&quot;,&quot;id&quot;:&quot;UFKQCTLHKQ&quot;}" data-component-name="LatexBlockToDOM"></div><p>All three public units are represented by our order. The remaining two units are necessarily additive.</p><p>The cancellation behaviour is slightly less obvious. If we cancel the five-unit order, only its two additive units should disappear from the physical book. The three borrowed units still belong to the historical public observation and must return as anonymous liquidity:</p><pre><code><code>before cancellation:
[ours: 5]

L = 3, O = 5, B = 3, E = 0, T = 5

after cancellation:
[anonymous: 3]

L = 3, O = 0, B = 0, E = 3, T = 3</code></code></pre><p>Cancelling the private claim does not cancel the historical market.</p><h3>Public size moves through private size</h3><p>Now suppose our private order has size ten while the historical L2 level displays five:</p><pre><code><code>L = 5, O = 10, B = 5, E = 0, T = 10</code></code></pre><p>The public level then rises from five to eight:</p><pre><code><code>L = 8, O = 10, B = 8, E = 0, T = 10</code></code></pre><p>The physical matchable size does not change. Three more units of our private order simply become borrowed from the updated public observation.</p><p>If the L2 level subsequently rises to twelve:</p><pre><code><code>L = 12, O = 10, B = 10, E = 2, T = 12</code></code></pre><p>Our full ten-unit order is now borrowed, while the remaining two public units must be represented as anonymous liquidity that queues behind our owned orders.</p><p>The reverse case - suppose the public level falls from twelve to seven:</p><pre><code><code>before:
L = 12, O = 10, B = 10, E = 2, T = 12

after:
L = 7, O = 10, B = 7, E = 0, T = 10</code></code></pre><p>The private order remains physically matchable for ten units. The two anonymous units disappear, while three units of the private order lose their borrowed attribution and become additive.</p><p><strong>The different impact models fundamentally discuss the philosophy of whether our simulated orders should be treated as additional liquidity, or as liquidity already represented in the observed market data.</strong></p><h2>Queue Position Policies</h2><p>Once the impact policy has produced a synthetic L3 level, the queue policy determines how exogenous reductions change our position.</p><p>New public liquidity joins the tail. Historical trades consume liquidity from the head. <strong>The ambiguous event is an L2 size reduction: did the disappearing liquidity sit ahead of us or behind us?</strong></p><h3>Optimistic and pessimistic bounds</h3><p>Consider a borrowed-impact book with ten public units. We submit an order for two:</p><pre><code><code>[anonymous: 8] [ours: 2]</code></code></pre><p>The public level then rises from ten to fifteen. The new liquidity joins the tail:</p><pre><code><code>[anonymous: 8] [ours: 2] [anonymous: 5]</code></code></pre><p>The level subsequently falls back to ten.</p><p>An optimistic, front-cancellation policy removes the five units from the head:</p><pre><code><code>[anonymous: 3] [ours: 2] [anonymous: 5]</code></code></pre><p>Our queue position has improved by five. A subsequent trade for five units consumes the three anonymous units ahead of us and fills our two-unit order.</p><p>A pessimistic, back-cancellation policy removes the five units from the tail:</p><pre><code><code>[anonymous: 8] [ours: 2]</code></code></pre><p>Our position has not improved. The same five-unit trade does not reach us.</p><p><strong>The market data is identical in both cases. Only the queue policy changes.</strong></p><h3>Probabilistic queue models</h3><p>The optimistic and pessimistic models are useful bounds. A probabilistic model allocates the reduction between liquidity ahead of and behind our order.</p><p>Let:</p><ul><li><p><em>A</em>: anonymous quantity ahead of our order;</p></li><li><p><em>H</em>: anonymous quantity behind our order;</p></li><li><p><em>C</em>: observed L2 reduction.</p></li></ul><p>Define the relative queue position:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;x=\\frac{A}{A+H}&quot;,&quot;id&quot;:&quot;GQBRTDKNYN&quot;}" data-component-name="LatexBlockToDOM"></div><p>A simple probability function is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;p_{\\text{ahead}}(x)\n=\n\\frac{f(x)}\n{f(x)+f(1-x)}&quot;,&quot;id&quot;:&quot;ONDWMFDQKY&quot;}" data-component-name="LatexBlockToDOM"></div><p>where:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f(x)=x^\\gamma&quot;,&quot;id&quot;:&quot;NMUGDXCWQA&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>The exponent <em>&#947; &gt; 0</em> controls the curvature of the cancellation-probability function.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AL7a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d5d24a7-67e9-4359-9f33-6c99f29172e0_1601x954.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AL7a!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d5d24a7-67e9-4359-9f33-6c99f29172e0_1601x954.png 424w, https://substackcdn.com/image/fetch/$s_!AL7a!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d5d24a7-67e9-4359-9f33-6c99f29172e0_1601x954.png 848w, https://substackcdn.com/image/fetch/$s_!AL7a!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d5d24a7-67e9-4359-9f33-6c99f29172e0_1601x954.png 1272w, https://substackcdn.com/image/fetch/$s_!AL7a!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d5d24a7-67e9-4359-9f33-6c99f29172e0_1601x954.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AL7a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d5d24a7-67e9-4359-9f33-6c99f29172e0_1601x954.png" width="576" height="343.38461538461536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5d5d24a7-67e9-4359-9f33-6c99f29172e0_1601x954.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:868,&quot;width&quot;:1456,&quot;resizeWidth&quot;:576,&quot;bytes&quot;:168201,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/211191137?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d5d24a7-67e9-4359-9f33-6c99f29172e0_1601x954.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AL7a!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d5d24a7-67e9-4359-9f33-6c99f29172e0_1601x954.png 424w, https://substackcdn.com/image/fetch/$s_!AL7a!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d5d24a7-67e9-4359-9f33-6c99f29172e0_1601x954.png 848w, https://substackcdn.com/image/fetch/$s_!AL7a!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d5d24a7-67e9-4359-9f33-6c99f29172e0_1601x954.png 1272w, https://substackcdn.com/image/fetch/$s_!AL7a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d5d24a7-67e9-4359-9f33-6c99f29172e0_1601x954.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>All curves meet at <em>x=0.5</em>. When the anonymous quantity is split equally ahead of and behind our order, the model assigns equal cancellation probability to both sides regardless of <em>&#947;</em>.</p><p>For <em>&#947; &gt; 1</em>, the curve becomes steeper around the midpoint. <strong>The model increasingly assigns the reduction to whichever side contains more liquidity</strong>. </p><p>For <em>0 &lt;&#947; &lt; 1</em>, the curve flattens. <strong>Cancellation probabilities are pulled towards </strong><em><strong>0.5</strong></em><strong>, making the model less sensitive to the relative amount of liquidity ahead and behind us.</strong></p><p>In practice, the probability function depends on rather predictable factors such as distance from the top of book. We can generalize the probability function by fitting different curves across reasonable market variables.</p><p>These policy choices and parameters can then be calibrated against empirical  order traces.</p><h2>Calibrating Queue Policies and Parameters</h2><p>We now have several defensible impact and queue models. The remaining question is which model best represents the market we are trying to simulate.</p><p><strong>Calibrating directly against strategy PnL is problematic.</strong> Market-making strategies are state-dependent: one different fill changes inventory, which changes subsequent quotes, cancellations and order sizes. </p><p>The action paths quickly diverge, leaving us unable to determine whether a PnL difference came from the queue model or from the strategy.</p><p>Instead, we calibrate through a <strong>closed-action replay</strong>. <strong>We hold the live order actions fixed and allow only their simulated outcomes to change.</strong></p><h3>Trace and tick-data objects</h3><p>Event journalling architecture in quantpylib was discussed here:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;2a0ba831-ff8a-43d7-8ac5-90b09fa97beb&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;HFT - Event Journaling and Quantpylib's Native Journaling Architecture&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-07-28T16:50:41.350Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!m2hC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c92a4a5-6d3f-49f8-a3ee-acd8c51ce1a9_1672x680.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/hft-event-journaling-and-quantpylibs&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:208855749,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:7,&quot;comment_count&quot;:1,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>Consider an order trace containing:</p><ul><li><p>order and cancellation intents;</p></li><li><p>submission and cancellation timestamps;</p></li><li><p>side, price, size, order type and time-in-force;</p></li><li><p>acknowledgements and terminal order states;</p></li><li><p>fills, including their quantity, price and exchange timestamp.</p></li></ul><p>From this trace, we may extract the exogenous action tape:</p><pre><code><code>submit order A at t1
submit order B at t2
cancel order A at t3
submit order C at t4
...</code></code></pre><p>The second object is the public tick-data stream. It contains the market events required to reconstruct exchange-side state:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;4a687eff-3ee1-4e62-807d-bc230107b288&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Designing Institutional Data Capture for Quantitative Research.&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-07-03T13:17:11.190Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!IRvk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/designing-institutional-data-capture&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:204803981,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:9,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><ul><li><p>L2 snapshots and updates;</p></li><li><p>trades;</p></li><li><p>exchange and receive timestamps;</p></li><li><p>&#8230;<br></p></li></ul><p>The market data capture infrastructure in QuantPylib supports these artefacts.</p><p><strong>For a candidate model </strong><em><strong>&#952;</strong></em><strong>, we replay the same action tape of order submissions and cancellations against the same tick-data stream.</strong></p><p><strong>In QuantPylib, the wall clock is swapped against the replay clock and the same trace architecture generates replay trace files.</strong> <strong>We can then compare the live trace fill against the simulated trace file in a queue replay harness.</strong></p><p>We can therefore compare outcomes order by order and determine quantitatively the &#8220;fitness function of a queue model&#8221;.</p><h3>Fill classification</h3><p>Let <em>I</em> be the set of submitted order intents. Define:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;F=\\{i\\in I:q_i>0\\}&quot;,&quot;id&quot;:&quot;RBNTLSHLIV&quot;}" data-component-name="LatexBlockToDOM"></div><p>as the set of orders which received at least one live fill, and:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\widehat{F}_\\theta\n=\n\\{i\\in I:\\widehat{q}_{i,\\theta}>0\\}&quot;,&quot;id&quot;:&quot;RVAMVPUUCS&quot;}" data-component-name="LatexBlockToDOM"></div><p>as the set filled under candidate model <em>&#952;</em>.</p><p><strong>Fill precision is:</strong></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;P_\\theta\n=\n\\frac{|F\\cap\\widehat{F}_\\theta|}\n{|\\widehat{F}_\\theta|}&quot;,&quot;id&quot;:&quot;CNQHKELWAX&quot;}" data-component-name="LatexBlockToDOM"></div><p>This answers: when the simulation produces a fill, how often did that order also fill live?</p><p><strong>Fill recall is:</strong></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;R_\\theta\n=\n\\frac{|F\\cap\\widehat{F}_\\theta|}\n{|F|}&quot;,&quot;id&quot;:&quot;ZSJECNDJZJ&quot;}" data-component-name="LatexBlockToDOM"></div><p>This answers: how many live-filled orders did the simulation reproduce?</p><p>A combined F1 score is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;F_{1,\\theta}\n=\n\\frac{2P_\\theta R_\\theta}\n{P_\\theta+R_\\theta}&quot;,&quot;id&quot;:&quot;UHEACQKTGC&quot;}" data-component-name="LatexBlockToDOM"></div><p>A pessimistic model may have excellent precision while missing many live fills. An optimistic model may reproduce most live fills while inventing many others.</p><h3>Lifecycle accuracy</h3><p>Let <em>s<sub>i</sub></em> and <em>s&#770;<sub>i,&#952;</sub></em> be the terminal live and simulated states of order <em>i</em>, such as filled, partially filled, cancelled or rejected.</p><p>Lifecycle accuracy is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;A_{\\text{status},\\theta}\n=\n\\frac{1}{|I|}\n\\sum_{i\\in I}\n\\mathbf{1}\n\\left[\ns_i=\\widehat{s}_{i,\\theta}\n\\right]&quot;,&quot;id&quot;:&quot;HETSHOGOFW&quot;}" data-component-name="LatexBlockToDOM"></div><p>This catches differences which a binary filled/unfilled label misses, particularly partial fills and cancellation outcomes.</p><h3>Fill timing</h3><p>For orders filled in both traces, let <em>t<sub>i</sub></em> and <em>t&#770;<sub>i,&#952;</sub></em> be the timestamps of the first live and simulated fills. Define:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;C_\\theta=F\\cap\\widehat{F}_\\theta&quot;,&quot;id&quot;:&quot;AENGUBQXYZ&quot;}" data-component-name="LatexBlockToDOM"></div><p>A smooth timing score is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;S_{t,\\theta}\n=\n\\frac{1}{|C_\\theta|}\n\\sum_{i\\in C_\\theta}\n\\exp\n\\left(\n-\\frac{\n|t_i-\\widehat{t}_{i,\\theta}|\n}{\\tau}\n\\right)&quot;,&quot;id&quot;:&quot;INGQITFPUN&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>The scale <em>&#964;</em> determines the timing tolerance.  The score ranges from zero to one. A score of one represents identical first-fill timestamps, while values near zero indicate timing errors which are large relative to <em>&#964;</em>. <strong>Semantically, it quantifies how closely the simulated trace reproduces first-fill timing for orders filled in both traces.</strong></p><h3>Fill-price similarity</h3><p>Let <em>p<sub>i</sub></em> and <em>p&#770;<sub>i,&#952;</sub></em> be the live and simulated volume-weighted fill prices for an order filled in both traces.</p><p>The price error in basis points is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;e_{i,\\theta}\n=\n10^4\n\\frac{\n|p_i-\\widehat{p}_{i,\\theta}|\n}{p_i}&quot;,&quot;id&quot;:&quot;MTLYKWQJUP&quot;}" data-component-name="LatexBlockToDOM"></div><p>We can convert this into a bounded score:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;S_{p,\\theta}\n=\n\\frac{\n\\sum_{i\\in C_\\theta}\nw_i\n\\exp\n\\left(\n-\\frac{e_{i,\\theta}}{\\kappa}\n\\right)\n}{\n\\sum_{i\\in C_\\theta}w_i\n}&quot;,&quot;id&quot;:&quot;GGSIOHHTWH&quot;}" data-component-name="LatexBlockToDOM"></div><p>where <em>&#954;</em> controls the price-error tolerance and:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;w_i\n=\n\\min(q_i,\\widehat{q}_{i,\\theta})p_i&quot;,&quot;id&quot;:&quot;MYOYMSWJUE&quot;}" data-component-name="LatexBlockToDOM"></div><p>weights the comparison by overlapping filled notional.</p><p>For passive single-price orders, this metric may carry little information: both traces often fill at the submitted limit price. It is more useful for aggressive orders, multi-level executions and partial fills across prices.</p><h3>Cancellation races</h3><p>Cancellation behaviour deserves its own comparison. Let:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;r_i\n=\n\\mathbf{1}\n\\left[\nt_i^{\\text{cancel intent}}\n<\nt_i^{\\text{fill}}\n<\nt_i^{\\text{cancel effective}}\n\\right]&quot;,&quot;id&quot;:&quot;ZQMJAXTGYZ&quot;}" data-component-name="LatexBlockToDOM"></div><p>indicate that order <em>i</em> filled while its cancellation was in flight. Define <em>r&#770;<sub>i,&#952;</sub></em> similarly for the simulation. Cancellation-race accuracy is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;A_{\\text{cancel},\\theta}\n=\n\\frac{1}{|I_{\\text{cancel}}|}\n\\sum_{i\\in I_{\\text{cancel}}}\n\\mathbf{1}\n\\left[\nr_i=\\widehat{r}_{i,\\theta}\n\\right]&quot;,&quot;id&quot;:&quot;NXRMKRQMMF&quot;}" data-component-name="LatexBlockToDOM"></div><p>This exposes a common source of optimistic replay: allowing the order to disappear when the strategy decides to cancel rather than when the cancellation reaches the exchange.</p><h3>Trace similarity as a fitness function</h3><p>The component metrics can be combined into a trace-similarity score:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;S(\\theta)\n=\nw_fF_{1,\\theta}\n+\nw_sA_{\\text{status},\\theta}\n+\nw_qS_{q,\\theta}\n+\nw_tS_{t,\\theta}\n+\nw_pS_{p,\\theta}\n+\nw_cA_{\\text{cancel},\\theta}&quot;,&quot;id&quot;:&quot;LUKXMURUXM&quot;}" data-component-name="LatexBlockToDOM"></div><p>with:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\sum_j w_j=1&quot;,&quot;id&quot;:&quot;FITZNRAFRM&quot;}" data-component-name="LatexBlockToDOM"></div><p><strong>The weights should reflect the use case.</strong> </p><p>For calibration sessions <em>D<sub>train</sub></em>, we select:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\theta^\\star\n=\n\\arg\\max_{\\theta}\n\\frac{1}{|\\mathcal{D}_{\\text{train}}|}\n\\sum_{d\\in\\mathcal{D}_{\\text{train}}}\nS_d(\\theta)&quot;,&quot;id&quot;:&quot;WWZKTAATIE&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>The purpose is not to find the queue model which produces the highest backtest PnL. It is to find the model whose order-level outcomes most closely resemble the empirical trace.</p><p></p><p>thanks for reading. cheers!</p>]]></content:encoded></item><item><title><![CDATA[Tick Data Session Replay in QuantTerminal]]></title><link>https://www.research.hangukquant.com/p/tick-data-session-replay-in-quantterminal</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/tick-data-session-replay-in-quantterminal</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Mon, 10 Aug 2026 15:02:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/bMA0C_WnOSw" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A couple of weeks ago, we introduced the QuantTerminal, equipped with multi-exchange live tick data views.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;4040a6cb-c491-4a52-a6f5-2271313c73d2&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Introduce, the QuantTerminal&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-07-26T16:26:27.442Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!Mrz_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/introduce-the-quantterminal&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:208298022,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:9,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>We also discussed <strong>how can you natively manage your own tick data lake with Quantpylib:</strong></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;4d400e6e-7183-4d6e-a1b1-9f6dac24aadb&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Manage Your Quantitative Tick Data Lake with Quantpylib&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-07-08T18:13:40.870Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!EsF3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/manage-your-quantitative-tick-data&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:206133789,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:6,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p><br>This is the architecture that supports exchange replay fidelity - from when the exchange processed data, to when it dispatched <strong>(TX)</strong> it, <strong>to when you received (RX) it</strong>, giving you critical observability into your own trading stack&#8217;s processing back-pressure and latency figures.<br><br>There is no substitute for high grade fidelity replay for latency-sensitive analytics involved in quantitative trading - public data simply does not make the cut.<br><br><strong>Today, we release the ability to perform session-replay on your own tick data lake in the QuantTerminal.</strong></p><div id="youtube2-bMA0C_WnOSw" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;bMA0C_WnOSw&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/bMA0C_WnOSw?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>Obtain your access pass <strong><a href="https://quantpylib.hangukquant.com/pricing/pricing/">here</a></strong>.<br><br><strong>Terminal access pass cost increases in 1 week. </strong>More on the terminal<strong> <a href="https://quantpylib.hangukquant.com/terminal/">here</a>.<br></strong>Next release will have</p><ul><li><p><strong>private orders, positions, fills display on live exchanges</strong></p></li><li><p><strong>private orders, positions, fills replay on tick data <a href="https://www.research.hangukquant.com/p/hft-event-journaling-and-quantpylibs">with your own trace files.</a></strong></p></li></ul><p>Next post on the blog discusses the architecture and technical details to designing a high fidelity tick data backtest - soon to be released on quantpylib!<br></p>]]></content:encoded></item><item><title><![CDATA[Quantitative Trading Strategies - How I went from 10k to 100k to 1M (part 5: hft mm)]]></title><link>https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-fd5</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-fd5</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Thu, 06 Aug 2026 12:40:46 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Lvvp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e6fa10f-5aa8-4f78-89e1-1eae828b892e_1200x480.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi folks, in the last post, we talked about managing an fx basket:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;a9e4fa4e-68fb-4a53-9b0e-2f89a6dc5888&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Quantitative Trading Strategies - How I went from 10k to 100k to 1M (part 4: managing an FX basket)&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-08-02T13:08:01.259Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!4P_x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-e4c&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:209479046,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:12,&quot;comment_count&quot;:2,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p><br>The last of the Quantitative Trading Strategy series pertains to hft mm. Of course, for obvious reasons - I am unwilling to share in detail the specifics. However, I do want to share <strong>a piece of market microstructural analyses between binance and polymarket crypto markets I did. </strong></p><p>This article is abit of a special format - instead of written form, this is simply a <strong>snippet from Lecture 7 of my (yet to be released) hft lectures I have on the topic. Then some food for thought and tricks.</strong></p><p>The specific figures there are no longer applicable due to the changing dynamics of the markets involved, but the techniques therein are applicable no matter and to orthogonal markets&#8230;</p>
      <p>
          <a href="https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-fd5">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Quantitative Trading Strategies - How I went from 10k to 100k to 1M (part 4: managing an FX basket)]]></title><description><![CDATA[macroeconomic policy, to statistical modelling and portfolio construction]]></description><link>https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-e4c</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-e4c</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Sun, 02 Aug 2026 13:08:01 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!4P_x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi folks, we previously modelled this before, but there <strong>have been significant improvements to the modelling and construction accuracies.</strong> We will discuss FX trading today.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4P_x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4P_x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.png 424w, https://substackcdn.com/image/fetch/$s_!4P_x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.png 848w, https://substackcdn.com/image/fetch/$s_!4P_x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.png 1272w, https://substackcdn.com/image/fetch/$s_!4P_x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4P_x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.png" width="1456" height="431" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:431,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:744244,&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;:&quot;https://www.research.hangukquant.com/i/209479046?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4P_x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.png 424w, https://substackcdn.com/image/fetch/$s_!4P_x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.png 848w, https://substackcdn.com/image/fetch/$s_!4P_x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.png 1272w, https://substackcdn.com/image/fetch/$s_!4P_x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5967bb21-b651-40ca-90fd-f5643aeea331_3186x944.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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><br>Currency desks are commonly divided by geography and market structure: G10, EMFX, LatAm, and so on. In FX, the policy regime plays a significant role in price discovery, and central bank leaning is one of the primary sources of price discovery.</p><p><strong>Python Code for replication is provided at the end of the article. </strong></p><p>In this series, we will be looking at trading SGD crosses. The MAS manages the Singapore dollar against a basket of currencies through the S$NEER.</p><p>The regime is normally described as <strong>basket, band and crawl</strong>:</p><ul><li><p><strong>Basket:</strong> SGD is managed against the currencies of Singapore&#8217;s major trading partners rather than against one bilateral rate.</p></li><li><p><strong>Band:</strong> the trade-weighted index is allowed to move within an undisclosed policy band.</p></li><li><p><strong>Crawl:</strong> the slope of that band is reviewed and adjusted as the inflation and growth outlook changes.</p></li></ul><p>These parameters <strong>are not disclosed</strong>, except for rough &#8220;policy guidance&#8221;. MAS may intervene through spot or forward FX transactions. Insofar as possible, market forces are otherwise allowed to determine where the currency trades inside the band.</p><p>I will leave the economic motivation of these policies as self-reading.</p><p>As you may imagine - for a number of business functions (such as fx hedging, speculation) in banks, hedge funds and whatnot - currency desks are undeterred in modelling these parameters.</p><p>We will perform such an exercise with public data and construct a trading strategy on a basket of tradable assets. Since MAS explains policy decisions in qualitative language, we will come up with a simple, algorithmic state machine. </p><p>In order to assess the quality of our policy recalibration, we will cross-reference with United Overseas Bank (UOB)&#8217;s <a href="https://www.uobgroup.com/web-resources/uobgroup/pdf/research/MN_190321.pdf">2019</a> and <a href="https://www.uob.com.sg/web-resources/uobgroup/pdf/research/MN_210415B.pdf">2021</a> paper.</p><p>We will take a look at these subtasks:</p><ul><li><p>data preparation for statistical modelling</p></li><li><p>performing numerical analysis through constrained regression</p></li><li><p>algorithmic reconstruction of policy mid, band and width</p></li><li><p>portfolio construction from proxy index</p></li><li><p>portfolio construction on tradable basket</p></li></ul><h2>data preparation for statistical modelling</h2><p>We require two datasets for the initial statistical model: the official S$NEER history and bilateral SGD exchange rates. Both are available for free from MAS.</p><p>The official S$NEER history can be downloaded as an XLSX file from the <a href="https://www.mas.gov.sg/statistics/exchange-rates/s$neer">MAS exchange-rate statistics page</a>. For our purposes the workbook contains two relevant fields:</p><pre><code><code>date          sneer
1999-01-08    100.00
1999-01-15     99.75
1999-01-22    100.10</code></code></pre><p>Each value represents the <strong>weekly average S$NEER for the week ending on the stated date</strong>. This gives us the dependent variable. We next need a set of explanatory FX rates.</p><h3>daily FX data</h3><p>Daily end-of-period exchange rates are available through the <a href="https://eservices.mas.gov.sg/apimg-portal/api-catalog">MAS API catalogue</a>. The request requires a (free to obtain) API key and returns JSON records. We retain the following currency fields:</p><pre><code><code>USD, CNY, EUR, MYR, JPY, AUD, GBP, IDR,
KRW, THB, CHF, TWD, INR, PHP, VND and CAD</code></code></pre><p>This is our candidate universe, not a claim about the actual basket. The statistical model will determine which currencies receive weight. The raw columns use the following quote convention:</p><pre><code><code>usd_sgd         SGD per 1 USD
eur_sgd         SGD per 1 EUR
jpy_sgd_100     SGD per 100 JPY
idr_sgd_100     SGD per 100 IDR</code></code></pre><p>We normalise this to sgd_xxx convention.</p><p>A complete cross-section is available beginning January 2008. The FX data is daily while the official S$NEER series is weekly. Since the target represents a weekly average, we take the arithmetic average of each FX series over the same week.</p><p>If <em>W<sub>t</sub></em> is the set of daily observations belonging to week <em>t</em>, the weekly normalized FX level is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;F_{t,i}\n=\n\\frac{1}{|W_t|}\n\\sum_{d\\in W_t}P_{d,i}.&quot;,&quot;id&quot;:&quot;VFWABUDFUA&quot;}" data-component-name="LatexBlockToDOM"></div><p>Let <em>S<sub>t</sub></em> denote the official weekly-average S$NEER level for week <em>t</em>. The resulting DataFrame has one row for each common observation week <em>t=0,&#8230;,T</em>. We denote this weekly level panel by</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\mathcal D\n=\n\\left[\n\\begin{array}{cccc|c}\nF_{0,1} &amp; F_{0,2} &amp; \\cdots &amp; F_{0,n} &amp; S_0\\\\\nF_{1,1} &amp; F_{1,2} &amp; \\cdots &amp; F_{1,n} &amp; S_1\\\\\n\\vdots &amp; \\vdots &amp; \\ddots &amp; \\vdots &amp; \\vdots\\\\\nF_{T,1} &amp; F_{T,2} &amp; \\cdots &amp; F_{T,n} &amp; S_T\n\\end{array}\n\\right]\n=\n\\left[\\mathbf F\\mid\\mathbf S\\right]\n\\in\n\\mathbb R_{+}^{(T+1)\\times(n+1)}.&quot;,&quot;id&quot;:&quot;VMJVNOVOYV&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>The first <em>n</em> columns, <em><strong>F</strong></em>, contain the normalized weekly-average FX levels. The final column, <em><strong>S</strong></em>, contains the corresponding official weekly-average S$NEER levels. In pandas, <code>regression_df</code> is simply the tabular representation of <em>&#119967;</em>.</p><h2>constructing the basket through restricted least squares</h2><p>The statistical problem is to infer a dynamic set of currency weights from the weekly level panel <em>&#119967;=[<strong>F</strong> | <strong>S</strong>]</em>. We use a weighted geometric basket.</p><p>Let <em>S<sub>t</sub></em> denote the official S$NEER level in week <em>t</em>, and let <em>F<sub>t,i</sub></em> denote the normalized weekly-average value of SGD against currency <em>i</em>. We model the changes by differencing the sneer value:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\Delta\\log S_t\n=\n\\sum_{i=1}^{n}w_i\\Delta\\log F_{t,i}\n+\\varepsilon_t.&quot;,&quot;id&quot;:&quot;FUGHILGUZM&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>The residual <em>varepsilon<sub>t</sub></em> absorbs anything else not captured by our candidate universe.</p><p>Define the weekly S$NEER return</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;s_t=\\Delta\\log S_t,&quot;,&quot;id&quot;:&quot;DAPPXGACAW&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>and the vector of bilateral FX returns obtained from the first <em>n</em> columns of <em>&#119967;</em>,</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;r_t=\n\\begin{bmatrix}\n\\Delta\\log F_{t,1} &amp;\n\\Delta\\log F_{t,2} &amp;\n\\cdots &amp;\n\\Delta\\log F_{t,n}\n\\end{bmatrix}^{\\top}.&quot;,&quot;id&quot;:&quot;ERNLBIAVRB&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>Stacking <em>T</em> observations gives</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;y=\n\\begin{bmatrix}\ns_1 &amp; s_2 &amp; \\cdots &amp; s_T\n\\end{bmatrix}^{\\top}\n\\in\\mathbb{R}^{T},&quot;,&quot;id&quot;:&quot;GWGLTAQZEJ&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>and</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;R=\n\\begin{bmatrix}\nr_1^{\\top}\\\\\nr_2^{\\top}\\\\\n\\vdots\\\\\nr_T^{\\top}\n\\end{bmatrix}\n\\in\\mathbb{R}^{T\\times n}.&quot;,&quot;id&quot;:&quot;XWHHQRTEWM&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>The regression can then be written compactly as</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;y=Rw+\\varepsilon.&quot;,&quot;id&quot;:&quot;AXUCWXVMSE&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>An unconstrained least-squares estimator would solve</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\widehat w_{OLS}\n=\n\\arg\\min_w\n\\lVert y-Rw\\rVert_2^2.&quot;,&quot;id&quot;:&quot;DEEVXYNRDL&quot;}" data-component-name="LatexBlockToDOM"></div><p>This may fit the historical S$NEER well while producing an economically implausible basket. The resulting weights may be negative or may not sum to one.</p><p>We know more about the object than ordinary least squares uses. Basket weights should be non-negative, and the complete basket should carry 100% weight. We therefore solve the restricted problem</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\begin{aligned}\n\\widehat w\n=\\arg\\min_w\\quad\n&amp;\\lVert y-Rw\\rVert_2^2,\\\\\n\\text{subject to}\\quad\n&amp;w_i\\geq0,\\\\\n&amp;\\sum_{i=1}^{n}w_i=1.\n\\end{aligned}&quot;,&quot;id&quot;:&quot;BQVKENZJHM&quot;}" data-component-name="LatexBlockToDOM"></div><p>The feasible set is the probability simplex</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\Delta_n\n=\n\\left\\{\nw\\in\\mathbb{R}^{n}:\nw_i\\geq0,\n\\mathbf{1}^{\\top}w=1\n\\right\\}.&quot;,&quot;id&quot;:&quot;QUDFZRVCGR&quot;}" data-component-name="LatexBlockToDOM"></div><p>The restrictions give the coefficients an immediate economic interpretation as basket weights.</p><h3>numerical solution (skip if not interested in the math)</h3><p>The squared-error objective</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f(w)=\\lVert y-Rw\\rVert_2^2&quot;,&quot;id&quot;:&quot;MMCRKYCTZA&quot;}" data-component-name="LatexBlockToDOM"></div><p>is convex, with gradient</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\nabla f(w)\n=\n2R^{\\top}(Rw-y).&quot;,&quot;id&quot;:&quot;IMHXDCCXVF&quot;}" data-component-name="LatexBlockToDOM"></div><p>We solve the constrained problem using projected gradient descent. From a feasible vector <em>w<sub>k</sub></em>, first take an unconstrained gradient step</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;v_{k+1}\n=\nw_k-\\eta\\nabla f(w_k),&quot;,&quot;id&quot;:&quot;CLOSTRAUBA&quot;}" data-component-name="LatexBlockToDOM"></div><p>then project it back onto the simplex:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;w_{k+1}\n=\n\\Pi_{\\Delta_n}(v_{k+1}).&quot;,&quot;id&quot;:&quot;UWUQPCRQEC&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>The projection is itself the optimization problem</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\Pi_{\\Delta_n}(v)\n=\n\\arg\\min_{w\\in\\Delta_n}\n\\frac{1}{2}\\lVert w-v\\rVert_2^2.&quot;,&quot;id&quot;:&quot;GWFXCSURHN&quot;}" data-component-name="LatexBlockToDOM"></div><p>Its solution has the form</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;w_i=\\max(v_i-\\theta,0),&quot;,&quot;id&quot;:&quot;DFXACHLVUF&quot;}" data-component-name="LatexBlockToDOM"></div><p>where <em>&#952;</em> is chosen such that</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\sum_{i=1}^{n}\\max(v_i-\\theta,0)=1.&quot;,&quot;id&quot;:&quot;BWQFFJDFML&quot;}" data-component-name="LatexBlockToDOM"></div><p>Intuitively, we subtract a common threshold from the unconstrained vector, set negative coordinates to zero, and choose the threshold so that the remaining weights sum to one.</p><p>We use the corresponding step size</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\eta\n=\n\\frac{1}{2\\lVert R\\rVert_2^2},&quot;,&quot;id&quot;:&quot;NBLQYZMSJY&quot;}" data-component-name="LatexBlockToDOM"></div><p>and stop when successive projected weight vectors are sufficiently close:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\lVert w_{k+1}-w_k\\rVert_2<\\epsilon.&quot;,&quot;id&quot;:&quot;TJWHCZAQSI&quot;}" data-component-name="LatexBlockToDOM"></div><h3>rolling estimation</h3><p>We estimate a separate basket for every observation week using the most recent <em>m=260</em> weekly returns, or approximately five years. This produces a sequence of models rather than one final model, which are the dynamic weights of the basket across time:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\widehat w_{t_0},\n\\widehat w_{t_0+1},\n\\ldots,\n\\widehat w_T.&quot;,&quot;id&quot;:&quot;ADBOFPSEUJ&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><h3>predicting the S$NEER</h3><p>A model indexed by week <em>t</em> contains the official S$NEER observation for that week. We shift each fitted weight vector forward by one observation through the preceding observation, <em>w&#770;<sub>t-1</sub></em>, and multiply them by the current weekly FX-return vector <em>r<sub>t</sub></em>. The weighted sum is the predicted S$NEER log return. Applying that return to the previous official level gives</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\widehat S_t\n=\nS_{t-1}\\exp\\left(\\widehat w_{t-1}^{\\top}r_t\\right).&quot;,&quot;id&quot;:&quot;WHOLNPEOZP&quot;}" data-component-name="LatexBlockToDOM"></div><p>How well do the previously estimated basket weights explain the next official weekly move?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Sv8S!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa002b211-df16-4e13-a236-47ef73aa3156_2388x1198.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Sv8S!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa002b211-df16-4e13-a236-47ef73aa3156_2388x1198.png 424w, https://substackcdn.com/image/fetch/$s_!Sv8S!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa002b211-df16-4e13-a236-47ef73aa3156_2388x1198.png 848w, https://substackcdn.com/image/fetch/$s_!Sv8S!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa002b211-df16-4e13-a236-47ef73aa3156_2388x1198.png 1272w, https://substackcdn.com/image/fetch/$s_!Sv8S!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa002b211-df16-4e13-a236-47ef73aa3156_2388x1198.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Sv8S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa002b211-df16-4e13-a236-47ef73aa3156_2388x1198.png" width="1456" height="730" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a002b211-df16-4e13-a236-47ef73aa3156_2388x1198.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:730,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:404506,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/209479046?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa002b211-df16-4e13-a236-47ef73aa3156_2388x1198.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Sv8S!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa002b211-df16-4e13-a236-47ef73aa3156_2388x1198.png 424w, https://substackcdn.com/image/fetch/$s_!Sv8S!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa002b211-df16-4e13-a236-47ef73aa3156_2388x1198.png 848w, https://substackcdn.com/image/fetch/$s_!Sv8S!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa002b211-df16-4e13-a236-47ef73aa3156_2388x1198.png 1272w, https://substackcdn.com/image/fetch/$s_!Sv8S!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa002b211-df16-4e13-a236-47ef73aa3156_2388x1198.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>The actual and predicted levels lie almost on top of one another <strong>with a 0.972 correlation between the predicted and official weekly log returns, and a 5.07bps in weekly return RMSE.</strong></p><p>The fit is strong enough to treat the estimated basket as a useful S$NEER proxy. We have a number of remaining parameters to estimate.</p><h2>reconstructing the policy band</h2><p>MAS would make a brilliant X finfluencer, because they are experts in vague-posting. MAS summarises <a href="https://www.mas.gov.sg/monetary-policy/past-monetary-policy-decisions">monetary policy statements</a> in roughly this form:</p><pre><code><code>date          slope                 width                   centre
2018-04-13    Increase slightly     -                       -
2020-03-30    Set at 0%             -                       Re-centre downwards
2022-04-14    Increase slightly     -                       Re-centre upwards</code></code></pre><p>Our job is to translate qualitative policy language into a deterministic state machine. </p><p>Let <em>g</em> denote the annualized slope of the midpoint and let <em>h</em> denote the log half-width of the band. An unchanged field carries its previous value forward. Every other phrase updates one component of the policy state:</p><ul><li><p><strong>increase very slightly:</strong> <em>g &#8592; g+0.5&#948;</em></p></li><li><p><strong>increase slightly:</strong> <em>g &#8592; g+&#948;</em></p></li><li><p><strong>increase:</strong> <em>g &#8592; g+2&#948;</em></p></li><li><p><strong>reduce slightly:</strong> <em>g &#8592; max(0,g-&#948;)</em></p></li><li><p><strong>reduce:</strong> <em>g &#8592; max(0,g-2&#948;)</em></p></li><li><p><strong>set at 0%:</strong> <em>g &#8592; 0</em></p></li><li><p><strong>widen slightly:</strong> <em>h &#8592; 1.25h</em></p></li><li><p><strong>widen:</strong> <em>h &#8592; 1.5h</em></p></li><li><p><strong>restore narrower band:</strong> <em>h &#8592; h<sub>0</sub></em></p></li><li><p><strong>re-centre:</strong> reset the midpoint to the prevailing (predicted) <em>S&#771;<sub>d </sub></em></p></li></ul><p>The rules are symmetric. The zero floor prevents a sequence of reductions from implying a negative slope due to MAS slope policy since the outset.</p><p>We set one slope tick to <em>&#948;=0.5%</em> per annum, use a baseline log half-width of <em>h<sub>0</sub>=0.02</em>, or approximately 2% on either side of the midpoint, and anchor the April initial slope at 2% per annum. </p><p>This is aligned with the UOB&#8217;s paper. Once these values are fixed, the same rules are applied across the entire time series; there is no additional parameter fitting.</p><h3>evolving the midpoint</h3><p>Let <em>M<sub>d</sub></em> be the policy midpoint on day <em>d</em>. Between re-centring decisions, its log level accumulates the prevailing annualized slope:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\log M_d\n=\n\\log M_{d-1}\n+\ng_{d-1}\\Delta\\tau_d,&quot;,&quot;id&quot;:&quot;PDAUEDEELE&quot;}" data-component-name="LatexBlockToDOM"></div><p>where <em>&#916;&#964;<sub>d</sub></em> is the fraction of a year elapsed since the preceding observation. On a re-centring date, we reset <em>M<sub>d</sub></em> to the prevailing reconstructed S$NEER and continue accumulating drift from the new base.</p><p>The upper and lower boundaries are then</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;L_d=M_d\\exp(-h_d),\n\\qquad\nU_d=M_d\\exp(h_d).&quot;,&quot;id&quot;:&quot;XQRLXZDWFV&quot;}" data-component-name="LatexBlockToDOM"></div><p>Using a geometric band keeps both boundaries positive and makes widening symmetric in log-return space.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cuJ2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F001d3e88-d44b-4ce6-b19f-e95fd9f06f7b_2378x1190.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cuJ2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F001d3e88-d44b-4ce6-b19f-e95fd9f06f7b_2378x1190.png 424w, https://substackcdn.com/image/fetch/$s_!cuJ2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F001d3e88-d44b-4ce6-b19f-e95fd9f06f7b_2378x1190.png 848w, https://substackcdn.com/image/fetch/$s_!cuJ2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F001d3e88-d44b-4ce6-b19f-e95fd9f06f7b_2378x1190.png 1272w, https://substackcdn.com/image/fetch/$s_!cuJ2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F001d3e88-d44b-4ce6-b19f-e95fd9f06f7b_2378x1190.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cuJ2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F001d3e88-d44b-4ce6-b19f-e95fd9f06f7b_2378x1190.png" width="1456" height="729" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/001d3e88-d44b-4ce6-b19f-e95fd9f06f7b_2378x1190.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:729,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1037331,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/209479046?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F001d3e88-d44b-4ce6-b19f-e95fd9f06f7b_2378x1190.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cuJ2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F001d3e88-d44b-4ce6-b19f-e95fd9f06f7b_2378x1190.png 424w, https://substackcdn.com/image/fetch/$s_!cuJ2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F001d3e88-d44b-4ce6-b19f-e95fd9f06f7b_2378x1190.png 848w, https://substackcdn.com/image/fetch/$s_!cuJ2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F001d3e88-d44b-4ce6-b19f-e95fd9f06f7b_2378x1190.png 1272w, https://substackcdn.com/image/fetch/$s_!cuJ2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F001d3e88-d44b-4ce6-b19f-e95fd9f06f7b_2378x1190.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>We have now constructed a parsimonious model calibrated against a deterministic state machine, and verified that results are somewhat in line with a reputable bank. If we are economist, we would be happy, but as traders, we make no money from this&#8230;</p><p>But how may we construct a continuous portfolio from this?</p><h3>portfolio construction</h3>
      <p>
          <a href="https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-e4c">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[HFT - Event Journaling and Quantpylib's Native Journaling Architecture]]></title><description><![CDATA[Mathematics, Finance and Their Babies. 
quant research and quant dev.]]></description><link>https://www.research.hangukquant.com/p/hft-event-journaling-and-quantpylibs</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/hft-event-journaling-and-quantpylibs</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Tue, 28 Jul 2026 16:50:41 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!m2hC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c92a4a5-6d3f-49f8-a3ee-acd8c51ce1a9_1672x680.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In software, an event journal is an ordered, append-only record of state transitions accepted by a system. In a HFT trading system, it provides a durable account of important in-memory states such as order state transitions, fills, position deltas, and portfolio snapshots. It records details such as </p><ul><li><p>when an order was created locally and sent into the wire</p></li><li><p>when the order arrived at the exchange</p></li><li><p>when the order-ack was received locally</p></li><li><p>and all other state transitions.</p></li></ul><p>These artefacts can be used downstream for a number of important business functions such as</p><ul><li><p>latency analysis;</p></li><li><p>slippage analysis;</p></li><li><p>markout and adverse-selection analysis;</p></li><li><p>tick-to-trade shortfall;</p></li><li><p>trading-cost attribution; and</p></li><li><p>reconciliation and incident replay.</p></li></ul><p>Event journalling is a core component of replay fidelity. A replay recovers the order in which the live process observed and accepted state changes. A journal lets us rebuild those transitions.</p><p></p><h4><strong>We are running 1-week of discounts of access to Quantpylib:</strong></h4><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;23b91969-7d13-4af0-bdd6-b11e9cbb09ce&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Introduce, the QuantTerminal&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-07-26T16:26:27.442Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!Mrz_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/introduce-the-quantterminal&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:208298022,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:9,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p></p><p><strong>In this article,</strong> we give a rundown of quantpylib&#8217;s native binary event-journal architecture and how to use it, including the Quantpylib Event Trace (QET) compiler. We will also show how quantpylib users can produce QET trace files directly from an OMS workflow.</p><h2>Artefacts</h2><p>In quantpylib, the following portfolio artefacts are journaled:</p><ul><li><p>order state changes;</p></li><li><p>fill insertions;</p></li><li><p>position deltas;</p></li><li><p>order snapshots; and</p></li><li><p>position snapshots.</p><p></p></li></ul><p>We will use an order lifecycle as the running example. Consider the following HYPE limit order:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:&quot;c7e20f0d-482c-4ebe-954d-bea36591d911&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">from decimal import Decimal


order = {
    "exc": "hyperliquid",
    "ticker": "HYPE",
    "amount": Decimal("1"),
    "price": Decimal("20"),
    "tif": "Alo",
    "cloid": oms.rand_cloid(exc="hyperliquid"),
}

await oms.limit_order(**order)</code></pre></div><p>The OMS first constructs the exchange-native order wire. Before submitting that wire, it inserts the order into its in-memory <code>Orders</code> ledger with a <code>CREATE_PENDING</code> status and a local <code>ts_submit_ns</code>. At this point the client order ID (<code>cloid</code>) is known, but the exchange order ID (<code>oid</code>) usually is not. </p><p>When an update arrives through the private order WebSocket, the ledger resolves the order by <code>cloid</code> or <code>oid</code> and applies its staleness and identity checks. A successful acknowledgement will typically complete the identity with an <code>oid</code> and transition the order to <code>NEW</code>. A rejected submission transitions to <code>REJECTED</code>. Later updates may move a live order through <code>PARTIAL</code> and <code>FILLED</code>, or through <code>CANCEL_PENDING</code> and <code>CANCELLED</code> when we attempt a cancellation.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bGO0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1801dd5f-513f-4220-b851-9fc6cd028cba_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bGO0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1801dd5f-513f-4220-b851-9fc6cd028cba_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!bGO0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1801dd5f-513f-4220-b851-9fc6cd028cba_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!bGO0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1801dd5f-513f-4220-b851-9fc6cd028cba_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!bGO0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1801dd5f-513f-4220-b851-9fc6cd028cba_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bGO0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1801dd5f-513f-4220-b851-9fc6cd028cba_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1801dd5f-513f-4220-b851-9fc6cd028cba_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Order lifecycle and binary QET trace&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Order lifecycle and binary QET trace" title="Order lifecycle and binary QET trace" srcset="https://substackcdn.com/image/fetch/$s_!bGO0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1801dd5f-513f-4220-b851-9fc6cd028cba_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!bGO0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1801dd5f-513f-4220-b851-9fc6cd028cba_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!bGO0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1801dd5f-513f-4220-b851-9fc6cd028cba_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!bGO0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1801dd5f-513f-4220-b851-9fc6cd028cba_1672x941.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>The diagram is deliberately simplified. The exact path depends on the venue and execution outcome.</p><p>For the <code>CREATE_PENDING</code> order above, the in-memory object and its trace artefact look like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!az6m!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43a6b521-687e-4c85-922f-9cde45789b66_1672x941.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!az6m!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43a6b521-687e-4c85-922f-9cde45789b66_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!az6m!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43a6b521-687e-4c85-922f-9cde45789b66_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!az6m!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43a6b521-687e-4c85-922f-9cde45789b66_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!az6m!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43a6b521-687e-4c85-922f-9cde45789b66_1672x941.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!az6m!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43a6b521-687e-4c85-922f-9cde45789b66_1672x941.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/43a6b521-687e-4c85-922f-9cde45789b66_1672x941.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;In-memory order encoded as a binary QET trace&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="In-memory order encoded as a binary QET trace" title="In-memory order encoded as a binary QET trace" srcset="https://substackcdn.com/image/fetch/$s_!az6m!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43a6b521-687e-4c85-922f-9cde45789b66_1672x941.png 424w, https://substackcdn.com/image/fetch/$s_!az6m!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43a6b521-687e-4c85-922f-9cde45789b66_1672x941.png 848w, https://substackcdn.com/image/fetch/$s_!az6m!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43a6b521-687e-4c85-922f-9cde45789b66_1672x941.png 1272w, https://substackcdn.com/image/fetch/$s_!az6m!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43a6b521-687e-4c85-922f-9cde45789b66_1672x941.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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><code>S</code><span> identifies the trading session, while </span><code>N</code><span> is the session&#8217;s trace sequence number. Based on the state machine, the appropriate events. such as </span><code>trace.orders.insert</code><span>, </span><code>trace.orders.state_transition</code><span> is created.</span></p><p><strong><span>These actions occur in the trading hot path, so an inefficient transport would make the journal unusable. The trace artefact is compactly encoded as raw bytes and handed to quantpylib's high performance logging subsystem.</span></strong><span> </span></p><p><span>The transport is therefore a native C++ implementation adapted into byte buffers over the LMAX Disruptor pattern, exposed in Python.</span></p><p><span>Read the design here: </span><a href="https://www.research.hangukquant.com/p/designing-state-of-the-art-logging">Designing State-of-the-Art Logging in Python</a><span>. </span></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;5575423b-a20d-4776-a642-a11f9ddb2c03&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Designing State-of-the-Art Logging in Python&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-05-08T12:55:55.552Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!NdZd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40d93e98-9675-4d08-aecc-318e4e4a626b_1682x626.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/designing-state-of-the-art-logging&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:196889438,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:15,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p><span>Insofar as the trading system is concerned, the trace is complete. This makes the trace subsystem a lightweight attachment (a normal logging statement) and non-intrusively composed with client applications.</span></p><p></p><h2>QET Compilation</h2><p>Once the logging hand-off is complete, the log file receives JSONL records of the following shape.</p><pre><code><code>{"level": "INFO", "time": "2026-07...", "message": "trace", "event": "trace.orders.insert", "trace": "qwAAAAMAAAAHAAAA...VzAw"}</code></code></pre><p><code>event</code> identifies the accepted mutation. <code>trace</code> is the original binary artefact, base64-encoded. Trace records and ordinary application logs may share the same file.</p><p>An event journal can be attached directly to a live trading system. <strong>quantpylib instead uses the log files as the substrate and compiles QET files in a separate, cold process.</strong> </p><p>The trading process is finished once it hands the record to the logger; parsing, ordering, deduplication, and journal I/O remain outside the live system.</p><p>Many firms already operate some form of the Grafana logging stack. <a href="https://grafana.com/docs/alloy/latest/">Grafana Alloy</a> acts as the collector. The usual destination is <a href="https://grafana.com/docs/loki/latest/">Grafana Loki</a>, which stores compressed log chunks and indexes their labels for later queries.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!m2hC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c92a4a5-6d3f-49f8-a3ee-acd8c51ce1a9_1672x680.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!m2hC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c92a4a5-6d3f-49f8-a3ee-acd8c51ce1a9_1672x680.png 424w, https://substackcdn.com/image/fetch/$s_!m2hC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c92a4a5-6d3f-49f8-a3ee-acd8c51ce1a9_1672x680.png 848w, https://substackcdn.com/image/fetch/$s_!m2hC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c92a4a5-6d3f-49f8-a3ee-acd8c51ce1a9_1672x680.png 1272w, https://substackcdn.com/image/fetch/$s_!m2hC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c92a4a5-6d3f-49f8-a3ee-acd8c51ce1a9_1672x680.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!m2hC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c92a4a5-6d3f-49f8-a3ee-acd8c51ce1a9_1672x680.png" width="1456" height="592" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c92a4a5-6d3f-49f8-a3ee-acd8c51ce1a9_1672x680.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:592,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;quantpylib binary event journal pipeline&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="quantpylib binary event journal pipeline" title="quantpylib binary event journal pipeline" srcset="https://substackcdn.com/image/fetch/$s_!m2hC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c92a4a5-6d3f-49f8-a3ee-acd8c51ce1a9_1672x680.png 424w, https://substackcdn.com/image/fetch/$s_!m2hC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c92a4a5-6d3f-49f8-a3ee-acd8c51ce1a9_1672x680.png 848w, https://substackcdn.com/image/fetch/$s_!m2hC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c92a4a5-6d3f-49f8-a3ee-acd8c51ce1a9_1672x680.png 1272w, https://substackcdn.com/image/fetch/$s_!m2hC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c92a4a5-6d3f-49f8-a3ee-acd8c51ce1a9_1672x680.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>quantpylib piggybacks on this battle-tested transport. We configure Alloy to push the same records to our compiler's Loki-compatible endpoint:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;b20f4de7-5474-49c4-8d73-ce1f920efd21&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">loki.write "qet_compiler" {
  endpoint {
    url = "http://127.0.0.1:33200/loki/api/v1/push"
  }
}</code></pre></div><p>This can be the sole destination or added to an existing Alloy pipeline.</p><p><span>The compiler is a small local HTTP service that implements the Loki push API. It decompresses each Snappy-compressed protobuf batch, recovers the original JSON line, filters trace records, base64-decodes the trace, and validates the QET schema and record length. </span></p><p><span>The Loki entry timestamp selects the UTC output day; the trace's </span><code>sid</code><span> and </span><code>seqno</code><span> is used for ordering and idempotence. The compiler then appends the original binary records to a daily </span><code>.qet</code><span> file.</span></p><h2>Example</h2><p>Here we will give a walkthrough of how to wire them together.</p><p>Install Alloy using Grafana&#8217;s <a href="https://grafana.com/docs/alloy/latest/set-up/install/">platform instructions</a>. The Alloy CLI command reference is <a href="https://grafana.com/docs/alloy/latest/reference/cli/">here</a>.</p><h3>1. start the compiler</h3><pre><code><code>python3.11 -m quantpylib.hft.qet_compiler serve \
  --root ./qet \
  --host 127.0.0.1 \
  --port 33200 \
  --buffer-size 48</code></code></pre><p>Check its counters from another terminal:</p><pre><code><code>curl http://127.0.0.1:33200/health</code></code></pre><h3>2. start Alloy</h3><p><code>examples/configs.alloy</code> (<a href="https://github.com/hangukquant/quantpylib/blob/main/examples/configs.alloy">quantpylib</a>) points Alloy at an absolute log glob and at the local compiler. Point Alloy at the file written by the example in step 3:</p><pre><code><code>export QUANTPYLIB_LOG_PATH="$(pwd)/logs/journal.log"

alloy validate examples/configs.alloy
alloy run --storage.path=./.alloy-data examples/configs.alloy</code></code></pre><h3>3. run the example</h3><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:&quot;8a49c3e2-0af9-42b4-bf6d-ef68d7cc6d32&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">import os
import asyncio
import logging
from decimal import Decimal

from dotenv import load_dotenv

from quantpylib.hft.oms import OMS
from quantpylib.logger import Logger
from quantpylib.gateway.master import Gateway


load_dotenv()

exchange = "bybit"
ticker = "HYPEUSDT"
amount = Decimal("1")
price = Decimal("10")

async def main():
    gateway = Gateway({
        exchange: {
            "key": os.environ["TEST_BYBIT_KEY"],
            "secret": os.environ["TEST_BYBIT_SECRET"],
        },
    })
    await gateway.init_clients()

    os.makedirs("logs", exist_ok=True)
    logger = Logger(
        name="perf",
        stdout_register=True,
        filename="journal.log",
        logs_dir="./logs",
        file_level=logging.INFO,
    )

    oms = OMS(gateway, logger=logger)

    try:
        await oms.init()
        cloid = oms.rand_cloid(exc=exchange)
        res = await oms.limit_order(
            exc=exchange,
            ticker=ticker,
            amount=amount,
            price=price,
            cloid=cloid,
        )
        print(res)
        await asyncio.sleep(5)

        res = await oms.cancel_order(exc=exchange, ticker=ticker, cloid=cloid)
        print(res)
    finally:
        await oms.cleanup()
        logger.shutdown()

if __name__ == "__main__":
    asyncio.run(main())</code></pre></div><p>In <code>journal.log</code> we see one insert and three state transitions, corresponding to create, create-ack, cancel, and cancel-ack. We also see snapshots, which allow recovery when a new session begins.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;f4902047-3c53-48d9-9abc-6e70fa728da8&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">{"ts":"2026-07-26 17:15:25.642","level":"INFO","filename":"portfolio.py","line":1157,"msg":"trace","event":"trace.orders.snapshot","trace":"b'...'"}
{"ts":"2026-07-26 17:15:25.766","level":"INFO","filename":"portfolio.py","line":408,"msg":"trace","event":"trace.positions.snapshot","trace":"b'...'"}
{"ts":"2026-07-26 17:15:25.965","level":"INFO","filename":"portfolio.py","line":1354,"msg":"trace","event":"trace.orders.insert","trace":"b'...'"}
{"ts":"2026-07-26 17:15:25.998","level":"INFO","filename":"portfolio.py","line":1354,"msg":"trace","event":"trace.orders.state_transition","trace":"b'...'"}
{"ts":"2026-07-26 17:15:31.000","level":"INFO","filename":"portfolio.py","line":1354,"msg":"trace","event":"trace.orders.state_transition","trace":"b'...'"}
{"ts":"2026-07-26 17:15:31.093","level":"INFO","filename":"portfolio.py","line":1354,"msg":"trace","event":"trace.orders.state_transition","trace":"b'...'"}</code></pre></div><p>Inspect the generated qet file here:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:&quot;103362a8-db64-448e-9eb8-3119f173ca0c&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">from pathlib import Path

from quantpylib.hft.qet import QETReader, QET_SCHEMA_REGISTRY


path = sorted(Path("qet").glob("*.qet"))[-1]
reader = QETReader(path)

for event in reader.decoded_records():
    event_type = QET_SCHEMA_REGISTRY[event["schema_id"]].partition("(")[0]
    print(event["sid"], event["seqno"], event_type)</code></pre></div><p><span>which gives me the following traces:</span></p><pre><code>92375019 0 QETOrdersSnapshot
92375019 1 QETPositionsSnapshot
92375019 2 QETOrder
92375019 3 QETOrder
92375019 4 QETOrder
92375019 5 QETOrder</code></pre>]]></content:encoded></item><item><title><![CDATA[Introduce, the QuantTerminal]]></title><link>https://www.research.hangukquant.com/p/introduce-the-quantterminal</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/introduce-the-quantterminal</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Sun, 26 Jul 2026 16:26:27 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Mrz_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>3 years ago, we launched the quantpylib repo.</strong> The goal was to enable quantitative research and trading workflows for quants. Over the years, traders have used the library to research and deploy all sorts of strategies, from loose-pants trend following to complex market-making systems. </p><p>I myself have used quantpylib&#8217;s crypto wrappers on dexs, prediction markets et cetera in latency sensitive workflows to <strong>generate more than $1M in market making pnl, and more than $1B in volume driving my quantitative research and strategies.</strong></p><p>The library allows developers to assimilate into their own trading pipeline, allowing sophisticated traders to use it&#8217;s well-abstracted features at the appropriate layer, whether it is for risk management, offline research, or live trading. </p><p><strong>Today, we announce the QuantTerminal, which gives a face to Quantpylib&#8217;s core features - this will give quant teams an interface and access to end-end applications of the best and most powerful workflows possible in Quantpylib.</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Mrz_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Mrz_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.png 424w, https://substackcdn.com/image/fetch/$s_!Mrz_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.png 848w, https://substackcdn.com/image/fetch/$s_!Mrz_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.png 1272w, https://substackcdn.com/image/fetch/$s_!Mrz_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Mrz_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.png" width="290" height="290" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/850adc34-8c05-4836-b523-d7842311e611_1254x1254.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1254,&quot;width&quot;:1254,&quot;resizeWidth&quot;:290,&quot;bytes&quot;:1107866,&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;:&quot;https://www.research.hangukquant.com/i/208298022?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Mrz_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.png 424w, https://substackcdn.com/image/fetch/$s_!Mrz_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.png 848w, https://substackcdn.com/image/fetch/$s_!Mrz_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.png 1272w, https://substackcdn.com/image/fetch/$s_!Mrz_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850adc34-8c05-4836-b523-d7842311e611_1254x1254.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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><h3>Target Core features</h3><ul><li><p>Live, multi-exchange Tick Data Terminal</p></li><li><p>Live, multi-exchange position and Order Tracking</p></li><li><p>Tick Data Lake Archival and Session Replay</p></li><li><p>Binary Order Event Trace for HFT Market Making</p></li><li><p>Quantitative Analytics for Order Execution (markouts, slippage, latency etc)</p></li><li><p>Live Telemetry</p></li><li><p>and more!</p></li></ul><p>This is an <strong>internal quant tooling system</strong> we&#8217;ve been sitting on, and we have decided to do a staged rollout of it. We understand that quant teams need to own their IPs - code and data are sacred. Therefore, the terminal application is transparent software that is intended to be run locally on your own workstation - with your own data. <strong>It&#8217;s powered by quantpylib, therefore access to the library is a prerequisite.</strong></p><p>First stage of the rollout is the <strong>live terminal view</strong>. Here is a short 30-sec demo. </p><div id="youtube2-ibAkft1yO2E" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;ibAkft1yO2E&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/ibAkft1yO2E?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>Note that it&#8217;s in a beta-stage rollout, and priced as such. As we continue to rollout, we will increase the price of the access pass accordingly.</p><h3>Access, Quantpylib 1 Week Discount</h3><p style="text-align: center;">The QuantTerminal access pass is available here:<br><a href="https://quantpylib.hangukquant.com/pricing/pricing/">https://quantpylib.hangukquant.com/pricing/pricing/</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CFxP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1575a67-09fa-40dc-98db-e5871b0416f9_1306x822.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CFxP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1575a67-09fa-40dc-98db-e5871b0416f9_1306x822.png 424w, https://substackcdn.com/image/fetch/$s_!CFxP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1575a67-09fa-40dc-98db-e5871b0416f9_1306x822.png 848w, https://substackcdn.com/image/fetch/$s_!CFxP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1575a67-09fa-40dc-98db-e5871b0416f9_1306x822.png 1272w, https://substackcdn.com/image/fetch/$s_!CFxP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1575a67-09fa-40dc-98db-e5871b0416f9_1306x822.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CFxP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1575a67-09fa-40dc-98db-e5871b0416f9_1306x822.png" width="1306" height="822" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a1575a67-09fa-40dc-98db-e5871b0416f9_1306x822.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:822,&quot;width&quot;:1306,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:179293,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/208298022?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1575a67-09fa-40dc-98db-e5871b0416f9_1306x822.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CFxP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1575a67-09fa-40dc-98db-e5871b0416f9_1306x822.png 424w, https://substackcdn.com/image/fetch/$s_!CFxP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1575a67-09fa-40dc-98db-e5871b0416f9_1306x822.png 848w, https://substackcdn.com/image/fetch/$s_!CFxP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1575a67-09fa-40dc-98db-e5871b0416f9_1306x822.png 1272w, https://substackcdn.com/image/fetch/$s_!CFxP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1575a67-09fa-40dc-98db-e5871b0416f9_1306x822.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>For one week, we are running discounted access to Quantpylib. Running QuantTerminal requires access to the Quantpylib library.</p><p></p>]]></content:encoded></item><item><title><![CDATA[Quantitative Trading Strategies - How I went from 10k to 100k to 1M (part 3.1: event driven arbitrage)]]></title><description><![CDATA[Mathematics, Finance and Their Babies. 
quant research and quant dev.]]></description><link>https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-12a</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-12a</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Fri, 24 Jul 2026 11:51:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!3nb5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febd8b20b-01f7-4bc9-b498-d8bd3375074c_1672x941.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Prediction markets have attracted considerable attention over the past year, driven by the proliferation of exchanges, liquidity venues and increasingly creative contracts. Pricing theory around many of these contracts remains nascent, and outsized opportunities still exist while more conventional market makers find their footing.</p><p>I have traded more than $100 million in volume across these platforms, generating more than $1 million in PnL. My operations have primarily revolved around three strategy families:</p><ul><li><p>cross-exchange, combinatorial and statistical arbitrage;</p></li><li><p>event-driven arbitrage;</p></li><li><p>high-frequency market making.</p></li></ul><p><strong>The first family</strong> is somewhat capacity-constrained. Liquidity remains shallow across many nascent venues, and seemingly identical contracts are not necessarily fungible. Two exchanges may list economically similar questions while using different resolution sources, deadlines, wording or discretionary procedures. What looks like a locked arbitrage can therefore contain rather more basis risk. In fact, as I write this post, here is an obvious one between poly and hpl.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Jot9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F457c22c9-6ab6-44e1-8c85-ab11c45ae319_1202x1324.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Jot9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F457c22c9-6ab6-44e1-8c85-ab11c45ae319_1202x1324.png 424w, https://substackcdn.com/image/fetch/$s_!Jot9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F457c22c9-6ab6-44e1-8c85-ab11c45ae319_1202x1324.png 848w, https://substackcdn.com/image/fetch/$s_!Jot9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F457c22c9-6ab6-44e1-8c85-ab11c45ae319_1202x1324.png 1272w, https://substackcdn.com/image/fetch/$s_!Jot9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F457c22c9-6ab6-44e1-8c85-ab11c45ae319_1202x1324.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Jot9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F457c22c9-6ab6-44e1-8c85-ab11c45ae319_1202x1324.png" width="552" height="608.0266222961731" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/457c22c9-6ab6-44e1-8c85-ab11c45ae319_1202x1324.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1324,&quot;width&quot;:1202,&quot;resizeWidth&quot;:552,&quot;bytes&quot;:523536,&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;:&quot;https://www.research.hangukquant.com/i/208021198?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F457c22c9-6ab6-44e1-8c85-ab11c45ae319_1202x1324.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Jot9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F457c22c9-6ab6-44e1-8c85-ab11c45ae319_1202x1324.png 424w, https://substackcdn.com/image/fetch/$s_!Jot9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F457c22c9-6ab6-44e1-8c85-ab11c45ae319_1202x1324.png 848w, https://substackcdn.com/image/fetch/$s_!Jot9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F457c22c9-6ab6-44e1-8c85-ab11c45ae319_1202x1324.png 1272w, https://substackcdn.com/image/fetch/$s_!Jot9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F457c22c9-6ab6-44e1-8c85-ab11c45ae319_1202x1324.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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> </p><p><strong>The second family</strong> is considerably more scalable, but requires serious thought around engineering processes. I ran reduced-form versions of these strategies in the past before eventually pausing them. Too many parts of the system were &#8220;non-automatable&#8221;: particularly around sourcing new contracts, registering new data sources et-cetera.</p><p><strong>Recent improvements in agentic systems&#8212;particularly following GPT5.5 and Opus4.8 make the problem interesting again in my opinion.</strong></p><p><strong>The third strategy</strong> family, high-frequency market making, is the most scalable of the three. It also requires proper domain expertise, quantitative reasoning and a reasonably intimate understanding of exchange microstructure. This is what placed me near the top of the relevant leaderboards in terms of both volume and PnL.</p><p>We have, in fact, documented an entire lecture series detailing the design and implementation of my HFT ops, to be later posted <a href="https://lectures.hangukquant.com/">here</a>.</p><p>It will not be released until yours truly is no longer involved in said markets.</p><p>For now, we will focus on event-driven arbitrage. Our discussion here will take a more <em>idealistic approach compared to what I ran</em>, accounting for the scalability now possible under accelerated agentic capabilities. The objective is a pipeline capable of serving hundreds to thousands, of prediction-market contracts.</p>
      <p>
          <a href="https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-12a">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Quantitative Trading Strategies - How I went from 10k to 100k to 1M (part 2: trading in factor space)]]></title><description><![CDATA[factor-trading in crypto, with code]]></description><link>https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-3df</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-3df</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Sat, 18 Jul 2026 16:37:49 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!haFO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd713ca0e-cf3d-4137-a399-d0a3ccaa3601_1456x399.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><span>PSA: we have an </span><strong><span>ongoing, 1-week 50% discount on all subs.</span></strong></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;6348eed7-19a9-4e1b-9995-3cec21d46526&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Quantitative Trading Strategies - How I went from 10k to 100k to 1M (new series intro)&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-07-13T15:27:14.056Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!XNBn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/quantitative-trading-strategies-how&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:206797572,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:17,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p></p><p><strong>A</strong> factor model is motivated by the observation that market movements are primarily driven by a relatively small number of common sources of risk. Assets may have thousands of individual return streams, but much of their variation is shared: broad market movements, industries, economic characteristics, liquidity conditions, or latent statistical relationships. The purpose of a factor model is to separate these common movements from asset-specific noise.</p><p>There are three broad approaches: <strong>Fama-style (time-series) portfolio factors</strong>, <strong>statistical factor models such as PCA</strong>, and <strong>Barra-style (cross-sectional) exposure models</strong>. They differ not merely in interpretation, but in the direction of estimation, the information supplied to the model, and the quantity being estimated.</p><p>Getting timely exposure to desirable factors &#8212; and hedging undesirable ones &#8212; is a primary concern of smart-beta funds and are a TRILLION dollar industry. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!haFO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd713ca0e-cf3d-4137-a399-d0a3ccaa3601_1456x399.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!haFO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd713ca0e-cf3d-4137-a399-d0a3ccaa3601_1456x399.webp 424w, https://substackcdn.com/image/fetch/$s_!haFO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd713ca0e-cf3d-4137-a399-d0a3ccaa3601_1456x399.webp 848w, https://substackcdn.com/image/fetch/$s_!haFO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd713ca0e-cf3d-4137-a399-d0a3ccaa3601_1456x399.webp 1272w, https://substackcdn.com/image/fetch/$s_!haFO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd713ca0e-cf3d-4137-a399-d0a3ccaa3601_1456x399.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!haFO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd713ca0e-cf3d-4137-a399-d0a3ccaa3601_1456x399.webp" width="1456" height="399" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d713ca0e-cf3d-4137-a399-d0a3ccaa3601_1456x399.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:399,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:25172,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/206813161?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd713ca0e-cf3d-4137-a399-d0a3ccaa3601_1456x399.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!haFO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd713ca0e-cf3d-4137-a399-d0a3ccaa3601_1456x399.webp 424w, https://substackcdn.com/image/fetch/$s_!haFO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd713ca0e-cf3d-4137-a399-d0a3ccaa3601_1456x399.webp 848w, https://substackcdn.com/image/fetch/$s_!haFO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd713ca0e-cf3d-4137-a399-d0a3ccaa3601_1456x399.webp 1272w, https://substackcdn.com/image/fetch/$s_!haFO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd713ca0e-cf3d-4137-a399-d0a3ccaa3601_1456x399.webp 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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>Factor analysis in crypto is still nascent. This article focuses on Barra-style models and how I actively trade them to enhance my pnl. </p><p><strong>The full implementation is included at the bottom.</strong></p><p>We will touch lightly on the first two, and then detail a Barra-style analysis with code.</p><h2>Fama-style</h2><p>A Fama-style factor is defined as the return of a portfolio. For example, a simplified value factor might be</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_{\\mathrm{value},t}\n=\nR_{\\mathrm{high\\ value},t}\n-\nR_{\\mathrm{low\\ value},t}.&quot;,&quot;id&quot;:&quot;OWHEQIPCCJ&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>More generally, if (<em>p<sub>k,t</sub></em>) contains the asset weights of factor portfolio (<em>k</em>), then</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_{k,t}=p_{k,t}'R_t.&quot;,&quot;id&quot;:&quot;KFQEYMHZGS&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Once these factor-return histories have been constructed, the <strong>exposure of an individual asset is estimated through time:</strong></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\underbrace{r_i}_{T\\times1}\n=\n\\alpha_i\\mathbf 1\n+\n\\underbrace{F}_{T\\times K}\n\\underbrace{\\beta_i}_{K\\times1}\n+\n\\epsilon_i.&quot;,&quot;id&quot;:&quot;GCBDFAFQZK&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The factor-return matrix (<em>F</em>) is known. The regression estimates (<em>&#946;<sub>i</sub></em>):</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\widehat{\\beta}_i\n=\n(F'F)^{-1}F'r_i.&quot;,&quot;id&quot;:&quot;WHVDMMNGRW&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>For a single, demeaned factor,</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\widehat{\\beta}_i\n=\n\\frac{\\operatorname{Cov}(r_i,f)}\n{\\operatorname{Var}(f)}.&quot;,&quot;id&quot;:&quot;EGDMXSSQZH&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p><strong>Fama-style models are motivated by economic hypotheses about expected returns.</strong> Is a manager&#8217;s apparent alpha simply compensation for exposure to known factor strategies? Is our portfolio (statistically) significantly just some beta against a factor portfolio?</p><p>For a portfolio with estimated factor betas (<em>&#946;<sub>p</sub></em>),</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\operatorname{Var}(r_p)\n=\n\\beta_p'\\Sigma_F\\beta_p\n+\n\\sigma_{\\epsilon,p}^2.&quot;,&quot;id&quot;:&quot;AUDVSIVIFD&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><h2>Statistical-style</h2><p>A statistical factor model begins with the complete return matrix:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;R\\in\\mathbb R^{T\\times N},&quot;,&quot;id&quot;:&quot;YWPMZDWBBF&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>where rows are dates and columns are assets. It seeks a lower-dimensional approximation:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;R\\approx FL'+E,&quot;,&quot;id&quot;:&quot;NGCRPYEPMF&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>where <em>F</em> &#8712; &#8477;<sup>T&#215;K</sup> contains the statistical factor returns and <em>L</em> &#8712; &#8477;<sup>N&#215;K</sup> contains the asset loadings. In principal components analysis, first estimate the asset covariance matrix:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\Sigma_R\n=\n\\frac{1}{T-1}R'R,&quot;,&quot;id&quot;:&quot;IWCFZNNDRS&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>of demeaned returns. Decompose it as</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\Sigma_R=V\\Lambda V'.&quot;,&quot;id&quot;:&quot;UUOTIICYLG&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The first (<em>K</em>) eigenvectors define the principal directions:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;V_K=\n\\begin{bmatrix}\nv_1 &amp; \\cdots &amp; v_K\n\\end{bmatrix},&quot;,&quot;id&quot;:&quot;JGQVTGGNZZ&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>and the corresponding factor scores are</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;F=RV_K.&quot;,&quot;id&quot;:&quot;ECLAFNMGFZ&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The resulting rank-(<em>K</em>) reconstruction is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;R\\approx FV_K'.&quot;,&quot;id&quot;:&quot;PSRNDHKIOD&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Unlike the Fama regression, however, neither the factors nor the loadings are specified economically. </p><p>These are <strong>motivated mainly by dimensionality reduction</strong>. If hundreds of assets share a few dominant covariance patterns, the researcher may want to discover those patterns without imposing characteristic taxonomy.</p><p><a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3530390">Here is a seminal paper on enhanced portfolio optimization using principal components by AQR&#8217;s Pedersen et al.</a></p><h2>Barra-style </h2><p>The focus of our post, is the Barra-style model. We will first discover it&#8217;s mathematical basis, and then use them to identify sector performance.</p><p>We begin by specifying each asset&#8217;s exposures. On date (<em>t</em>),</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;B_t\\in\\mathbb R^{N\\times K}&quot;,&quot;id&quot;:&quot;CVZWMANRQF&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>contains exposures to K factors, such as categories, industries, countries, or continuous styles such as size and momentum.</p><p>The model then examines the <strong>cross-section of asset returns on that date:</strong></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\underbrace{R_t}_{N\\times1}\n=\n\\underbrace{B_t}_{N\\times K}\n\\underbrace{f_t}_{K\\times1}\n+\n\\epsilon_t.&quot;,&quot;id&quot;:&quot;GDAPQLMLIY&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The <strong>exposures (</strong><em><strong>B<sub>t</sub></strong></em><strong>) are known. The factor returns (</strong><em><strong>f<sub>t</sub></strong></em><strong>) are estimated</strong> using the (<em>N</em>) assets observed on that date. </p><p><strong>This regression is repeated for every date, therefore produces a time series of factor returns from a sequence of cross-sectional regressions.</strong></p><p>Barra-style models are motivated by the need to describe the current economic composition of a portfolio. Rather than waiting for a long return history to reveal a portfolio&#8217;s betas, the manager declares or measures the underlying asset exposures directly.</p><p>Repeating the cross-sectional regression each day produces a synthetic return series for every factor. By extension, if sector inclusion is defined as a factor, we obtain the synthetic return of the sector performance.</p><p>They are useful to:</p><ul><li><p>portfolio managers performing return attribution;</p></li><li><p>risk managers estimating common and specific risk;</p></li><li><p>traders neutralising unwanted industry or style bets;</p></li><li><p><em><strong>isolating sector performance for smart beta plays.</strong></em></p><p></p></li></ul><p>The factor return has a different meaning from a Fama-style factor. It is the return attributed to one unit of exposure after controlling for the other exposures in the cross-sectional regression. </p><h2>Example'; crypto Barra model</h2><p>We will demonstrate the categorical Barra analysis here using a reduced four-asset problem with two categories. The full regression code can be found at the bottom.</p><p>Let&#8217;s begin.</p><p>Suppose our universe contains four assets:</p><ul><li><p><strong>BTC</strong> &#8212; L1; daily return 4%; liquidity score 4.</p></li><li><p><strong>ETH</strong> &#8212; L1; daily return 2%; liquidity score 2.</p></li><li><p><strong>DOGE</strong> &#8212; Meme; daily return 8%; liquidity score 1.</p></li><li><p><strong>PEPE</strong> &#8212; Meme; daily return 6%; liquidity score 1.</p></li></ul><p>The objective is to estimate three returns:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_t=\n\\begin{bmatrix}\nf_{\\mathrm{market},t}\\\\\nf_{\\mathrm{L1},t}\\\\\nf_{\\mathrm{Meme},t}\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;BCJOCGUSMY&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The market factor represents the weighted return of the crypto universe. The category factors represent L1 and Meme performance relative to that market.</p><h3>1. Construct the return vector</h3><p>For each asset, the daily close-to-close return is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;r_{i,t}\n=\n\\frac{P_{i,t}}{P_{i,t-1}}-1.&quot;,&quot;id&quot;:&quot;QBHNFWAGXO&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Collect the four asset returns into the vector</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;y_t=\n\\begin{bmatrix}\nr_{\\mathrm{BTC},t}\\\\\nr_{\\mathrm{ETH},t}\\\\\nr_{\\mathrm{DOGE},t}\\\\\nr_{\\mathrm{PEPE},t}\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;PICTAWXKGC&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>This is the dependent variable in the daily cross-sectional regression.</p><h3>2. Construct the regression weights</h3><p>For each day, determine asset&#8217;s regression weight. Reasonably, we may choose the square root of its preceding 30-day dollar volume:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;q_{i,t}\n=\n\\sqrt{\n\\sum_{\\tau=t-30}^{t-1}\nP_{i,\\tau}V_{i,\\tau}\n}.&quot;,&quot;id&quot;:&quot;BTZLISHCRN&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The weights are then normalised:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;w_{i,t}\n=\n\\frac{q_{i,t}}{\\sum_jq_{j,t}}.&quot;,&quot;id&quot;:&quot;KGTMRPAHKA&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Our simplified liquidity scores are</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;q=\n\\begin{bmatrix}\n4\\\\\n2\\\\\n1\\\\\n1\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;OVTZPSPRBJ&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Since they sum to eight, the normalised weights are</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;w=\n\\begin{bmatrix}\n0.50\\\\\n0.25\\\\\n0.125\\\\\n0.125\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;XDBQMSUDHR&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The WLS weighting matrix is simply diag(w).</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;W=\n\\begin{bmatrix}\n0.50&amp;0&amp;0&amp;0\\\\\n0&amp;0.25&amp;0&amp;0\\\\\n0&amp;0&amp;0.125&amp;0\\\\\n0&amp;0&amp;0&amp;0.125\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;ZGEIEQKAJD&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>BTC contributes half of the regression weight, ETH contributes one quarter, and DOGE and PEPE each contribute one eighth.</p><h3>3. Construct the exposure matrix</h3><p>Every asset has market exposure equal to one. It also has exposure equal to one to its assigned category.</p><p>The exposure matrix is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;X=\n\\begin{bmatrix}\n1&amp;1&amp;0\\\\\n1&amp;1&amp;0\\\\\n1&amp;0&amp;1\\\\\n1&amp;0&amp;1\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;PAYGCVVLQN&quot;}" data-component-name="LatexBlockToDOM"></div><p>for columns [market, L1, Meme] and rows [BTC, ETH, DOGE, PEPE].</p><p>Each day, the regression equation is given by (solve for <em>f</em>)</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;y=Xf+\\epsilon.&quot;,&quot;id&quot;:&quot;XENVCEVQOK&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>For instance,</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;r_{\\mathrm{BTC}}\n=\nf_{\\mathrm{market}}\n+\nf_{\\mathrm{L1}}\n+\n\\epsilon_{\\mathrm{BTC}},&quot;,&quot;id&quot;:&quot;LEXXVGZVHO&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;r_{\\mathrm{PEPE}}\n=\nf_{\\mathrm{market}}\n+\nf_{\\mathrm{Meme}}\n+\n\\epsilon_{\\mathrm{PEPE}}.&quot;,&quot;id&quot;:&quot;PHVXMGIXBC&quot;}" data-component-name="LatexBlockToDOM"></div><p>The model assigns the same fitted common return to assets in the same category. Differences between the individual asset returns in a fitted category return remain in the residuals.</p><h3>4. Remove collinearity problem</h3><p>The market column is equal to the sum of the two category columns:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;X_{\\mathrm{market}}\n=\nX_{\\mathrm{L1}}\n+\nX_{\\mathrm{Meme}}.&quot;,&quot;id&quot;:&quot;OODGHFBWJN&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Consequently, the exposure matrix does not have full column rank.</p><p>For a particular solution</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\left(\nf_{\\mathrm{market}},\nf_{\\mathrm{L1}},\nf_{\\mathrm{Meme}}\n\\right)&quot;,&quot;id&quot;:&quot;XTLXQUXLYI&quot;}" data-component-name="LatexBlockToDOM"></div><p>and any constant <em>a</em>,</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\left(\nf_{\\mathrm{market}}+a,\nf_{\\mathrm{L1}}-a,\nf_{\\mathrm{Meme}}-a\n\\right)&quot;,&quot;id&quot;:&quot;OPZSQNZXQI&quot;}" data-component-name="LatexBlockToDOM"></div><p>produces exactly the same fitted asset returns.</p><p><strong>We</strong> <strong>may solve this by requiring the liquidity-weighted average category return to equal zero.</strong></p><h3>5. Reduction of Degree of Freedom</h3><p>Let the aggregate weight of <strong>category </strong><em><strong>c</strong></em> be</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;s_c\n=\n\\sum_{i\\in c}w_i.&quot;,&quot;id&quot;:&quot;PSNVLEZTHV&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>In our example,</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;s_{\\mathrm{L1}}\n=\n0.50+0.25\n=\n0.75&quot;,&quot;id&quot;:&quot;YVQVVZUCNE&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;s_{\\mathrm{Meme}}\n=\n0.125+0.125\n=\n0.25.&quot;,&quot;id&quot;:&quot;VKQFDSAVEW&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>We impose</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;s_{\\mathrm{L1}}f_{\\mathrm{L1}}\n+\ns_{\\mathrm{Meme}}f_{\\mathrm{Meme}}\n=\n0.&quot;,&quot;id&quot;:&quot;FAXLYRNJTU&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Substituting the category weights,</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;0.75f_{\\mathrm{L1}}\n+\n0.25f_{\\mathrm{Meme}}\n=\n0.&quot;,&quot;id&quot;:&quot;IJXQFJUWVX&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The constraint vector is therefore</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;c=\n\\begin{bmatrix}\n0\\\\\n0.75\\\\\n0.25\n\\end{bmatrix},&quot;,&quot;id&quot;:&quot;YQEPOJNSFL&quot;}" data-component-name="LatexBlockToDOM"></div><p>and the constraint is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;c'f=0.&quot;,&quot;id&quot;:&quot;XXHCZBOAGU&quot;}" data-component-name="LatexBlockToDOM"></div><p><strong>The leading zero means that the market coefficient is not directly constrained.</strong> </p><p></p><h3>6. Solving the constrained WLS</h3><p>We minimise the weighted squared residuals:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\widehat f\n=\n\\arg\\min_f\n\\frac{1}{2}\n(y-Xf)'W(y-Xf)&quot;,&quot;id&quot;:&quot;VCBVGXWLJS&quot;}" data-component-name="LatexBlockToDOM"></div><p>subject to</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;c'f=0.&quot;,&quot;id&quot;:&quot;DCTQOZMNGV&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Introduce a Lagrange multiplier <em>&#955;</em>:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\mathcal L(f,\\lambda)\n=\n\\frac{1}{2}\n(y-Xf)'W(y-Xf)\n+\n\\lambda c'f.&quot;,&quot;id&quot;:&quot;RIDVVOOJIQ&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The first-order condition with respect to <em>f</em> is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;-X'W(y-Xf)+c\\lambda=0.&quot;,&quot;id&quot;:&quot;ORYSDZAPIN&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Rearranging,</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;X'WXf+c\\lambda=X'Wy.&quot;,&quot;id&quot;:&quot;ZJMNPBZBKM&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The first-order condition with respect to <em>&#955;</em> is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;c'f=0.&quot;,&quot;id&quot;:&quot;IXSQGTNODF&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Combining the two equations produces the KKT system:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\begin{bmatrix}\nX'WX&amp;c\\\\\nc'&amp;0\n\\end{bmatrix}\n\\begin{bmatrix}\n\\widehat f\\\\\n\\lambda\n\\end{bmatrix}\n=\n\\begin{bmatrix}\nX'Wy\\\\\n0\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;BTVELVIGRW&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>For our example,</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;X'WX\n=\n\\begin{bmatrix}\n1&amp;0.75&amp;0.25\\\\\n0.75&amp;0.75&amp;0\\\\\n0.25&amp;0&amp;0.25\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;BKMKTTDWYO&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The weighted return vector is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;X'Wy\n=\n\\begin{bmatrix}\n0.0425\\\\\n0.0250\\\\\n0.0175\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;JOATWJKCRH&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The first element is the weighted return contribution of the whole market:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;0.50(0.04)\n+\n0.25(0.02)\n+\n0.125(0.08)\n+\n0.125(0.06)\n=\n0.0425.&quot;,&quot;id&quot;:&quot;KAGYSICTZS&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The second is the weighted contribution from L1 assets:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;0.50(0.04)+0.25(0.02)=0.0250.&quot;,&quot;id&quot;:&quot;NQWXBXDXLQ&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The third is the weighted contribution from Meme assets:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;0.125(0.08)+0.125(0.06)=0.0175.&quot;,&quot;id&quot;:&quot;VXBSHDOJIO&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The complete system is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\begin{bmatrix}\n1&amp;0.75&amp;0.25&amp;0\\\\\n0.75&amp;0.75&amp;0&amp;0.75\\\\\n0.25&amp;0&amp;0.25&amp;0.25\\\\\n0&amp;0.75&amp;0.25&amp;0\n\\end{bmatrix}\n\\begin{bmatrix}\nf_{\\mathrm{market}}\\\\\nf_{\\mathrm{L1}}\\\\\nf_{\\mathrm{Meme}}\\\\\n\\lambda\n\\end{bmatrix}\n=\n\\begin{bmatrix}\n0.0425\\\\\n0.0250\\\\\n0.0175\\\\\n0\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;FLWUVWKMEA&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Solving gives</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_{\\mathrm{market}}\n=\n0.0425,&quot;,&quot;id&quot;:&quot;NCTNEISWPT&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_{\\mathrm{L1}}\n=\n-0.0091667,&quot;,&quot;id&quot;:&quot;TTFKTHVIBQ&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_{\\mathrm{Meme}}\n=\n0.0275.&quot;,&quot;id&quot;:&quot;FXPWBCQCTD&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The constraint is satisfied:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;0.75(-0.9167\\%)\n+\n0.25(2.75\\%)\n=\n0.&quot;,&quot;id&quot;:&quot;QGWGKMNPMP&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><h3>7. Interpretations</h3><p>The weighted return of the L1 category is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\overline r_{\\mathrm{L1}}\n=\n\\frac{\n0.50(4\\%)\n+\n0.25(2\\%)\n}{\n0.75\n}\n=\n3.3333\\%.&quot;,&quot;id&quot;:&quot;DUYTEQDWPG&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The weighted return of the Meme category is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\overline r_{\\mathrm{Meme}}\n=\n\\frac{\n0.125(8\\%)\n+\n0.125(6\\%)\n}{\n0.25\n}\n=\n7\\%.&quot;,&quot;id&quot;:&quot;YEMKHASMCR&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The category coefficients <em>are the differences between these category returns and the weighted market return:</em></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_{\\mathrm{L1}}\n=\n3.3333\\%-4.25\\%\n=\n-0.9167\\%,&quot;,&quot;id&quot;:&quot;NFNFTCNZGF&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_{\\mathrm{Meme}}\n=\n7\\%-4.25\\%\n=\n2.75\\%.&quot;,&quot;id&quot;:&quot;OYRTIUIBQS&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>The fitted common return for an L1 asset is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_{\\mathrm{market}}+f_{\\mathrm{L1}}\n=\n4.25\\%-0.9167\\%\n=\n3.3333\\%.&quot;,&quot;id&quot;:&quot;ACXCYCQYSP&quot;}" data-component-name="LatexBlockToDOM"></div><p>The regression therefore tells us:</p><ul><li><p>the weighted market returned <em>4.25%</em>;</p></li><li><p>L1 underperformed the market by <em>0.9167%</em>;</p></li></ul><p>And the same exercise applies to the Memes category.</p><p>The residuals describe the returns not explained by category membership.</p><p>For BTC,</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\epsilon_{\\mathrm{BTC}}\n=\n4\\%-3.3333\\%\n=\n0.6667\\%.&quot;,&quot;id&quot;:&quot;AAEOIHXCUM&quot;}" data-component-name="LatexBlockToDOM"></div><h3>8. Repeat the analysis through time</h3><p>The same cross-sectional regression is repeated for every date <em>t</em>. Each regression produces one market return and one relative return for every represented category:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\widehat f_t\n=\n\\begin{bmatrix}\n\\widehat f_{\\mathrm{market},t}\\\\\n\\widehat f_{\\mathrm{L1},t}\\\\\n\\widehat f_{\\mathrm{Meme},t}\\\\\n\\vdots\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;KUMNZJUUVL&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Stacking the daily estimates produces a synthetic return history for every category/sector.</p><p>For example,</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\left\\{\nf_{\\mathrm{Meme},1},\nf_{\\mathrm{Meme},2},\n\\ldots,\nf_{\\mathrm{Meme},T}\n\\right\\}&quot;,&quot;id&quot;:&quot;WVIXURGZNJ&quot;}" data-component-name="LatexBlockToDOM"></div><p>is the estimated history of the crypto meme-sector relative to the weighted crypto market. If we take these as &#8216;sector returns&#8217; and compound them from 1, we essentially have a synthetic sector index. This is (theoretically) tradable with a factor-mimicking portfolio.</p><h3>9. Recover the factor-mimicking weights</h3><p>The estimated coefficients are linear combinations of the asset returns. We may therefore recover asset weights that reproduce them exactly.</p><p>For the market factor, the mimicking weights are the normalised regression weights:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;p_{\\mathrm{market}}\n=\n\\begin{bmatrix}\n0.50\\\\\n0.25\\\\\n0.125\\\\\n0.125\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;YFKKKQVZXY&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>For category <em>c</em>, the mimicking weights are</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;p_{c,i}\n=\n\\mathbf 1\\{i\\in c\\}\n\\frac{w_i}{s_c}\n-\nw_i.&quot;,&quot;id&quot;:&quot;EDMXMDVIJW&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>For L1, this gives</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;p_{\\mathrm{L1}}\n=\n\\begin{bmatrix}\n0.50/0.75-0.50\\\\\n0.25/0.75-0.25\\\\\n-0.125\\\\\n-0.125\n\\end{bmatrix}\n=\n\\begin{bmatrix}\n0.1667\\\\\n0.0833\\\\\n-0.125\\\\\n-0.125\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;PPUXHRSCSM&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>These weights sum to zero:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;0.1667+0.0833-0.125-0.125=0.&quot;,&quot;id&quot;:&quot;BYBWDEDGYS&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Their realised return is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;p_{\\mathrm{L1}}'y\n=\n0.1667(4\\%)\n+\n0.0833(2\\%)\n-\n0.125(8\\%)\n-\n0.125(6\\%)\n=\n-0.9167\\%.&quot;,&quot;id&quot;:&quot;JKPOGGSYST&quot;}" data-component-name="LatexBlockToDOM"></div><p>For Meme,</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;p_{\\mathrm{Meme}}\n=\n\\begin{bmatrix}\n-0.50\\\\\n-0.25\\\\\n0.125/0.25-0.125\\\\\n0.125/0.25-0.125\n\\end{bmatrix}\n=\n\\begin{bmatrix}\n-0.50\\\\\n-0.25\\\\\n0.375\\\\\n0.375\n\\end{bmatrix}.&quot;,&quot;id&quot;:&quot;AENOSNVHMW&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p>Its return is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;p_{\\mathrm{Meme}}'y\n=\n-0.50(4\\%)\n-\n0.25(2\\%)\n+\n0.375(8\\%)\n+\n0.375(6\\%)\n=\n2.75\\%.&quot;,&quot;id&quot;:&quot;VLUDZKDEZZ&quot;}" data-component-name="LatexBlockToDOM"></div><p style="text-align: center;"></p><p><strong>This exactly reproduces the L1 factor return.</strong></p><p><strong>The category factor can therefore be interpreted as a long position in the weighted category basket and a short position in the weighted market basket.</strong></p><p><strong>The factor-mimicking portfolio exists exactly in the mathematics.</strong> Essentially, what we have done is to transform quantitative analysis from price space to factor space, using statistical categorical analysis. In the process, we might</p><ul><li><p>better appreciate crypto asset returns as a mixture of factors/sectors</p></li><li><p>construct a more informed portfolio by reducing noise in our samples</p></li></ul><p>For instance, using &#8220;theoretical&#8221; factor-mimicking portfolios, we may look to construct a long-short delta neutral portfolio for &#8220;bullish sectors&#8221; against &#8220;bearish sectors&#8221;. Or we may look to &#8220;enhance&#8221; our trend construction from the previous post to trading in the factor space, subject to same considerations of portfolio construction that were discussed.</p><h3>Code:</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!y5iF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d5b0fb-a147-469f-a887-136a94395538_3402x1236.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!y5iF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d5b0fb-a147-469f-a887-136a94395538_3402x1236.png 424w, https://substackcdn.com/image/fetch/$s_!y5iF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d5b0fb-a147-469f-a887-136a94395538_3402x1236.png 848w, https://substackcdn.com/image/fetch/$s_!y5iF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d5b0fb-a147-469f-a887-136a94395538_3402x1236.png 1272w, https://substackcdn.com/image/fetch/$s_!y5iF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d5b0fb-a147-469f-a887-136a94395538_3402x1236.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!y5iF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d5b0fb-a147-469f-a887-136a94395538_3402x1236.png" width="728" height="264.5" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/44d5b0fb-a147-469f-a887-136a94395538_3402x1236.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:529,&quot;width&quot;:1456,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:607935,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/206813161?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d5b0fb-a147-469f-a887-136a94395538_3402x1236.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!y5iF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d5b0fb-a147-469f-a887-136a94395538_3402x1236.png 424w, https://substackcdn.com/image/fetch/$s_!y5iF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d5b0fb-a147-469f-a887-136a94395538_3402x1236.png 848w, https://substackcdn.com/image/fetch/$s_!y5iF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d5b0fb-a147-469f-a887-136a94395538_3402x1236.png 1272w, https://substackcdn.com/image/fetch/$s_!y5iF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d5b0fb-a147-469f-a887-136a94395538_3402x1236.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>Let&#8217;s take a look an example construction of the above test to a universe of hundred tickers from Binance and Python code.</p>
      <p>
          <a href="https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-3df">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Quantitative Trading Strategies - How I went from 10k to 100k to 1M (part 1: trend my friend)]]></title><description><![CDATA[trend following over the years, with code]]></description><link>https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-c9a</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-c9a</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Wed, 15 Jul 2026 12:48:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Y886!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F244fa5f1-4c11-4691-8df0-b48ebfec32e2_3412x936.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><span>PSA: we have an </span><strong><span>ongoing, 1-week 50% discount on all subs.</span></strong></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;3630dda0-7909-444c-add6-86f429d4528e&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Quantitative Trading Strategies - How I went from 10k to 100k to 1M (new series intro)&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-07-13T15:27:14.056Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!XNBn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/quantitative-trading-strategies-how&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:206797572,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:16,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p><span><br></span><strong><span>IN</span></strong><span> my first quant internship, I was tasked with testing commodity futures skew effects.<br><br></span><strong><span>pm:</span></strong><span> "how did you account for contract roll"<br><br></span><strong><span>me:</span></strong><span> "treated them as continuous, sometimes it's contango sometimes backwardated, so. it's small approximation error"</span></p><p><strong><span>pm: </span>&#128529;</strong></p><p>In trading, a lot of effects and strategies are known. Index rebalancing, stat arb, yield curve arbitrage, market making - are all known strategies. The devil is in the details, and like my old self, <em><strong>doing something and doing something right </strong></em><strong>are completely different things. If you are targeting these strategies, fantastic! You are in the right arena. For those testing some inverse shoulder rsi combo schtick, it&#8217;s time to come around. </strong>No shame in where the journey starts.</p><p>This article is dedicated a little bit to that - when asked about how one should &#8220;start their quant journey&#8221;, I always default to this one - a fantastically simple strategy that opens up a ton of critical questions that expand to more complex strategies. For example</p><ul><li><p>Execution fees and optimal rebalancing</p></li><li><p>Signal quantisation</p></li><li><p>Volatility and square root laws</p></li><li><p>Diversification</p></li><li><p>Backtesting sanitation</p></li><li><p>Signal transformation</p></li><li><p>Risk targeting/management</p></li><li><p>Order automation</p></li></ul><p>It is also one of the strategies that is &#8220;slow enough&#8221; that can be handled manually, and where different components mentioned above can be automated &#8220;one-at-a-time&#8221;, which is the good old principle of abstraction and core principle of building complex systems.<br></p><p>Our <em>next post</em> will continue on factor trading and how I leverage &#8216;smart-beta&#8217; strategies to enhance portfolio returns.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y886!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F244fa5f1-4c11-4691-8df0-b48ebfec32e2_3412x936.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y886!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F244fa5f1-4c11-4691-8df0-b48ebfec32e2_3412x936.png 424w, https://substackcdn.com/image/fetch/$s_!Y886!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F244fa5f1-4c11-4691-8df0-b48ebfec32e2_3412x936.png 848w, https://substackcdn.com/image/fetch/$s_!Y886!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F244fa5f1-4c11-4691-8df0-b48ebfec32e2_3412x936.png 1272w, https://substackcdn.com/image/fetch/$s_!Y886!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F244fa5f1-4c11-4691-8df0-b48ebfec32e2_3412x936.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y886!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F244fa5f1-4c11-4691-8df0-b48ebfec32e2_3412x936.png" width="1456" height="399" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/244fa5f1-4c11-4691-8df0-b48ebfec32e2_3412x936.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:399,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1003607,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/206978369?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F244fa5f1-4c11-4691-8df0-b48ebfec32e2_3412x936.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Y886!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F244fa5f1-4c11-4691-8df0-b48ebfec32e2_3412x936.png 424w, https://substackcdn.com/image/fetch/$s_!Y886!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F244fa5f1-4c11-4691-8df0-b48ebfec32e2_3412x936.png 848w, https://substackcdn.com/image/fetch/$s_!Y886!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F244fa5f1-4c11-4691-8df0-b48ebfec32e2_3412x936.png 1272w, https://substackcdn.com/image/fetch/$s_!Y886!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F244fa5f1-4c11-4691-8df0-b48ebfec32e2_3412x936.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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></p><p>Shall we begin? </p><p><strong>(Code is attached at the bottom.)</strong></p><h3>Signal is the easy part.</h3><p>The high-level rule is simple: buy markets that are going up and sell markets that are going down. It gives us a strategy whose intuition can be stated in one sentence, and then there is everything else.</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\text{market data} \\rightarrow \\text{trend signal} \\rightarrow \\text{forecast} \\rightarrow \\text{position} \\rightarrow \\text{portfolio} &quot;,&quot;id&quot;:&quot;HEIUYLUVPV&quot;}" data-component-name="LatexBlockToDOM"></div><p>Until we specify how strongly to trade the signal, how much risk to allocate to each asset, how contracts are sized, when trades are executed and how costs are charged, it&#8217;s not a quantifiable test.</p><p>Trend following is therefore a useful first quantitative strategy for two reasons. It is simple enough that we can intuit the entire research process, while being rich enough to expose common lapses in framework and backtesting.</p><p>Moskowitz, Ooi and Pedersen document this effect across equity-index, currency, commodity and bond futures. A diversified portfolio of these signals produced returns with little exposure to conventional asset-pricing factors and <a href="https://w4.stern.nyu.edu/facdir/lpederse/papers/TimeSeriesMomentum.pdf">tended to perform well during large market moves</a>.</p><p>Let&#8217;s just say, there is a <em>ton</em> (two centuries) of evidence supporting trend following: <a href="https://research.cbs.dk/en/publications/a-century-of-evidence-on-trend-following-investing/">A Century of Evidence on Trend-Following Investing</a> and <a href="https://arxiv.org/abs/1404.3274">Two Centuries of Trend Following</a>.</p><p>As they say, if it&#8217;s robust, simple does the trick. The simplest discrete signal is the sign of a trailing return:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;s_{i,t}\n=\n\\operatorname{sign}\n\\left(\n\\frac{P_{i,t}}{P_{i,t-h}}-1\n\\right)&quot;,&quot;id&quot;:&quot;WIZXIVYRSA&quot;}" data-component-name="LatexBlockToDOM"></div><p>The forecast is +1 when the asset has appreciated over the previous <strong>h</strong> periods and -1 when it has depreciated.</p><p>A moving-average crossover produces a similar binary rule:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;s_{i,t}\n=\n\\operatorname{sign}\n\\left(\nMA^{\\text{fast}}_{i,t}\n-\nMA^{\\text{slow}}_{i,t}\n\\right)&quot;,&quot;id&quot;:&quot;IGJOZDQOLV&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>Now imagine if you were thirsty, and you could only drink or not drink a litre at a time. That would be miserable. A continuous forecast tries to retain information about trend strength. </p><p>A continuous forecast distinguishes between a weak and strong trend. It can also move gradually through zero rather than jumping directly from fully short to fully long. <a href="https://www.cmegroup.com/education/files/demystifiing-time-series-momentum-strategies.pdf">Continuous rules based on the statistical strength of a trend can materially reduce turnover without a statistically significant performance penalty</a>. </p><p>One possible construction is a volatility-normalised trailing return:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_{i,t}\n=\n\\operatorname{clip}\n\\left(\n\\frac{\\sum_{k=1}^{h} r_{i,t-k}}\n     {\\hat{\\sigma}_{i,t}\\sqrt{h}},\n-f_{\\max},\nf_{\\max}\n\\right)&quot;,&quot;id&quot;:&quot;UBQOUAAANX&quot;}" data-component-name="LatexBlockToDOM"></div><p>In more nuance, weak trends appear to persist, but the relationship eventually saturates. We know this from the Potters and Bouchaud paper. The appropriate forecast may therefore look less like an infinitely increasing linear function and more like a clipped or saturating one. A sensible forecast transformation is often saturating:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\tilde f_{i,t}\n=\n\\tanh\\left(\\frac{f_{i,t}}{c}\\right)&quot;,&quot;id&quot;:&quot;NAOKCBZYTA&quot;}" data-component-name="LatexBlockToDOM"></div><h3>Can I Have One HubbaHubba of Egg Contracts? On Risk.</h3><p>Said no-one ever. </p><p>Suppose Bitcoin and interest-rate futures both produce a forecast of +1. What does this even mean? Giving them the same dollar exposure makes no sense from an economic standpoint. A standard normalisation feature to encode a dimensionless forecast is the forecast annualised return volatility of asset <em>i:</em></p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;u_{i,t}\n=\nb_i\n\\frac{f_{i,t}}{\\hat{\\sigma}_{i,t}}&quot;,&quot;id&quot;:&quot;KVKWXHEIBI&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>where <em>b_i</em> is an instrument or asset-class risk budget.</p><p>The inverse-volatility term gives smaller positions to volatile assets and larger positions to quiet assets. With binary forecasts and equal risk budgets, each <strong>instrument contributes approximately the same standalone volatility before correlations are considered.</strong></p><p>Extending this framework, asset normalisation does not guarantee portfolio risk stability. 10 contracts long A and 10 contracts short B is a different portfolio from 10 contracts long in each. Instruments are correlated, correlations are dynamic, and the positions are too.</p><p>Let <em>u_t</em> be the vector of preliminary exposures and let <em>Sigma</em> be the forecast covariance matrix of asset returns. The forecast volatility of the preliminary portfolio is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\hat{\\sigma}_{p,t}\n=\n\\sqrt{u_t^\\top \\hat{\\Sigma}_t u_t}&quot;,&quot;id&quot;:&quot;MFHOGHBVWF&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>Given a portfolio volatility target, the final exposure vector is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;w_t\n=\n\\frac{\\sigma^\\text{target}}\n     {\\hat{\\sigma}_{p,t}}\nu_t&quot;,&quot;id&quot;:&quot;HKKZFEZWPB&quot;}" data-component-name="LatexBlockToDOM"></div><p>scaling the whole portfolio so that its forecast volatility equals the target.</p><p>There are therefore two distinct pieces of risk management:</p><ol><li><p>Asset-level normalisation prevents volatile instruments from dominating the portfolio performance.</p></li><li><p>Portfolio-level scaling adjusts total leverage based on dynamic correlations and the realised volatility of the combined strategy in relation to target.</p></li></ol><p>Volatility targeting has a wider literature of its own. <a href="https://www.nber.org/papers/w22208">Reducing exposure during high-volatility periods improves the historical Sharpe ratios of several risk factors</a>. </p><h3>We Live in the Real World</h3><p>For a linear contract, a simplified conversion from notional weight to units is</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;q_{i,t}\n=\n\\frac{A_t w_{i,t}}\n     {P_{i,t}M_iX_{i,t}}&quot;,&quot;id&quot;:&quot;CBGDYVEXMH&quot;}" data-component-name="LatexBlockToDOM"></div><p>where A is the portfolio capital, P is the contract price, M is contract multiplier and X is the currency conversion. The position must then respect integer contract quantities, minimum order sizes, tick sizes, leverage limits and venue-specific margin rules. This may surprise some crypto traders, but you can&#8217;t always buy 0.0001 of $MONKEY coin in liquid futures markets where standardised contracts trade in (large) fixed sizes. Accordingly, this tracking error can play a part in &#8216;which universe of assets&#8217; are sensibly tradable for hedge funds - even when AUM is minimally tens of millions! When generating backtests, we need to be careful about directionally correct and economically meaningless results.</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;r_{p,t+1}\n=\nw_t^\\top r_{t+1}\n-\nC(\\Delta w_t)\n-\n\\operatorname{Carry}_{t+1}&quot;,&quot;id&quot;:&quot;GAZAWPXVTV&quot;}" data-component-name="LatexBlockToDOM"></div><p><br>Next on the chopping board of reality are fees. The cost function includes commissions, bid-ask spreads, slippage, market impact and carry/funding costs.  </p><p>Thankfully, when doing longer-term trend following, fees are more&#8230;secondary class citizens. However, as you evolve in your career as a trader, or look at higher frequency trading, you, too, will come to obsess about fees. But <strong>for now, </strong><em><strong>in this post,</strong> </em>we can be abit more cavalier about it.</p><p>To be frank, cost management and proper backtesting principles probably deserve an entire series on its own, but that borders on the HOW rather than the WHAT, and I promised not to bore you with the how in this series. I do have an entire post on <a href="https://quantpylib.hangukquant.com/learn/statistical_finance/#statistical-inferencing-for-quantitative-strategies">statistical inferencing for backtest validation</a>, if you are interested. </p><p>So, for now - <strong>COST IS IMPORTANT, and non-negligible, </strong>and ideas from optimal control theory suggest that we should&#8230;have continuous signals but not continuous positions. This prevents us from &#8220;flip-flopping&#8221; our holdings and paying the broker or the market maker excessively. Fortunately, we can get 95% of the way there with 5% of the brain: by applying &#8220;positional inertia&#8221; - the inertia to trade into target position when the current position is sufficiently close to the target.</p><p>The &#8220;rough-ideal&#8221; for inertia levels can be set by setting average trading costs and varying inertia levels, and then simply doing a walk forward backtest to find the optimal tradeoff. If robustness is anywhere found, a <em>reasonable band</em> will appear. Generally, the more noise (or low Sharpe your cost-free strategy is), the larger should be your inertia threshold. If your signal is all-noise, then you should just sit on your hands and stop trading all together.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!R1m1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ad33681-dc77-4a3c-9ad1-80b290d49ee3_564x500.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!R1m1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ad33681-dc77-4a3c-9ad1-80b290d49ee3_564x500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!R1m1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ad33681-dc77-4a3c-9ad1-80b290d49ee3_564x500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!R1m1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ad33681-dc77-4a3c-9ad1-80b290d49ee3_564x500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!R1m1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ad33681-dc77-4a3c-9ad1-80b290d49ee3_564x500.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!R1m1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ad33681-dc77-4a3c-9ad1-80b290d49ee3_564x500.jpeg" width="564" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0ad33681-dc77-4a3c-9ad1-80b290d49ee3_564x500.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:564,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&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_!R1m1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ad33681-dc77-4a3c-9ad1-80b290d49ee3_564x500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!R1m1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ad33681-dc77-4a3c-9ad1-80b290d49ee3_564x500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!R1m1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ad33681-dc77-4a3c-9ad1-80b290d49ee3_564x500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!R1m1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ad33681-dc77-4a3c-9ad1-80b290d49ee3_564x500.jpeg 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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><h4>Code</h4><h4><strong>Comparing with and without costs:</strong></h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qycE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc2b36f-dca1-40cd-8e7a-53f520f7e915_1456x534.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qycE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc2b36f-dca1-40cd-8e7a-53f520f7e915_1456x534.webp 424w, https://substackcdn.com/image/fetch/$s_!qycE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc2b36f-dca1-40cd-8e7a-53f520f7e915_1456x534.webp 848w, https://substackcdn.com/image/fetch/$s_!qycE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc2b36f-dca1-40cd-8e7a-53f520f7e915_1456x534.webp 1272w, https://substackcdn.com/image/fetch/$s_!qycE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc2b36f-dca1-40cd-8e7a-53f520f7e915_1456x534.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qycE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc2b36f-dca1-40cd-8e7a-53f520f7e915_1456x534.webp" width="1456" height="534" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3bc2b36f-dca1-40cd-8e7a-53f520f7e915_1456x534.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:534,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:34326,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/206978369?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc2b36f-dca1-40cd-8e7a-53f520f7e915_1456x534.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qycE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc2b36f-dca1-40cd-8e7a-53f520f7e915_1456x534.webp 424w, https://substackcdn.com/image/fetch/$s_!qycE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc2b36f-dca1-40cd-8e7a-53f520f7e915_1456x534.webp 848w, https://substackcdn.com/image/fetch/$s_!qycE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc2b36f-dca1-40cd-8e7a-53f520f7e915_1456x534.webp 1272w, https://substackcdn.com/image/fetch/$s_!qycE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bc2b36f-dca1-40cd-8e7a-53f520f7e915_1456x534.webp 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>From a code perspective, it is critical from a research infrastructural standpoint to encompass all (or most) of the above concerns in a parsimonious framework. What separates novice traders from more sophisticated quantitative analysts is the research harness.</p>
      <p>
          <a href="https://www.research.hangukquant.com/p/quantitative-trading-strategies-how-c9a">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Quantitative Trading Strategies - How I went from 10k to 100k to 1M (new series intro)]]></title><description><![CDATA[uncovering some of the dirty work]]></description><link>https://www.research.hangukquant.com/p/quantitative-trading-strategies-how</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/quantitative-trading-strategies-how</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Mon, 13 Jul 2026 15:27:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!XNBn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Not too long ago, I ran the nimble market-maker series, discussing important techniques for <strong>quants in pseudo-competitive</strong> trading environments.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;e15247fb-9532-40bb-a044-aaef858d8517&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Nimble Market-Maker Alpha&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2025-11-19T17:21:12.345Z&quot;,&quot;cover_image&quot;:&quot;https://images.unsplash.com/photo-1734787101540-050257ab9ded?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyMnx8ZHdhcmZ8ZW58MHx8fHwxNzYyMTkyMTczfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=1080&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/nimble-market-maker-alpha&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:177905187,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:16,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>We developed a number of critical tips and tricks there that the quantitative trader should be aware of when profiling and deploying trading strategies. It was very well received, and a reader even changed their username to thenimblemm &#128517;</p><p></p><p>I&#8217;ve been writing this blog for 5 years now, and over the years - we focused mainly on developing quantitative <em>research frameworks</em> - on the <strong>how rather than the what</strong><em>. </em>Here and there, we discussed some quantitative <em>strategies, which talk about the what.</em></p><p><strong>After half a decade, I thought it would be a nice series to give some more detail into WHAT goes on behind the scenes in my &#8216;dirty operations&#8217;.</strong></p><p>From trend following, to factor trading, FX policy arbitrage, event driven trading, to cross-exchange statistical arbitrage and hft market making - these 5 years was a busy one!</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;816e252c-aef6-4fd5-9f0c-5982acf27aa2&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;lg&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;2 Years, 1M PnL and Life as a Solo Crypto Quant&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-04-10T16:15:21.296Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!Lvvp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e6fa10f-5aa8-4f78-89e1-1eae828b892e_1200x480.jpeg&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/2-years-1m-pnl-and-life-as-a-solo&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:193809007,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:54,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><h3>7 Days Discount</h3><p>For 1 week, all subscription plans are 50% off:</p><p><a href="https://www.research.hangukquant.com/d7b4564d">https://www.research.hangukquant.com/d7b4564d</a></p><p>You can also support me with a Lifetime Subscription here:</p><p><a href="https://buy.stripe.com/dRm3cw0mC05N6Am3XKe7m0f">https://buy.stripe.com/dRm3cw0mC05N6Am3XKe7m0f</a></p><p><br><strong>Shout out to the ~300 lifetime members who have supported me, love ya back.</strong></p><p><strong>Hope you look forward to the series!</strong></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XNBn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XNBn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png 424w, https://substackcdn.com/image/fetch/$s_!XNBn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png 848w, https://substackcdn.com/image/fetch/$s_!XNBn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png 1272w, https://substackcdn.com/image/fetch/$s_!XNBn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XNBn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png" width="48" height="20.406593406593405" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:619,&quot;width&quot;:1456,&quot;resizeWidth&quot;:48,&quot;bytes&quot;:96487,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/206797572?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XNBn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png 424w, https://substackcdn.com/image/fetch/$s_!XNBn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png 848w, https://substackcdn.com/image/fetch/$s_!XNBn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png 1272w, https://substackcdn.com/image/fetch/$s_!XNBn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3385a8ef-4ad1-44bf-b1cd-72a423fd5984_1728x735.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p>]]></content:encoded></item><item><title><![CDATA[Manage Your Quantitative Tick Data Lake with Quantpylib]]></title><description><![CDATA[Mathematics, Finance and Their Babies. 
quant research and quant dev.]]></description><link>https://www.research.hangukquant.com/p/manage-your-quantitative-tick-data</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/manage-your-quantitative-tick-data</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Wed, 08 Jul 2026 18:13:40 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!EsF3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the last post, we discussed what institutional data capture needs to preserve and how to design a clean architecture for maintaining your own data lake for quantitative research.</p><p>This is available in quantpylib, our quant repo for annual, paid subscribers:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;c08cb5e7-045f-4abb-bf54-66c9becbb158&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;HangukQuant quantpylib Github Repo&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2023-11-24T16:59:27.729Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/hangukquant-community-github-repo&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:139132009,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:29,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>We have <strong>redesigned critical core architecture and subsystems that will enable powerful workflows for traders using quantpylib</strong> in their trading infrastructure. Examples include performant and institutional-grade data replay, event journaling, telemetry systems and quantitative analytics.</p><p>We are proud to announce that managing your data lake has been now made a ~100~ lines of code powered by quantpylib, into raw binary flat files.</p><p>We have also shipped and documented a bunch of improvements to our backend, including cpp implementations for native orderbooks states. Once we launch versioning, we will deprecate old APIs.</p><p>See our data archival example here:</p><p><a href="https://quantpylib.hangukquant.com/hft/hft/#data-archival">https://quantpylib.hangukquant.com/hft/hft/#data-archival</a></p><p>See our feed model and QBN encoding notes:</p><p><a href="https://quantpylib.hangukquant.com/hft/feed/">https://quantpylib.hangukquant.com/hft/feed/</a></p><p><a href="https://quantpylib.hangukquant.com/hft/l0/">https://quantpylib.hangukquant.com/hft/l0/</a></p><p>Our new, performant native orderbook implementation is documented here:<br><a href="https://quantpylib.hangukquant.com/hft/orderbook/">https://quantpylib.hangukquant.com/hft/orderbook/</a><br></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EsF3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EsF3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png 424w, https://substackcdn.com/image/fetch/$s_!EsF3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png 848w, https://substackcdn.com/image/fetch/$s_!EsF3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png 1272w, https://substackcdn.com/image/fetch/$s_!EsF3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EsF3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png" width="1456" height="1283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1283,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1868483,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.research.hangukquant.com/i/206133789?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EsF3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png 424w, https://substackcdn.com/image/fetch/$s_!EsF3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png 848w, https://substackcdn.com/image/fetch/$s_!EsF3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png 1272w, https://substackcdn.com/image/fetch/$s_!EsF3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b55722f-9904-41e9-90b2-f389db65ee22_2150x1894.png 1456w" sizes="100vw" loading="lazy"></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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>We continue our aim of providing institutional grade trading infrastructure available to serious traders.</p><h5>Note:<br>We intend to increase quantpylib&#8217;s costs over the coming weeks with a change in access model. Existing users with access will see no change. Non-subscribers may obtain an access pass <a href="https://quantpylib.hangukquant.com/pricing/pricing/">here</a>.</h5><p></p>]]></content:encoded></item><item><title><![CDATA[Designing Institutional Data Capture for Quantitative Research.]]></title><description><![CDATA[Payload to Disk.]]></description><link>https://www.research.hangukquant.com/p/designing-institutional-data-capture</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/designing-institutional-data-capture</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Fri, 03 Jul 2026 13:17:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!IRvk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello folks, I&#8217;ve spent the couple of months working on quantpylib, and the bulk of the refactor has been done~ I am excited to start doing up the docs so our users can experiment with it. <strong>As early as next week!</strong></p><p>One of the revamped subsystems was the improvement of data capture architecture towards more institutional grade archival policies. This article will be dedicated to describing what may constitute such a change.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IRvk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IRvk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.png 424w, https://substackcdn.com/image/fetch/$s_!IRvk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.png 848w, https://substackcdn.com/image/fetch/$s_!IRvk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.png 1272w, https://substackcdn.com/image/fetch/$s_!IRvk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IRvk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.png" width="663" height="363.83035714285717" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:799,&quot;width&quot;:1456,&quot;resizeWidth&quot;:663,&quot;bytes&quot;:1611185,&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;:&quot;https://www.research.hangukquant.com/i/204803981?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IRvk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.png 424w, https://substackcdn.com/image/fetch/$s_!IRvk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.png 848w, https://substackcdn.com/image/fetch/$s_!IRvk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.png 1272w, https://substackcdn.com/image/fetch/$s_!IRvk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da95310-88bf-4654-8ff1-9732597a1bf2_1693x929.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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></p><p><strong>Modern quantitative research</strong> is becoming less constrained by storage cost and more constrained by the quality of the artefacts we choose to preserve. Cheap cloud object stores, high-throughput local disks, and increasingly capable agents have changed the economics of retention. It is now <em>cheaper to store, easier to dig, </em><strong>making</strong><em><strong> </strong></em><strong>data storage policies and approach correctness a step-change more important as an interface for humans and intelligent solutions to sift through valuable insights hidden in the data.</strong></p><p>For a trading desk, the highest-value artefacts are the operational record: market data, order traces, fills, gateway logs, replay journals, risk decisions, and the metadata that ties these streams together. Agents are good at sifting, ranking, joining, and summarising. But they are only as useful as the substrate underneath them.</p>
      <p>
          <a href="https://www.research.hangukquant.com/p/designing-institutional-data-capture">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Designing L2 and L3 Orderbook (without Templates)]]></title><description><![CDATA[with Mechanical and Situational Empathy]]></description><link>https://www.research.hangukquant.com/p/designing-l2-and-l3-orderbook-without</link><guid isPermaLink="false">https://www.research.hangukquant.com/p/designing-l2-and-l3-orderbook-without</guid><dc:creator><![CDATA[HangukQuant]]></dc:creator><pubDate>Wed, 10 Jun 2026 17:17:49 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/sX2nF1fW7kI" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello folks, it&#8217;s been awhile. I&#8217;ve spent the last 2+ weeks working day-day on the quantpylib library. A handful of folks have requested access recently, and I have not yet updated the docs, simply because our dev speed is too rapid atm and it would be futile to keep it updated. Forgive me for that.<br>Previously, we <strong>introduced a new state of the art logging subsystem:</strong></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;812af068-652c-4f3f-a3d2-667c51653491&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;lg&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Designing State-of-the-Art Logging in Python&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2026-05-08T12:55:55.553Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!NdZd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40d93e98-9675-4d08-aecc-318e4e4a626b_1682x626.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/designing-state-of-the-art-logging&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:196889438,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:13,&quot;comment_count&quot;:0,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p><br>And as of late, we have <strong>completely revamped the archival subsystem (to a custom L0 binary capture),</strong> and am in the process of rewriting the native orderbooks, as well as data replay systems. I am also working on a sidecar terminal application so that traders/market makers with strategies powered by quantpylib have institutional grade trading infrastructure backing them.</p><p>Anyhow, since I was on the topic, today, we are going to do a light(er) article on implementing an orderbook. Previously, we already spoke on this topic:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;10056097-7741-4535-baca-e5a3a75b74ef&quot;,&quot;caption&quot;:&quot;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Implementing a C-level Orderbook in Python&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:42788676,&quot;name&quot;:&quot;HangukQuant&quot;,&quot;bio&quot;:&quot;quant research and quant dev. not financial advice.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/733e6c1a-d932-4d0f-8f5a-4fa0c33d8d29_4096x2528.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:100}],&quot;post_date&quot;:&quot;2025-03-14T17:57:26.147Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F656511ba-42cb-4ddc-8274-26db66aeb882_1000x500.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://www.research.hangukquant.com/p/implementing-a-c-level-orderbook&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:159076270,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:8,&quot;comment_count&quot;:4,&quot;publication_id&quot;:453792,&quot;publication_name&quot;:&quot;HangukQuant Research&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!LX9y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5718e3-074f-4c1d-a77d-f1fa609a9ea0_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>While that was a pretty simple and intuitive discussion, much more detail can be assigned to this task. It is also a common question at quant dev interviews, and I have recently had quant friends drilled on these.</p><p>Extending from our previous discussion, if we would like to extend an orderbook implementation into something matching-engine compatible and full-depth, the book needs to support queue position. That means the interface is no longer only MBP (market by price), but rather an MBO surface (market by order). </p><p>When it comes to L3 implementation, there are roughly two schools of thought. The standard text of reference is David Gross&#8217;s CppCon talk, <em>When Nanoseconds Matter: Ultrafast Trading Systems in C++</em>.</p><div id="youtube2-sX2nF1fW7kI" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;sX2nF1fW7kI&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/sX2nF1fW7kI?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>Some of the design pressures in this post are motivated by that discussion. Here we will provide some clarity and implementation on Gross&#8217;s solution and also expand on the crypto&#8217;s common L2 domain, and how we can support both interface efficiently without template overhead.</p>
      <p>
          <a href="https://www.research.hangukquant.com/p/designing-l2-and-l3-orderbook-without">
              Read more
          </a>
      </p>
   ]]></content:encoded></item></channel></rss>