<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Emily</title>
    <description>The latest articles on Forem by Emily (@emily19980210).</description>
    <link>https://forem.com/emily19980210</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3697303%2Fa264ecdf-bed0-4c65-a1bb-0a0fb2a7a370.png</url>
      <title>Forem: Emily</title>
      <link>https://forem.com/emily19980210</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/emily19980210"/>
    <language>en</language>
    <item>
      <title>Handling Real-Time HK Stock Quotes Without Timeouts: A WebSocket Approach</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Mon, 18 May 2026 21:30:34 +0000</pubDate>
      <link>https://forem.com/emily19980210/handling-real-time-hk-stock-quotes-without-timeouts-a-websocket-approach-7h1</link>
      <guid>https://forem.com/emily19980210/handling-real-time-hk-stock-quotes-without-timeouts-a-websocket-approach-7h1</guid>
      <description>&lt;p&gt;If you’re building any kind of HK stock market tool, you’ve probably hit the wall where your HTTP requests start timing out—especially during the opening rush. In this post, I’ll walk through the exact steps I took to stabilize a brokerage advisory dashboard, moving from fragile polling to a robust WebSocket pipeline.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Understanding the Problem
&lt;/h4&gt;

&lt;p&gt;Timeout errors usually stem from two places: the data provider’s gateway being overloaded (leading to actual network timeouts), and your local processing being too slow (causing back-pressure that starves the socket). When I profiled my own app, I realized that synchronous database writes inside the callback were delaying the event loop just enough to trigger downstream timeouts.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Stop Polling, Start Streaming
&lt;/h4&gt;

&lt;p&gt;The first architectural change is to replace periodic HTTP pulls with a persistent WebSocket connection. Once established, the server pushes each tick in real time. For HK stocks, I rely on AllTick’s WebSocket feed—it accepts a subscription list and delivers a continuous stream, removing the need for constant reconnections.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Code Example: WebSocket Subscription in Python
&lt;/h4&gt;

&lt;p&gt;Here’s a minimal working example that subscribes to Tencent and Alibaba HK shares:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Received tick data; in production, push to a queue or DB
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;subscribe_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;action&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;subscribe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;symbols&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;00700.HK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;09988.HK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# Symbols to subscribe to
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subscribe_data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;ws&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WebSocketApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wss://api.alltick.co/ws/stock&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;on_message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;on_message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;on_open&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;on_open&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep the callback light; just parse and forward.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Batch Subscriptions and Throttle Requests
&lt;/h4&gt;

&lt;p&gt;When subscribing to many instruments at once, split the list into chunks of 10–20 and insert a 50–100 ms pause between chunks. This prevents the initial burst from overwhelming the server’s TCP buffer and avoids throttling.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Implementing Reconnection with Exponential Backoff
&lt;/h4&gt;

&lt;p&gt;Even WebSocket connections drop. I set up a heartbeat (ping every 30s, reconnect after two missed pongs). Reconnection attempts follow an exponential backoff: 1s, 2s, 4s, … max 30s. If only a single symbol fails, I re-subscribe just that one to avoid disturbing the rest.&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Offload Processing with Async and Queues
&lt;/h4&gt;

&lt;p&gt;Move any heavy work—indicator computation, database writes—out of the &lt;code&gt;on_message&lt;/code&gt; thread. I use a &lt;code&gt;queue.Queue&lt;/code&gt; and a consumer thread that flushes data in batches. Bulk inserts (every 100 ticks or 200ms) keep the database happy and eliminate write-induced timeouts.&lt;/p&gt;

&lt;h4&gt;
  
  
  7. Final Tips
&lt;/h4&gt;

&lt;p&gt;Since moving to this WebSocket + queue architecture, the advisory dashboard I maintain hasn’t experienced a single client-visible timeout during trading hours. Start by swapping your transport, then optimize your processing, and your HK stock data pipeline will become orders of magnitude more reliable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpz6hq9qp8t86t5i0cl4k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpz6hq9qp8t86t5i0cl4k.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>javascript</category>
      <category>performance</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Dynamic Forex Pair Subscription in Python: Stop Spamming Your WebSocket Data Feed</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Fri, 15 May 2026 05:21:22 +0000</pubDate>
      <link>https://forem.com/emily19980210/dynamic-forex-pair-subscription-in-python-stop-spamming-your-websocket-data-feed-62a</link>
      <guid>https://forem.com/emily19980210/dynamic-forex-pair-subscription-in-python-stop-spamming-your-websocket-data-feed-62a</guid>
      <description>&lt;p&gt;&lt;strong&gt;Have you ever had your live trading bot kicked off the data server just when the market started moving?&lt;/strong&gt; I certainly have. The culprit wasn't my trading strategy, but how I was shouting &lt;code&gt;subscribe&lt;/code&gt; and &lt;code&gt;unsubscribe&lt;/code&gt; commands at my WebSocket connection. Let me share how I built a polite, stateful client that keeps the data flowing cleanly.&lt;/p&gt;

