<?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>DEV Community: rocketsquirreldev</title>
    <description>The latest articles on DEV Community by rocketsquirreldev (@rocketsquirreldev).</description>
    <link>https://dev.to/rocketsquirreldev</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%2F3849271%2F5c7a54bb-000b-44cb-ac7c-e19347a618a9.jpg</url>
      <title>DEV Community: rocketsquirreldev</title>
      <link>https://dev.to/rocketsquirreldev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rocketsquirreldev"/>
    <language>en</language>
    <item>
      <title>[CryptoTradingBot] Analyzing 70 Live Trades of My Python Crypto Bot (v8.04 Post-Mortem)</title>
      <dc:creator>rocketsquirreldev</dc:creator>
      <pubDate>Mon, 11 May 2026 13:22:13 +0000</pubDate>
      <link>https://dev.to/rocketsquirreldev/analyzing-70-live-trades-of-my-python-crypto-bot-v804-post-mortem-5acl</link>
      <guid>https://dev.to/rocketsquirreldev/analyzing-70-live-trades-of-my-python-crypto-bot-v804-post-mortem-5acl</guid>
      <description>&lt;p&gt;I’ve been running version 8.04 of my Python-based crypto trading bot live for about a month. Instead of just looking at the final PnL, I built a dashboard to analyze the exact entry/exit logs of all 70 trades. &lt;/p&gt;

&lt;p&gt;Here is what the raw data taught me about the gap between theoretical algorithms and live markets.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Stats: A Tale of Two Months
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Total Trades:&lt;/strong&gt; 70&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Win Rate:&lt;/strong&gt; 48.6% &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;April (35 trades):&lt;/strong&gt; 43% win rate, net negative.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;May (35 trades):&lt;/strong&gt; 54% win rate, net positive.&lt;/li&gt;
&lt;/ul&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%2F9oy2w43q1f55nlidx179.png" 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%2F9oy2w43q1f55nlidx179.png" alt=" " width="800" height="653"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The bot clearly improved in May. In April, my logging showed two fatal flaws: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Sideways Trap:&lt;/strong&gt; The bot entered BTC 4 times in a single day during a chop zone, getting stopped out repeatedly. My 1-hour cooldown logic was simply too short.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simultaneous Liquidations:&lt;/strong&gt; The bot held LONG positions in LINK and ETH simultaneously. When the market dipped, both hit their stop-losses at the exact same minute, doubling my daily drawdown.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Risk/Reward Illusion
&lt;/h3&gt;

&lt;p&gt;This was the most humbling discovery. My algorithm is strictly coded to aim for a &lt;strong&gt;3:1 Risk/Reward ratio&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, the real-world data showed an average win of 0.80 and an average loss of 0.70. My actual R/R ratio was &lt;strong&gt;1.14:1&lt;/strong&gt;. Why?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trailing Stops:&lt;/strong&gt; My &lt;code&gt;EXIT_PROFIT_SECURE&lt;/code&gt; trailing stop logic was too aggressive. It protected my capital by closing trades early during minor pullbacks, but it effectively prevented the bot from ever reaching the 3:1 target. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Asset Breakdown
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;$LINK (9W 9L):&lt;/strong&gt; My most profitable pair. The "Volume Climax Filter" I added in v8.03 worked perfectly here, preventing FOMO entries at the top of pumps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;$ETH (7W 9L):&lt;/strong&gt; The absolute worst performer. The stop-losses were large, and the take-profits were tiny.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Next Steps for v8.05
&lt;/h3&gt;

&lt;p&gt;Data analysis gives you a clear roadmap. My next commits will include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stricter ETH Entry:&lt;/strong&gt; Bumping the ADX threshold limit to 25 specifically for ETH.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Increased Cooldowns:&lt;/strong&gt; Changing the post-loss cooldown for BTC from 1 hour to 2 hours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Daily Circuit Breaker:&lt;/strong&gt; If the total daily loss exceeds a specific threshold, halt all new entries for 24 hours to prevent cascading simultaneous stops.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Algo-trading is 10% writing trading logic and 90% debugging your own assumptions through data. Back to the code!&lt;/p&gt;

</description>
      <category>python</category>
      <category>algotrading</category>
      <category>data</category>
      <category>lessons</category>
    </item>
    <item>
      <title>Visualizing Certificate Expiry in the Browser (x509Lab v1.5.0)</title>
      <dc:creator>rocketsquirreldev</dc:creator>
      <pubDate>Fri, 08 May 2026 12:38:29 +0000</pubDate>
      <link>https://dev.to/rocketsquirreldev/visualizing-certificate-expiry-in-the-browser-x509lab-v150-445m</link>
      <guid>https://dev.to/rocketsquirreldev/visualizing-certificate-expiry-in-the-browser-x509lab-v150-445m</guid>
      <description>&lt;p&gt;Hey everyone, I'm RocketSquirrel. I build &lt;strong&gt;x509Lab&lt;/strong&gt;, a purely client-side web tool for visualizing and generating X.509 certificate chains. &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%2F0dwfxxvfyvwjh8ol3o18.png" 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%2F0dwfxxvfyvwjh8ol3o18.png" alt=" " width="485" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you work in DevOps, Backend, or IT Infra, you know the quiet terror of a production certificate expiring because someone forgot to track it. &lt;/p&gt;

&lt;p&gt;When visualizing complex PKI trees (Root -&amp;gt; Multiple Intermediates -&amp;gt; Dozens of Leafs) in x509Lab, clicking into every single node to check its expiry date was becoming a chore. So for the v1.5.0 update, I built a visual warning system directly into the canvas nodes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visual Expiry Badges
&lt;/h3&gt;

&lt;p&gt;Now, the moment you upload or generate a certificate, the node card displays a color-coded badge based on its remaining lifespan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🟢 &lt;strong&gt;VALID (&amp;gt; 90 days):&lt;/strong&gt; All good.&lt;/li&gt;
&lt;li&gt;🟡 &lt;strong&gt;D-XX (31~90 days):&lt;/strong&gt; Warning zone.&lt;/li&gt;
&lt;li&gt;🟠 &lt;strong&gt;D-XX (&amp;lt; 30 days):&lt;/strong&gt; Danger zone. A small orange dot also appears on the node header.&lt;/li&gt;
&lt;li&gt;🔴 &lt;strong&gt;D-XX (&amp;lt;= 7 days) or EXPIRED:&lt;/strong&gt; Critical. A bright red dot appears on the header.&lt;/li&gt;
&lt;/ul&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%2Fas5zccevwyvpdulbhafs.png" 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%2Fas5zccevwyvpdulbhafs.png" alt=" " width="800" height="666"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This makes it incredibly easy to zoom out on your 5000x5000 canvas and instantly spot which certificates in your chain need to be replaced. &lt;/p&gt;

&lt;h3&gt;
  
  
  Bug Fix: Save/Load State Loss
&lt;/h3&gt;

&lt;p&gt;I also fixed a frustrating state management bug. Previously, if you generated certificates inside the app, saved your workspace to a &lt;code&gt;.json&lt;/code&gt; file, and loaded it later, the certificates would disappear (only the empty nodes remained). The serialization logic was missing the dynamically generated PEM strings. This is now fully patched—you can safely save your test PKI environments and restore them anytime.&lt;/p&gt;

&lt;p&gt;As always, everything runs locally via the Web Crypto API. No backend, no data collection. &lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Try it here:&lt;/strong&gt; &lt;a href="https://x509lab.vercel.app" rel="noopener noreferrer"&gt;https://x509lab.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Instagram Link:&lt;/strong&gt; &lt;a href="https://www.instagram.com/reel/DYE_C6KqL3Z/?utm_source=ig_web_copy_link&amp;amp;igsh=MzRlODBiNWFlZA==" rel="noopener noreferrer"&gt;https://www.instagram.com/reel/DYE_C6KqL3Z/?utm_source=ig_web_copy_link&amp;amp;igsh=MzRlODBiNWFlZA==&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next up on the roadmap: One-click templates for TLS Server, Code Signing, and S/MIME chains!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>openssl</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>[DeskFlow]Added 11 New Devices to DeskFlow (Including Windows Laptops &amp; UPS!)</title>
      <dc:creator>rocketsquirreldev</dc:creator>
      <pubDate>Sun, 03 May 2026 12:27:39 +0000</pubDate>
      <link>https://dev.to/rocketsquirreldev/deskflowadded-11-new-devices-to-deskflow-including-windows-laptops-ups-10ge</link>
      <guid>https://dev.to/rocketsquirreldev/deskflowadded-11-new-devices-to-deskflow-including-windows-laptops-ups-10ge</guid>
      <description>&lt;p&gt;Hey everyone, RocketSquirrel here. I am a solo developer working on DeskFlow, a web-based visual planner for desk setups and cable routing.&lt;/p&gt;

&lt;p&gt;I usually code late at night after putting my kid to bed. Recently, I realized my equipment library was heavily biased towards Macbooks and just a few generic monitors. To make the tool actually useful for planning real-world setups, I just pushed a quick database update adding 11 highly requested items.&lt;/p&gt;

&lt;p&gt;Here is what just dropped into the library:&lt;/p&gt;