&lt;p&gt;When you're developing a high-frequency forex bot as a solo dev, you quickly realize that a real-time feed isn't a static resource. Your strategy constantly shifts focus, and your code must tell the server to add new currency pairs and drop old ones &lt;em&gt;without reconnecting&lt;/em&gt;. If you get this wrong, you'll either flood yourself with useless ticks or get rate-limited into oblivion. Let's fix that.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Stateless Requests to a Stateful Connection
&lt;/h2&gt;

&lt;p&gt;We often treat a WebSocket like a REST endpoint, firing off messages whenever we feel like it. Imagine a breakout strategy that monitors &lt;code&gt;EURUSD&lt;/code&gt;. The moment volatility spikes, it wants to also watch &lt;code&gt;GBPUSD&lt;/code&gt; and &lt;code&gt;USDJPY&lt;/code&gt;. A naive implementation does this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Don't do this at home!
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;volatility_spikes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;action&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;subscribe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;symbols&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GBPUSD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}))&lt;/span&gt;
    &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;action&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;subscribe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;symbols&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;USDJPY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that condition oscillates during a choppy market, you'll hammer the server with rapid, repeated subscription attempts. The platform's firewall will likely classify your script as misbehaving and drop the connection. Now you're disconnected during the exact volatility you wanted to trade.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: A Local Subscription Mirror
&lt;/h2&gt;

&lt;p&gt;The trick is to keep a client-side record of exactly what's currently active. Let this local object be the gatekeeper. Any subscription request gets checked against it; any cancellation is only sent if the pair is truly active.&lt;/p&gt;

&lt;p&gt;I use this pattern with the AllTick real-time API, but it works with any provider that supports dynamic subscription messages. Here’s a battle-tested code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="c1"&gt;# Message handler for incoming ticks
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tick:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ws&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WebSocketApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wss://api.alltick.co/realtime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;on_message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;on_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Our local state mirror
&lt;/span&gt;&lt;span class="n"&gt;subscribed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;safe_subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;symbols&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Filter out already active symbols
&lt;/span&gt;    &lt;span class="n"&gt;new_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;symbols&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subscribed&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;new_list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;action&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;subscribe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;symbols&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;new_list&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;new_list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;subscribed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;safe_unsubscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;symbols&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Filter out symbols we aren't watching
&lt;/span&gt;    &lt;span class="n"&gt;active_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;symbols&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subscribed&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;active_list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;action&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unsubscribe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;symbols&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;active_list&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;active_list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;subscribed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;safe_subscribe&lt;/code&gt; and &lt;code&gt;safe_unsubscribe&lt;/code&gt;, your strategy can be as noisy as it wants. The gateway absorbs the duplicates and only sends clean, minimal diffs to the server. No more disconnection panic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pro Tips: Batching and Data Handling
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Batch your commands&lt;/strong&gt;: If you need to add five pairs and remove three, compute the entire diff and send a single &lt;code&gt;subscribe&lt;/code&gt; and a single &lt;code&gt;unsubscribe&lt;/code&gt; message. One round trip, not eight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache the latest price&lt;/strong&gt;: Don't process ticks directly in the &lt;code&gt;on_message&lt;/code&gt; callback. Update a global &lt;code&gt;latest_price&lt;/code&gt; dictionary and have your strategy loop read it asynchronously.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use a separate thread for I/O&lt;/strong&gt;: Let a writer thread accumulate ticks and flush them to your database every 500ms. This prevents the GIL or I/O waits from slowing down your message parsing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Managing WebSocket subscriptions feels like a tiny plumbing task, but doing it right is what separates a weekend prototype from a robust 24/7 trading system. How do you handle dynamic subscriptions in your projects? Let me know in the comments!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo94279vkstq1yha2wryk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo94279vkstq1yha2wryk.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>performance</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Stream US stock ticks in real time with Python and WebSocket</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Thu, 14 May 2026 02:13:08 +0000</pubDate>
      <link>https://forem.com/emily19980210/stream-us-stock-ticks-in-real-time-with-python-and-websocket-26gh</link>
      <guid>https://forem.com/emily19980210/stream-us-stock-ticks-in-real-time-with-python-and-websocket-26gh</guid>
      <description>&lt;h2&gt;
  
  
  The problem with polling market data
&lt;/h2&gt;

&lt;p&gt;If you’ve ever tried to fetch live US stock prices using REST APIs, you know the struggle: rate limits kick in when you need data the most, and the time between requests creates blind spots. For tick-by-tick analysis — like detecting volume spikes or order-flow imbalances — polling just doesn’t cut it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-time push with WebSocket
&lt;/h2&gt;

&lt;p&gt;WebSocket lets the server push every trade directly to you, eliminating polling delays and rate limits. I recently built a real-time tick feed for hot US stocks using Python and a WebSocket API. The data provider I used (AllTick) delivers each trade as a JSON object with symbol, price, and volume — super easy to parse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s see the code
&lt;/h2&gt;

&lt;p&gt;Here’s the simplest version to get you started:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Print price and volume for every trade
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;symbol&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; price: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; volume: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;volume&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Subscribe to a few popular tickers
&lt;/span&gt;    &lt;span class="n"&gt;symbols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TSLA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMZN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;symbol&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;symbols&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;action&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;subscribe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;symbol&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;symbol&lt;/span&gt;
        &lt;span class="p"&gt;}))&lt;/span&gt;

&lt;span class="n"&gt;ws&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WebSocketApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wss://apis.alltick.co/ws/stock-tick&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;on_message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;on_message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;on_open&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;on_open&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it, and you’ll see a live stream of every trade for Apple, Tesla, and Amazon. It’s that fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do with the data
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Store it in &lt;strong&gt;Redis&lt;/strong&gt; for ultra-fast access and real-time dashboards.&lt;/li&gt;
&lt;li&gt;Archive to &lt;strong&gt;SQLite&lt;/strong&gt; or &lt;strong&gt;PostgreSQL&lt;/strong&gt; for backtesting.&lt;/li&gt;
&lt;li&gt;Build a &lt;strong&gt;Streamlit&lt;/strong&gt; dashboard to visualize volume leaders in real time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Make it production-ready
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auto-reconnect&lt;/strong&gt;: Handle &lt;code&gt;on_close&lt;/code&gt; and reconnect with backoff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deduplication&lt;/strong&gt;: Use the trade ID to avoid double-counting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Async&lt;/strong&gt;: Use &lt;code&gt;asyncio&lt;/code&gt; or &lt;code&gt;websockets&lt;/code&gt; library for non-blocking I/O.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heartbeat&lt;/strong&gt;: Keep the connection alive with ping/pong.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Streaming real-time stock ticks is easier than most developers think. With a few lines of Python and a reliable WebSocket endpoint, you can turn your local machine into a powerful market monitoring station. I’ve been using this setup daily to feed our quant models, and it hasn’t missed a beat. Give it a try and see what insights you can uncover!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gmhwn4zqm4eja4s6zzx.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gmhwn4zqm4eja4s6zzx.jpeg" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>data</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Handle Weekend Data Gaps in XAUUSD Backtesting Without Losing Your Mind</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Fri, 08 May 2026 07:39:12 +0000</pubDate>
      <link>https://forem.com/emily19980210/how-to-handle-weekend-data-gaps-in-xauusd-backtesting-without-losing-your-mind-4joh</link>
      <guid>https://forem.com/emily19980210/how-to-handle-weekend-data-gaps-in-xauusd-backtesting-without-losing-your-mind-4joh</guid>
      <description>&lt;h4&gt;
  
  
  The bug that wasn’t a bug
&lt;/h4&gt;

&lt;p&gt;Confession time: I spent a whole week debugging a gold strategy that kept showing a mysterious profit spike every Monday at 00:00. The logic was fine. The data seemed fine. Then I realized my realtime feed simply didn’t send any XAUUSD ticks over the weekend, and my backtester was treating 48 hours of no-data as “price stayed flat.” That flat stretch was making the Monday gap look like a tradeable trend, and my metrics were lying to me.&lt;/p&gt;

&lt;p&gt;If you’re building a gold trading system, this is almost certainly affecting your backtests too. Let’s walk through why, and how to code around it.&lt;/p&gt;

&lt;h4&gt;
  
  
  The mechanics of backtest distortion
&lt;/h4&gt;

&lt;p&gt;Most backtesting loops work like this: for each time step, if there’s no new price, keep the old one. Over a weekend, that gives you a long flat line connecting Friday’s closing price to Monday’s opening price. When the new tick finally arrives, the instantaneous jump is fed directly to your indicators.&lt;/p&gt;

&lt;p&gt;This artificially inflates trend-following signals and deflates volatility estimates. The model sees a smooth entry into a gap, but the real market offers only a discontinuous fill. The result? Beautiful backtests that dissolve in live trading.&lt;/p&gt;