&lt;p&gt;Mice&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logitech MX Master 3S&lt;/li&gt;
&lt;li&gt;Apple Magic Mouse&lt;/li&gt;
&lt;li&gt;Razer DeathAdder V3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Speakers&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sonos Era 100&lt;/li&gt;
&lt;li&gt;Audioengine A2+&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Monitors&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LG C3 OLED 42 inch (for the massive gaming/productivity hybrid setups)&lt;/li&gt;
&lt;li&gt;ASUS ProArt PA279CRV 27 inch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Laptops&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LG Gram 16 (2024)&lt;/li&gt;
&lt;li&gt;ASUS Zenbook 14 OLED
(Finally, some Windows love!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Power &amp;amp; Stability&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Anker Power Strip (USB)&lt;/li&gt;
&lt;li&gt;APC UPS 700
(Because knowing where to hide your power strip is 90% of cable management)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is a simple content update, but having mice and power strips on the canvas really makes the setup visualization feel complete.&lt;/p&gt;

&lt;p&gt;You can check out the new items and try building your setup here: &lt;a href="https://deskflow.vercel.app" rel="noopener noreferrer"&gt;https://deskflow.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your daily driver equipment is missing from the list, drop a comment with the model name! I will prioritize adding them in the next batch.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>sideprojects</category>
      <category>desksetup</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>Making a Canvas-Based Web App Mobile Friendly (DeskFlow v1.1.8)</title>
      <dc:creator>rocketsquirreldev</dc:creator>
      <pubDate>Fri, 01 May 2026 12:58:28 +0000</pubDate>
      <link>https://dev.to/rocketsquirreldev/making-a-canvas-based-web-app-mobile-friendly-deskflow-v118-2dnk</link>
      <guid>https://dev.to/rocketsquirreldev/making-a-canvas-based-web-app-mobile-friendly-deskflow-v118-2dnk</guid>
      <description>&lt;p&gt;I'm building &lt;strong&gt;DeskFlow&lt;/strong&gt;, a visual desk setup and cable planner. Until now, it was strictly a desktop application. &lt;/p&gt;

&lt;p&gt;If you opened it on a mobile browser, it was a disaster. The left equipment panel and the right shopping list panel squeezed the central canvas into oblivion. You couldn't tap, drag, or plan anything.&lt;/p&gt;

&lt;p&gt;This weekend, I finally tackled mobile responsiveness in the v1.1.8 update. Here is a breakdown of the UX changes and the technical hurdles I ran into along the way.&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%2Frx9naxyoypiddop9xrgk.png" 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%2Frx9naxyoypiddop9xrgk.png" alt=" " width="455" height="144"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Mobile Redesign
&lt;/h3&gt;

&lt;p&gt;Since you can't cram a 3-panel layout into a 375px wide screen, I set a strict breakpoint at &lt;code&gt;650px&lt;/code&gt; and completely decoupled the mobile layout.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Canvas owns the screen:&lt;/strong&gt; The canvas now takes up 100% of the viewport.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Equipment Library:&lt;/strong&gt; Moved to a slide-out drawer accessible via a top-left hamburger menu (☰). Tapping an item drops it instantly onto the center of the canvas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shopping List:&lt;/strong&gt; Moved to a bottom sheet accessible via a top-right cart icon. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Touch Gestures:&lt;/strong&gt; Added 1-finger drag for canvas panning, and 2-finger pinch for zooming. Nodes can be tapped to select and dragged to move.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Note: The desktop experience remains exactly the same with its original 3-panel layout).&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Challenges &amp;amp; Bug Fixes
&lt;/h3&gt;

&lt;p&gt;Making a canvas work on mobile is never just about CSS. The touch events fought me every step of the way.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. The Pinch-to-Zoom Jumping Bug
&lt;/h4&gt;

&lt;p&gt;When I first implemented the 2-finger pinch-to-zoom, the canvas would violently jump off the screen. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The cause:&lt;/strong&gt; When two fingers are moving on the screen, the browser fires &lt;code&gt;touchmove&lt;/code&gt; events for &lt;em&gt;both&lt;/em&gt; touches. My panning logic was trying to calculate the delta and move the canvas based on these touches simultaneously while the zoom logic was also trying to scale the view. They collided.&lt;br&gt;
&lt;strong&gt;The fix:&lt;/strong&gt; I had to explicitly disable the panning calculation the moment &lt;code&gt;e.touches.length &amp;gt; 1&lt;/code&gt; is detected. Pan logic only runs for single touches.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. The Touch-Absorption Bug
&lt;/h4&gt;

&lt;p&gt;On mobile, users couldn't tap or drag the equipment nodes at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The cause:&lt;/strong&gt; In desktop mode, when "Pan Mode" is active, I place a transparent overlay layer on top of the canvas to catch mouse drags so they don't accidentally select elements underneath. On mobile, this layer was constantly absorbing all &lt;code&gt;touchstart&lt;/code&gt; events, making the nodes underneath completely unresponsive.&lt;br&gt;
&lt;strong&gt;The fix:&lt;/strong&gt; I disabled this specific interaction layer on mobile devices, allowing the touch events to safely reach the nodes for tapping and dragging, while handling canvas panning directly on the background container.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try it out
&lt;/h3&gt;

&lt;p&gt;You can check out the mobile experience right from your phone without any installations. It's super handy if you are at a store and need to quickly check if a specific USB-C hub has the right ports for your layout.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Live App:&lt;/strong&gt; &lt;a href="https://deskflow.vercel.app" rel="noopener noreferrer"&gt;https://deskflow.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've built interactive canvas apps for mobile, I'd love to hear how you handled complex touch events!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ux</category>
      <category>frontend</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>[x509Lab]Generating &amp; Parsing CSRs in the Browser (No OpenSSL required) - x509Lab v1.4.0</title>
      <dc:creator>rocketsquirreldev</dc:creator>
      <pubDate>Wed, 29 Apr 2026 13:39:41 +0000</pubDate>
      <link>https://dev.to/rocketsquirreldev/x509labgenerating-parsing-csrs-in-the-browser-no-openssl-required-x509lab-v140-46h5</link>
      <guid>https://dev.to/rocketsquirreldev/x509labgenerating-parsing-csrs-in-the-browser-no-openssl-required-x509lab-v140-46h5</guid>
      <description>&lt;p&gt;Hi everyone! I am an embedded developer by day, and an indie hacker by night. I'm building &lt;strong&gt;x509Lab&lt;/strong&gt;, a purely client-side visual tool for managing certificate chains. &lt;/p&gt;

&lt;p&gt;Today I’m releasing a pretty heavy feature update: &lt;strong&gt;CSR (Certificate Signing Request) Generation &amp;amp; Parsing.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Pain Point
&lt;/h3&gt;

&lt;p&gt;Usually, creating a CSR involves opening a terminal and typing something like this:&lt;br&gt;
&lt;code&gt;openssl req -new -key private.key -out request.csr&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then you have to remember which flags to pass for Subject Alternative Names (SANs) or specific Key Usages. To check if you did it right, you have to run &lt;code&gt;openssl req -text -noout -in request.csr&lt;/code&gt;. It's tedious.&lt;/p&gt;

&lt;p&gt;x509Lab now solves this visually in the browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Feature 1: Generate CSR
&lt;/h3&gt;

&lt;p&gt;Click the 📄 &lt;strong&gt;CSR&lt;/strong&gt; button in the top toolbar to open the new modal.&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%2F8k0jlk8r51fb70sx3s9r.png" 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%2F8k0jlk8r51fb70sx3s9r.png" alt=" " width="674" height="979"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve added comprehensive Subject fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CN&lt;/code&gt; (Common Name)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;O&lt;/code&gt; (Organization)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;OU&lt;/code&gt; (Org Unit)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;C&lt;/code&gt;, &lt;code&gt;ST&lt;/code&gt;, &lt;code&gt;L&lt;/code&gt; (Location data)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SAN&lt;/code&gt; (DNS / IP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the real highlight is the &lt;strong&gt;Key Usage &amp;amp; Extended Key Usage (EKU)&lt;/strong&gt; checkboxes. &lt;/p&gt;

&lt;h4&gt;
  
  
  Not just for web servers (Great for IoT/ECU)
&lt;/h4&gt;

&lt;p&gt;Since my day job involves automotive software, I wanted to make sure this tool could handle IoT and vehicle ECU PKI scenarios. &lt;/p&gt;

&lt;p&gt;By setting specific fields like &lt;code&gt;OU = ChassisControl&lt;/code&gt; and selecting &lt;code&gt;clientAuth&lt;/code&gt; and &lt;code&gt;codeSigning&lt;/code&gt; in the EKU section, you can generate CSRs perfectly suited for vehicle OTA updates or V2X infrastructure testing. &lt;/p&gt;

&lt;h3&gt;
  
  
  Feature 2: Parse CSR
&lt;/h3&gt;

&lt;p&gt;Generating is only half the battle. If you switch to the &lt;strong&gt;Parse CSR&lt;/strong&gt; tab, you can paste any existing &lt;code&gt;.csr&lt;/code&gt; PEM string or upload a file. &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%2F62xzldspwtxx8ruijwpy.png" 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%2F62xzldspwtxx8ruijwpy.png" alt=" " width="670" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The app instantly decodes it and displays:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The full Subject DN&lt;/li&gt;
&lt;li&gt;The Signature Algorithm&lt;/li&gt;
&lt;li&gt;SAN list&lt;/li&gt;
&lt;li&gt;Key Usage / EKU extensions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It completely replaces the need to run the &lt;code&gt;-text&lt;/code&gt; OpenSSL command just to peek inside a CSR file.&lt;/p&gt;

&lt;h3&gt;
  
  
  100% Secure &amp;amp; Client-Side
&lt;/h3&gt;

&lt;p&gt;Just like the rest of x509Lab, everything runs on the &lt;strong&gt;Web Crypto API&lt;/strong&gt;. No data, private keys, or CSRs are ever transmitted to a backend server. &lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Try it live here:&lt;/strong&gt; &lt;a href="https://x509lab.vercel.app" rel="noopener noreferrer"&gt;https://x509lab.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me know if you run into any bugs or have feature requests!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>openssl</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>[DeskFlow]Solving the 'Lost in Canvas' UX problem in my Flutter Web app (DeskFlow v1.1.7)</title>
      <dc:creator>rocketsquirreldev</dc:creator>
      <pubDate>Thu, 23 Apr 2026 13:19:10 +0000</pubDate>
      <link>https://dev.to/rocketsquirreldev/deskflowsolving-the-lost-in-canvas-ux-problem-in-my-flutter-web-app-deskflow-v117-1ac0</link>
      <guid>https://dev.to/rocketsquirreldev/deskflowsolving-the-lost-in-canvas-ux-problem-in-my-flutter-web-app-deskflow-v117-1ac0</guid>
      <description>&lt;p&gt;I am building &lt;strong&gt;DeskFlow&lt;/strong&gt;, a visual planner for desk setups and cable management running on Flutter Web. &lt;/p&gt;

&lt;p&gt;In my last update, I expanded the canvas size to a massive 5000x5000 pixels so users could comfortably plan huge multi-monitor setups. But fixing one UX problem created another: users (including myself) started getting lost in the void. If you panned too far away from your hardware nodes, finding them again involved a lot of frustrating scrolling.&lt;/p&gt;

&lt;p&gt;To fix this, I released v1.1.7 today, focusing entirely on spatial navigation.&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%2Fth83u6msm47q7eyjshg1.png" 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%2Fth83u6msm47q7eyjshg1.png" alt=" " width="449" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Canvas Minimap
&lt;/h3&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%2Fuigczoc29g66as5tqjul.png" 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%2Fuigczoc29g66as5tqjul.png" alt=" " width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I added a minimap overlay in the bottom-left corner. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It represents all your active hardware nodes as cyan blocks.&lt;/li&gt;
&lt;li&gt;The white rectangle represents your current viewport.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Click-to-jump:&lt;/strong&gt; You can click anywhere on the minimap to instantly pan the canvas to that exact location. No more aimless scrolling.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Fit to Content (The 'F' Key)
&lt;/h3&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%2Ffwb11d9uzh1n2jdfx4jx.png" 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%2Ffwb11d9uzh1n2jdfx4jx.png" alt=" " width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the feature I end up using the most. When you are zoomed in routing a specific USB-C cable and want to see the whole picture again, manually zooming out is tedious.&lt;/p&gt;

&lt;p&gt;Now, you can just press the &lt;strong&gt;&lt;code&gt;F&lt;/code&gt; key&lt;/strong&gt; (or click the bottom-right bounding box icon). The app calculates the bounding box of all active nodes and automatically adjusts the zoom and pan to fit everything perfectly in the center of your screen. &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%2Fmggnq2auyd87v2extx1t.png" 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%2Fmggnq2auyd87v2extx1t.png" alt=" " width="683" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Workflow
&lt;/h3&gt;

&lt;p&gt;The UX loop is now incredibly fluid:&lt;br&gt;
Hit &lt;code&gt;F&lt;/code&gt; to see the entire setup -&amp;gt; Click the Minimap to dive into a specific hub -&amp;gt; Route the cables -&amp;gt; Hit &lt;code&gt;F&lt;/code&gt; to zoom back out. &lt;/p&gt;

&lt;p&gt;If you are building a canvas-based app in Flutter or React, I highly recommend implementing a Fit-to-Content function early on. It saves so much user frustration.&lt;/p&gt;

&lt;p&gt;Try out the new navigation directly in your browser:&lt;br&gt;
🔗 &lt;strong&gt;&lt;a href="https://deskflow-gold.vercel.app/" rel="noopener noreferrer"&gt;https://deskflow-gold.vercel.app/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let me know what you think of the UX flow!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>flutter</category>
      <category>ux</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>[x509Lab]Sign new Leaf certificates with your existing Root CA directly in the browser (x509Lab v1.3.0)</title>
      <dc:creator>rocketsquirreldev</dc:creator>
      <pubDate>Tue, 21 Apr 2026 13:36:46 +0000</pubDate>
      <link>https://dev.to/rocketsquirreldev/x509labsign-new-leaf-certificates-with-your-existing-root-ca-directly-in-the-browser-x509lab-4g45</link>
      <guid>https://dev.to/rocketsquirreldev/x509labsign-new-leaf-certificates-with-your-existing-root-ca-directly-in-the-browser-x509lab-4g45</guid>
      <description>&lt;p&gt;Hey everyone. I'm building &lt;strong&gt;x509Lab&lt;/strong&gt;, a purely client-side web tool for visualizing and generating certificate chains. I usually work on this late at night after putting my kid to sleep, so I try to focus on fixing real annoyances I face during my day job.&lt;/p&gt;

&lt;p&gt;A huge pain point in the previous version was that whenever you hit the &lt;code&gt;Generate&lt;/code&gt; button, the app would blindly generate brand new keys and certificates for the entire tree. &lt;/p&gt;

&lt;p&gt;But what if you already have a Root CA and an Intermediate CA, and you just want to generate a new Leaf certificate signed by that existing Intermediate CA? &lt;/p&gt;

&lt;p&gt;With the new &lt;strong&gt;v1.3.0 update&lt;/strong&gt;, you can finally do exactly that.&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%2Fwh82lnwj42n2t2wh6ke9.png" 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%2Fwh82lnwj42n2t2wh6ke9.png" alt=" " width="480" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How to use the selective signing feature
&lt;/h3&gt;

&lt;p&gt;The workflow is designed to be as frictionless as possible.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;First&lt;/strong&gt;, build your tree on the canvas (e.g., &lt;code&gt;Root -&amp;gt; Intermediate -&amp;gt; Leaf&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Second&lt;/strong&gt;, upload your existing certificate PEM files to the Root and Intermediate nodes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Third&lt;/strong&gt;, you will notice a new &lt;code&gt;[+ Add Key]&lt;/code&gt; button appears on nodes that have a certificate loaded. Click it to provide the matching Private Key.&lt;/li&gt;
&lt;/ol&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%2F4ho7ezuo3ik7dykay1qu.png" 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%2F4ho7ezuo3ik7dykay1qu.png" alt=" " width="800" height="781"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Finally&lt;/strong&gt;, hit &lt;code&gt;Generate Certs&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The app will now recognize that the upper nodes already have their cryptographic material. It will skip generating them and only generate the new Leaf certificate, automatically signing it using the Intermediate CA's private key you provided.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visual status in the generation modal
&lt;/h3&gt;

&lt;p&gt;To prevent confusion when dealing with larger chains, the Generate modal now uses a simple color-coded status 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%2F5lt40roofwfhcv60mubq.png" 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%2F5lt40roofwfhcv60mubq.png" alt=" " width="521" height="846"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🟢 &lt;strong&gt;Green:&lt;/strong&gt; The node has both a certificate and a private key. It will be skipped during generation but used for signing downstream.&lt;/li&gt;
&lt;li&gt;🟡 &lt;strong&gt;Yellow:&lt;/strong&gt; The node has a certificate but is missing a private key. You need to add it if you want it to sign the nodes below it.&lt;/li&gt;
&lt;li&gt;⚪ &lt;strong&gt;Default/Gray:&lt;/strong&gt; No certificate exists. The app will generate a fresh one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can even add the missing private keys directly from inside the modal if you see a yellow warning, saving you a few clicks.&lt;/p&gt;

&lt;h3&gt;
  
  
  A quick note on security
&lt;/h3&gt;

&lt;p&gt;I know that pasting a Private Key into a web browser sounds like a terrible idea for any security or infra engineer. &lt;/p&gt;

&lt;p&gt;Please rest assured that x509Lab is a &lt;strong&gt;100% client-side application&lt;/strong&gt;. There is no backend server. Your private keys never leave your machine; they are only stored temporarily in your browser's memory to perform the Web Crypto API signing operations and are completely wiped the moment you close or refresh the tab.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;You can try it out for free here:&lt;/strong&gt; &lt;a href="https://x509lab.vercel.app" rel="noopener noreferrer"&gt;https://x509lab.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If this helps you debug your mTLS setups or saves you from digging through OpenSSL man pages, let me know. Feedback and feature requests are always welcome in the comments.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>tools</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>[DeskFlow]Scaling Up: Making My React Canvas App 6x Larger (v1.1.6)</title>
      <dc:creator>rocketsquirreldev</dc:creator>
      <pubDate>Sat, 18 Apr 2026 14:02:24 +0000</pubDate>
      <link>https://dev.to/rocketsquirreldev/deskflowscaling-up-making-my-react-canvas-app-6x-larger-v116-268a</link>
      <guid>https://dev.to/rocketsquirreldev/deskflowscaling-up-making-my-react-canvas-app-6x-larger-v116-268a</guid>
      <description>&lt;p&gt;I am building &lt;a href="https://deskflow-gold.vercel.app/" rel="noopener noreferrer"&gt;DeskFlow&lt;/a&gt;, a browser-based visual planner for desk setups and cable management. &lt;/p&gt;

&lt;p&gt;As the tool gained traction, users (and myself) hit a frustrating wall: the fixed 2000x2000px canvas was simply too small. If you were planning a dual-monitor setup with a laptop, a KVM switch, a NAS, and an audio interface, the nodes and cables quickly turned into a chaotic, overlapping mess.&lt;/p&gt;

&lt;p&gt;In version 1.1.6, I focused entirely on expanding the workspace and improving spatial navigation. Here is what changed.&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%2Fd2law0rrrynhy9uj3bmg.png" 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%2Fd2law0rrrynhy9uj3bmg.png" alt=" " width="452" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. A 5000x5000px Workspace
&lt;/h3&gt;

&lt;p&gt;I expanded the canvas area by 6.25x. Now, users can space out their hardware nodes comfortably. You can zoom out to view the entire home office layout, or zoom in to precisely route cables between specific ports.&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%2Fqrp7puuuir4xokblv5bx.png" 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%2Fqrp7puuuir4xokblv5bx.png" alt=" " width="800" height="722"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Bug fix note:&lt;/em&gt; When I expanded the container, users couldn't drag nodes past the top-left quadrant. I realized my clamp logic for node dragging still had the &lt;code&gt;2000&lt;/code&gt; boundaries hardcoded in three different utility functions. Always use constants, folks!&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Graph Paper Grid
&lt;/h3&gt;

&lt;p&gt;The old dot-grid background was functional but boring. I replaced it with a classic engineering "graph paper" style using a combination of linear gradients.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minor grid: 40px intervals (thin, subtle lines).&lt;/li&gt;
&lt;li&gt;Major grid: 200px intervals (slightly thicker lines every 5 blocks).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes it significantly easier to judge spatial relationships ("This 4-block area is my monitor arm, this area is under the desk"). The translucent white lines on the dark theme contrast perfectly with the cyan/pink cable paths.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Dedicated Pan Mode (Like Figma)
&lt;/h3&gt;

&lt;p&gt;With a massive canvas, navigation is critical. Previously, you had to hold &lt;code&gt;Space&lt;/code&gt; + Drag or use the middle mouse button to pan. &lt;/p&gt;

&lt;p&gt;I introduced a dedicated Pan Mode toggle (bottom-left hand icon, or press &lt;code&gt;H&lt;/code&gt;). When active, simple left-click dragging pans the entire viewport. If you use tools like Figma or Miro, this interaction model feels instantly familiar.&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%2F0j6ljyfclbghubai8lie.png" 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%2F0j6ljyfclbghubai8lie.png" alt=" " width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. UI Boundaries
&lt;/h3&gt;

&lt;p&gt;I added subtle, translucent cyan borders between the left hardware panel, the main canvas, and the right shopping list panel. It’s a tiny CSS tweak (&lt;code&gt;border-right: 1px solid rgba(0, 255, 255, 0.1)&lt;/code&gt;), but it dramatically sharpens the separation of the workspace.&lt;/p&gt;

&lt;p&gt;If you are planning to overhaul your desk setup or just want to play around with some visual hardware routing, try it out directly in your browser.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Try it here:&lt;/strong&gt; &lt;a href="https://deskflow-gold.vercel.app/" rel="noopener noreferrer"&gt;https://deskflow-gold.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next on the roadmap: custom node labels and a minimap for this giant new canvas!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>ui</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>[CryptoTradingBot] My Crypto Algo-Bot Hit a 41% Win Rate, But Still Lost Money. Here is Why.</title>
      <dc:creator>rocketsquirreldev</dc:creator>
      <pubDate>Thu, 16 Apr 2026 14:16:45 +0000</pubDate>
      <link>https://dev.to/rocketsquirreldev/cryptotradingbot-my-crypto-algo-bot-hit-a-41-win-rate-but-still-lost-money-here-is-why-4e4o</link>
      <guid>https://dev.to/rocketsquirreldev/cryptotradingbot-my-crypto-algo-bot-hit-a-41-win-rate-but-still-lost-money-here-is-why-4e4o</guid>
      <description>&lt;p&gt;Over the past 11 days, I deployed version 8.03 of my Python-based crypto auto-trading bot on Binance Futures. I had recently built a real-time web dashboard for it, so monitoring the trades was easier than ever. &lt;/p&gt;

&lt;p&gt;The good news? My win rate jumped from a miserable 26.7% to &lt;strong&gt;41.2%&lt;/strong&gt;.&lt;br&gt;
The bad news? I still ended up with a net loss of &lt;strong&gt;-2.42 USDT&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In algorithmic trading, numbers don't lie. I dug into the logs of the 34 executed trades to find out exactly where my strategy was leaking money. Here is the post-mortem data analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Overall Performance (April 5 - April 16)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Total Trades:&lt;/strong&gt; 34&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wins:&lt;/strong&gt; 14 / &lt;strong&gt;Losses:&lt;/strong&gt; 20&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Win Rate:&lt;/strong&gt; 41.2%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gross Profit:&lt;/strong&gt; +11.07 USDT / &lt;strong&gt;Gross Loss:&lt;/strong&gt; -13.49 USDT&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Average Win:&lt;/strong&gt; +0.79 / &lt;strong&gt;Average Loss:&lt;/strong&gt; -0.67&lt;/li&gt;
&lt;/ul&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%2Fp35gegfqvb3jwl4b2sr5.png" 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%2Fp35gegfqvb3jwl4b2sr5.png" alt=" " width="800" height="641"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding the Culprit: Asset Breakdown
&lt;/h3&gt;

&lt;p&gt;Looking at the PnL by asset class revealed the obvious weak link:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;LINKUSDT&lt;/code&gt;: 5W 4L (+3.33 USDT) 🏆&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;XRPUSDT&lt;/code&gt;: 3W 3L (+0.09 USDT)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ETHUSDT&lt;/code&gt;: 5W 6L (-1.83 USDT)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;BTCUSDT&lt;/code&gt;: 1W 3L (-1.26 USDT)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SOLUSDT&lt;/code&gt;: &lt;strong&gt;0W 4L (-2.75 USDT)&lt;/strong&gt; 🚨&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Insight 1: The Solana Mismatch.&lt;/strong&gt; Just like ADA in my previous bot version, SOL's volatility profile does not fit my 15-minute timeframe strategy. All 4 trades were LONG entries that reversed and hit the stop-loss within 15 mins to 2 hours. &lt;em&gt;If I had simply excluded SOL, my net PnL would have been +0.33 USDT.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Digging Deeper: The Volume Climax Trap
&lt;/h3&gt;

&lt;p&gt;I cross-referenced all losing trades with my technical indicators. A glaring pattern emerged regarding the &lt;strong&gt;Volume Oscillator (VOL_OSC)&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;I isolated all trades where the bot entered while &lt;code&gt;VOL_OSC &amp;gt;= 30&lt;/code&gt; (indicating an unusually high volume spike):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;04-06 ETHUSDT BUY (VOL_OSC 42.4) -&amp;gt; -1.33 &lt;/li&gt;
&lt;li&gt;04-14 SOLUSDT BUY (VOL_OSC 58.2) -&amp;gt; -1.07&lt;/li&gt;
&lt;li&gt;04-14 ETHUSDT BUY (VOL_OSC 53.0) -&amp;gt; -1.02&lt;/li&gt;
&lt;li&gt;04-16 XRPUSDT BUY (VOL_OSC 51.5) -&amp;gt; -1.00&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Insight 2: Do not chase the climax.&lt;/strong&gt; 4 trades, 4 losses, costing me -4.42 USDT. When volume spikes abnormally high, the trend is usually reaching its climax before a sharp reversal. My bot was chasing the breakout right at the top. &lt;em&gt;Filtering out these 4 trades alone would have pushed my net PnL to +2.00 USDT.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Plan for v8.04
&lt;/h3&gt;

&lt;p&gt;Data analysis turns failure into a roadmap. For the upcoming v8.04 update, I am implementing two simple, data-driven rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Drop SOLUSDT&lt;/strong&gt; from the watchlist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement a Climax Filter:&lt;/strong&gt; Block all entries if &lt;code&gt;VOL_OSC &amp;gt;= 30&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These two rules alone would have improved this week's performance by roughly +6 USDT. &lt;/p&gt;

&lt;p&gt;Algo-trading isn't about intuition; it's about debugging your logic through raw data. Time to update the code and let v8.04 run. I'll share the results next time!&lt;/p&gt;

</description>
      <category>python</category>
      <category>algotrading</category>
      <category>data</category>
      <category>lessons</category>
    </item>
    <item>
      <title>[DeskFlow]Improving UX in my Side Project: Adding Multi-select &amp; Group Move to DeskFlow</title>
      <dc:creator>rocketsquirreldev</dc:creator>
      <pubDate>Wed, 15 Apr 2026 13:22:51 +0000</pubDate>
      <link>https://dev.to/rocketsquirreldev/deskflowimproving-ux-in-my-side-project-adding-multi-select-group-move-to-deskflow-33gd</link>
      <guid>https://dev.to/rocketsquirreldev/deskflowimproving-ux-in-my-side-project-adding-multi-select-group-move-to-deskflow-33gd</guid>
      <description>&lt;p&gt;As an indie developer building &lt;a href="https://deskflow.app" rel="noopener noreferrer"&gt;DeskFlow&lt;/a&gt; (a visual desk setup &amp;amp; cable planner), I've been using my own tool to plan my home office upgrade. &lt;/p&gt;

&lt;p&gt;But I quickly realized a massive pain point: as my setup grew complex, moving things around became a chore. To move a monitor, a hub, and a laptop, I had to click and drag each item individually. It was tedious and counter-intuitive.&lt;/p&gt;

&lt;p&gt;So, I spent my late-night coding session implementing a proper &lt;strong&gt;Multi-select and Group Move&lt;/strong&gt; feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's New?
&lt;/h3&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%2Fgp1r90d54019y0gaa2mb.png" 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%2Fgp1r90d54019y0gaa2mb.png" alt=" " width="800" height="647"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Box Selection:&lt;/strong&gt; Click and drag on an empty canvas to create a selection box (highlighted with an orange dotted border). Any hardware nodes within the box are selected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modifier Keys:&lt;/strong&gt; Use &lt;code&gt;Shift&lt;/code&gt; or &lt;code&gt;Cmd/Ctrl&lt;/code&gt; + click to toggle selection on individual nodes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synchronized Movement:&lt;/strong&gt; Once selected, dragging any node moves the entire group. Cables follow the movement in real-time, maintaining the structure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch Action:&lt;/strong&gt; Hit &lt;code&gt;Delete&lt;/code&gt; to clear out multiple nodes at once.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why this matters
&lt;/h3&gt;

&lt;p&gt;In any visual tool, the "speed of thought" should not be hindered by the UI. By allowing users to rearrange clusters of devices in a single motion, planning a desk layout becomes much more fluid and playful.&lt;/p&gt;

&lt;p&gt;If you're a fellow developer or gear enthusiast looking to map out your cable management or desk peripherals, give it a spin. No installation, no sign-up—just pure planning in your browser.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Link:&lt;/strong&gt; &lt;a href="https://deskflow-gold.vercel.app/" rel="noopener noreferrer"&gt;https://deskflow-gold.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd love to hear your feedback on the UX or any features you'd like to see next!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>javascript</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>[x509Lab]Generating Ed25519 Certificate Chains in the Browser (No Server Required)</title>
      <dc:creator>rocketsquirreldev</dc:creator>
      <pubDate>Tue, 14 Apr 2026 12:25:41 +0000</pubDate>
      <link>https://dev.to/rocketsquirreldev/generating-ed25519-certificate-chains-in-the-browser-no-server-required-2c2e</link>
      <guid>https://dev.to/rocketsquirreldev/generating-ed25519-certificate-chains-in-the-browser-no-server-required-2c2e</guid>
      <description>&lt;p&gt;I recently released an update to &lt;strong&gt;x509Lab&lt;/strong&gt; (a completely browser-based visual certificate chain builder) to support &lt;strong&gt;Ed25519&lt;/strong&gt; key generation and signing. &lt;/p&gt;

&lt;p&gt;If you deal with modern TLS, SSH, or code signing, you know Ed25519 is becoming the standard. It uses much smaller keys than RSA and offers faster signing than ECDSA. &lt;/p&gt;

&lt;p&gt;Here is how I implemented it entirely on the client side using the Web Crypto API, without any backend server.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Try it live:&lt;/strong&gt; &lt;a href="https://x509lab.vercel.app" rel="noopener noreferrer"&gt;https://x509lab.vercel.app&lt;/a&gt;&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%2Fvxoj4wyepk8n6qxekq80.png" 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%2Fvxoj4wyepk8n6qxekq80.png" alt=" " width="458" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Visualizing and Generating Ed25519 Chains
&lt;/h3&gt;

&lt;p&gt;The goal of x509Lab is to let you drag and drop Root CAs, Intermediate CAs, and Leaf nodes, connect them, and generate a valid PKI tree. &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%2Ffz44eho25iw5kt7wxrmk.png" 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%2Ffz44eho25iw5kt7wxrmk.png" alt="Canvas &amp;amp; Generation Modal" width="800" height="302"&gt;&lt;/a&gt;&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%2Fdct9ayxax74esyluum9p.png" 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%2Fdct9ayxax74esyluum9p.png" alt="Select Ed25519" width="528" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, when you click &lt;code&gt;Generate Certs&lt;/code&gt;, you can select &lt;strong&gt;Ed25519&lt;/strong&gt; from the Key Algorithm dropdown. The app will instantly generate the keypairs, sign the certificates down the chain, and verify the trust loop—all in your browser.&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%2Ftavwb295i1ldfku0zv2s.png" 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%2Ftavwb295i1ldfku0zv2s.png" alt="Generation Complete" width="530" height="365"&gt;&lt;/a&gt;&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%2Foyh3puzm99pwkzro2cmd.png" 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%2Foyh3puzm99pwkzro2cmd.png" alt="Verified Chain" width="409" height="769"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Technical Struggle: Web Crypto API &amp;amp; ASN.1 DER
&lt;/h3&gt;

&lt;p&gt;Generating the keys using &lt;code&gt;crypto.subtle.generateKey({ name: 'Ed25519' })&lt;/code&gt; and signing them was the easy part. The real challenge was encoding the resulting certificates into a valid &lt;code&gt;.pem&lt;/code&gt; format that OpenSSL would accept. &lt;/p&gt;

&lt;p&gt;The Web Crypto API doesn't spit out X.509 certificates out of the box. You have to build the ASN.1 structure manually.&lt;/p&gt;

&lt;p&gt;Here are a few technical hurdles I had to overcome:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Custom OID Implementation:&lt;/strong&gt; I had to manually implement the DER encoding for the Ed25519 Object Identifier (&lt;code&gt;1.3.101.112&lt;/code&gt;) based on RFC 8410.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The NULL Parameter Trap:&lt;/strong&gt; When dealing with RSA, the signature algorithm sequence typically includes a &lt;code&gt;NULL&lt;/code&gt; parameter. However, for Ed25519, including this &lt;code&gt;NULL&lt;/code&gt; parameter violates the standard and breaks the certificate. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Raw Signatures:&lt;/strong&gt; Unlike ECDSA, which requires converting the signature into a specific DER sequence, Ed25519 uses the raw 64-byte signature directly.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Auto-generating OpenSSL Commands
&lt;/h3&gt;

&lt;p&gt;A visual tool is great, but eventually, you need to type commands into a terminal. &lt;/p&gt;

&lt;p&gt;x509Lab analyzes your visual tree and generates the exact &lt;code&gt;openssl&lt;/code&gt; CLI commands needed to recreate that setup. With this update, it now natively outputs the correct syntax for Ed25519:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;openssl genpkey -algorithm Ed25519 -out root.key&lt;/code&gt;&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%2F4d36m74c4ml9oajp29w3.png" 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%2F4d36m74c4ml9oajp29w3.png" alt="OpenSSL Commands" width="707" height="895"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're studying cryptography, setting up internal CAs, or just sick of remembering OpenSSL flags, give it a try. Let me know what you think in the comments!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>cryptography</category>
      <category>javascript</category>
    </item>
    <item>
      <title>[CryptoTradingBot]Building a Real-Time Dashboard for My Python Crypto Bot (Without Breaking It)</title>
      <dc:creator>rocketsquirreldev</dc:creator>
      <pubDate>Fri, 10 Apr 2026 12:52:42 +0000</pubDate>
      <link>https://dev.to/rocketsquirreldev/building-a-real-time-dashboard-for-my-python-crypto-bot-without-breaking-it-4mm3</link>
      <guid>https://dev.to/rocketsquirreldev/building-a-real-time-dashboard-for-my-python-crypto-bot-without-breaking-it-4mm3</guid>
      <description>&lt;p&gt;When I first deployed my Python crypto trading bot to an AWS EC2 instance, I thought Telegram notifications would be enough. Getting a ping for every entry, stop-loss, or take-profit felt sufficient.&lt;/p&gt;

&lt;p&gt;But over time, the limitations became glaring. &lt;em&gt;What's my current win rate? How is v8.03 performing compared to v8.02? What's the exact PnL curve looking like?&lt;/em&gt; Telegram gives you isolated moments; it doesn't give you the narrative. But to see the big picture, I had to RDP into my Windows EC2 server, open CSV files, and manually calculate stats. I needed a dashboard, but I had one strict rule: &lt;strong&gt;Do not touch the core trading logic.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is how I built a real-time web dashboard for my bot with minimal footprint.&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%2Frv4leplcxqeashc6mhly.png" 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%2Frv4leplcxqeashc6mhly.png" alt=" " width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Architecture: Decoupled by Design
&lt;/h3&gt;

&lt;p&gt;Injecting UI or heavy API logic directly into a live trading bot is a recipe for disaster. If the UI thread crashes, I don't want it bringing down the trading engine during a volatile market move.&lt;/p&gt;

&lt;p&gt;I opted for a completely decoupled file-based architecture:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Bot (Writer):&lt;/strong&gt; Runs as usual. At the end of every candle evaluation, it simply writes its current state (balance, open positions, active settings) to a &lt;code&gt;bot_state.json&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Flask API (Reader):&lt;/strong&gt; A lightweight separate process that reads the &lt;code&gt;.json&lt;/code&gt; and &lt;code&gt;.csv&lt;/code&gt; trade logs and serves them via REST endpoints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Frontend:&lt;/strong&gt; A Vanilla JS + Chart.js static HTML page that polls the API every 15 seconds.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 1: The Lightweight Flask API
&lt;/h3&gt;

&lt;p&gt;I created a &lt;code&gt;dashboard_api.py&lt;/code&gt; script. It exposes endpoints like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/api/status&lt;/code&gt;: Bot version, strategy, ADX levels.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/api/balance&lt;/code&gt;: Current USDT balance.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/api/trades&lt;/code&gt;: Parses the CSV trade logs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/api/stats&lt;/code&gt;: Calculates win rate and total PnL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Inside the main bot script, I only added three lines of code inside the &lt;code&gt;start()&lt;/code&gt; method to launch the Flask server as a daemon thread. The trading logic remained untouched.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: The Vanilla JS Frontend
&lt;/h3&gt;

&lt;p&gt;I didn't want to over-engineer this with React or Vue. A single &lt;code&gt;index.html&lt;/code&gt; file using Vanilla JS and &lt;code&gt;Chart.js&lt;/code&gt; for the PnL curve was perfect. &lt;/p&gt;

&lt;p&gt;It fetches data asynchronously every 15 seconds. The dashboard displays active parameters, a live PnL chart, currently open positions, a recent trade ledger, and a historical comparison of bot versions (e.g., v8.00 vs v8.01 vs v8.02).&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenges &amp;amp; Troubleshooting
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. The Flask Threading Bottleneck&lt;/strong&gt;&lt;br&gt;
Initially, the dashboard kept hanging. The browser was trying to fetch 6 API endpoints simultaneously, but the default Flask development server runs on a single thread. Requests were timing out.&lt;br&gt;
&lt;em&gt;Fix:&lt;/em&gt; Simply setting &lt;code&gt;threaded=True&lt;/code&gt; in the &lt;code&gt;app.run()&lt;/code&gt; parameters solved the concurrency issue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Legacy CSV Ghost Data&lt;/strong&gt;&lt;br&gt;
My total PnL suddenly showed +$3,700 USDT (which I definitely didn't make). The API was reading old v7.x CSV files sitting in the &lt;code&gt;logs/&lt;/code&gt; directory. Because the column structures had changed between versions, the parser was reading random timestamp strings as PnL floats.&lt;br&gt;
&lt;em&gt;Fix:&lt;/em&gt; Added a strict date filter and outlier rejection logic to ignore corrupted or legacy data rows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The AWS + Windows Double Firewall&lt;/strong&gt;&lt;br&gt;
I opened port &lt;code&gt;8765&lt;/code&gt; (API) and &lt;code&gt;3000&lt;/code&gt; (HTML) in my AWS Security Group, restricted to my IP. But I still couldn't connect. I forgot that I was running a &lt;em&gt;Windows&lt;/em&gt; EC2 instance, which has its own internal firewall.&lt;br&gt;
&lt;em&gt;Fix:&lt;/em&gt; Had to add an inbound rule via the command line:&lt;br&gt;
&lt;code&gt;netsh advfirewall firewall add rule name="Dashboard" dir=in action=allow protocol=TCP localport=8765&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Building this dashboard was a game-changer. Staring at raw numbers in a terminal is one thing, but seeing a visual PnL curve and a comparative table of version win rates immediately highlights structural flaws in your strategy. &lt;/p&gt;

&lt;p&gt;If you are building an algo-trading bot, spend a weekend building a visual dashboard. Data visualization is the first real step toward strategy optimization.&lt;/p&gt;

</description>
      <category>python</category>
      <category>flask</category>
      <category>aws</category>
      <category>algotrading</category>
    </item>
  </channel>
</rss>