&lt;h4&gt;
  
  
  Which fix is worth the effort
&lt;/h4&gt;

&lt;p&gt;Here’s a quick comparison based on what I’ve tried:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Backtest Fidelity&lt;/th&gt;
&lt;th&gt;Implementation Effort&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ignore weekends completely&lt;/td&gt;
&lt;td&gt;Poor&lt;/td&gt;
&lt;td&gt;Trivial&lt;/td&gt;
&lt;td&gt;Not recommended&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fill with Friday’s closing price&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;td&gt;Barely acceptable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Replace with Monday’s opening price&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;td&gt;Average&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mark gap intervals as events&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Recommended&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incorporate external reference data&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Use as needed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I strongly suggest going with explicit gap marking. It involves a bit more code, but it preserves the discontinuity and lets you analyze how the strategy behaves around gaps — essential intel for gold.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sample code: separating weekend ticks from strategy signals
&lt;/h4&gt;

&lt;p&gt;I’ll show you a minimal example using a WebSocket connection to the AllTick API. The key is a date check that routes weekend data away from the strategy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromtimestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;time&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="c1"&gt;# Weekend tick: store for gap analysis only, don't feed to strategy
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;weekday&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Weekend data &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; written to gap buffer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# Save to gap storage
&lt;/span&gt;        &lt;span class="nf"&gt;store_gap_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Regular weekday tick
&lt;/span&gt;        &lt;span class="nf"&gt;process_tick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;symbol&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;ws&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WebSocketApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wss://apis.alltick.co/websocket-api/stock-websocket-interface-api/transaction-quote-subscription&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;on_message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;on_message&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Write a small gap injection routine for your backtester that applies the Friday-close to Monday-open jump before the first tick of the week. Now your simulation matches reality.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tips for honest gold backtests
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Time axis should be partitioned by trading sessions, not calendar days.&lt;/li&gt;
&lt;li&gt;Analyze gap PnL separately — if your edge comes purely from weekend jumps, you don’t have an edge.&lt;/li&gt;
&lt;li&gt;Keep the exact same data processing path in production and research.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fact that a gold API doesn’t push data on weekends is a guarantee of its accuracy. By explicitly modeling those gaps, you turn a hidden pitfall into a well-understood component of your system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzenuhb84x5nsbzq4cusx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzenuhb84x5nsbzq4cusx.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>data</category>
      <category>programming</category>
      <category>testing</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Build a Real‑Time Multi‑Currency Forex Volatility Dashboard with Python and WebSockets</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Thu, 07 May 2026 02:31:28 +0000</pubDate>
      <link>https://forem.com/emily19980210/how-to-build-a-real-time-multi-currency-forex-volatility-dashboard-with-python-and-websockets-o3p</link>
      <guid>https://forem.com/emily19980210/how-to-build-a-real-time-multi-currency-forex-volatility-dashboard-with-python-and-websockets-o3p</guid>
      <description>&lt;p&gt;As a part‑time forex trader and full‑time tinkerer, I wanted a dashboard that could show me, in real time, which currency pairs were suddenly becoming volatile. Standard charting platforms update volatility indicators at the close of each candle — too slow for my style of scalping. So I built my own tick‑by‑tick volatility monitor using Python, WebSockets, and ECharts. In this tutorial, I’ll walk you through the exact steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The Problem with Polling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I initially tried polling a REST API every second: fetch the latest price for a pair, store it in a list, compute standard deviation over the last 60 data points. It was simple, but the volatility curve was always lagging behind the real action. Polling captures only a tiny fraction of the tick stream, producing a heavily aliased signal. To get true micro‑volatility, you need to consume every tick as it happens. That‘s where WebSockets come in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Setting Up the Real‑Time Data Stream&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I chose a provider that offers a WebSocket API for forex ticks. With a single connection, you can subscribe to multiple instruments like EUR/USD, USD/JPY, GBP/USD. The setup is minimal — here’s a boilerplate Python script that prints each incoming tick:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# print the symbol and the latest traded price
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;symbol&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; current price: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ws&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WebSocketApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wss://api.alltick.co/realtime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;on_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note: AllTick is one example of a real‑time WebSocket data service; you can use any similar API.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Computing Real‑Time Volatility with a Sliding Window&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once ticks are flowing, the next step is to turn them into a volatility number. I use a time‑based sliding window of 60 seconds, implemented with a deque. For each new tick, I add it to the window, remove any data older than 60 seconds, and then calculate the sample standard deviation of the remaining prices. This provides a volatility value that updates on every single tick.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;collections&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;statistics&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="c1"&gt;# maintain a sliding window of the last 60 seconds of prices
&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deque&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;window_seconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_tick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="c1"&gt;# clean up expired entries from the front of the window
&lt;/span&gt;    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;window_seconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;popleft&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;prices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;vol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;statistics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stdev&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Real-time volatility: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vol&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key advantage: you‘re not waiting for a candle to close. Volatility starts climbing the millisecond buying pressure intensifies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Building the Dashboard (Without Overloading the Browser)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I moved all computation to a Python backend. The frontend is a static HTML page using ECharts that receives volatility updates via WebSocket or Server‑Sent Events. This keeps the browser lightweight — it only has to render the lines. I also added a simple visual rule: if a pair’s volatility exceeds a threshold, its line turns red, giving an immediate visual signal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Managing Multiple Pairs Concurrently&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To handle many pairs cleanly, my backend maintains a dictionary where each key is a currency pair string, and the value is an object containing that pair‘s tick deque, the latest price, and current volatility. The global WebSocket callback demultiplexes incoming messages by &lt;code&gt;symbol&lt;/code&gt; and routes them to the correct pair’s handler. This pattern scales well and keeps the codebase tidy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wrapping Up&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Building this dashboard changed how I perceive the market. Real‑time tick volatility reveals market rhythm in a way that minute bars can‘t. The code above provides a solid starting point — once you have the pipeline, you can extend it with multi‑timeframe volatility comparisons, alarms, or even integrate the volatility feed into your own trading bot. If you’re into forex algo trading, I highly recommend giving a live tick dashboard a try.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvp4bqmbzmh2whesd3by.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvp4bqmbzmh2whesd3by.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
    </item>
    <item>
      <title>Understanding Trading Instrument APIs: Fetching and Managing Symbols in Python</title>
      <dc:creator>Emily</dc:creator>
      <pubDate>Wed, 07 Jan 2026 01:44:29 +0000</pubDate>
      <link>https://forem.com/emily19980210/understanding-trading-instrument-apis-fetching-and-managing-symbols-in-python-5dbh</link>
      <guid>https://forem.com/emily19980210/understanding-trading-instrument-apis-fetching-and-managing-symbols-in-python-5dbh</guid>
      <description>&lt;p&gt;Building automated trading systems requires more than just real-time market data. Knowing your instruments—the symbols you can actually trade—is equally important. Trading instrument APIs (sometimes called symbol APIs) provide structured information about available instruments, including metadata and contract details. Handling this data efficiently can help prevent invalid orders and mismatched trades.&lt;br&gt;
Fetching Instrument Lists&lt;br&gt;
Most brokers and exchanges expose endpoints that return instruments or symbols. Typical fields include:&lt;br&gt;
Symbol/ticker (e.g., EURUSD, AAPL)&lt;br&gt;
Asset type (forex, stock, crypto, futures)&lt;br&gt;
Exchange or market&lt;br&gt;
Lot size or contract specifications&lt;br&gt;
Here’s a quick Python example using requests and pandas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import requests
import pandas as pd

url = https://api.example.com/instruments
response = requests.get(url).json()

df = pd.DataFrame(response["data"])
print(df.head())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple snippet fetches the instrument list and converts it into a pandas DataFrame, making it easy to filter, sort, or analyze.&lt;br&gt;
Filtering and Searching Instruments&lt;br&gt;
Large exchanges can have thousands of symbols. Filtering by asset type or market can streamline your workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;forex_symbols = df[df["type"] == "forex"]
print(forex_symbols)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also combine multiple filters, such as exchange and asset type, to quickly locate the instruments relevant to your strategy.&lt;br&gt;
Keeping Your Symbol Database Up-to-Date&lt;br&gt;
Instrument lists change frequently—new products are added, and others get delisted. Automating daily updates ensures your system never tries to trade an outdated symbol. Depending on your setup, you can:&lt;br&gt;
Fetch the latest symbols at the start of each session&lt;br&gt;
Maintain a local cache and update periodically&lt;br&gt;
Both approaches have pros and cons, but the key is consistency and automation.&lt;br&gt;
Why It Matters&lt;br&gt;
Incorrect instrument data can cause errors in backtesting and live trading alike. By combining trading instrument APIs with market data APIs, you ensure your system knows both what to trade and where to trade it.&lt;br&gt;
Discussion&lt;br&gt;
How do you manage symbol updates in your trading systems? Do you prefer fetching live every session or maintaining a local cache? Sharing your workflow can help others avoid common pitfalls.&lt;/p&gt;

</description>
      <category>api</category>
      <category>automation</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
