<?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:  WWP</title>
    <description>The latest articles on DEV Community by  WWP (@tatsuyawwp).</description>
    <link>https://dev.to/tatsuyawwp</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4060221%2F7b3b90d3-d53b-4852-aa58-7041a70c662e.png</url>
      <title>DEV Community:  WWP</title>
      <link>https://dev.to/tatsuyawwp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tatsuyawwp"/>
    <language>en</language>
    <item>
      <title>I had an AI agent build 3 trading bots. It was losing to HFT before it even started.</title>
      <dc:creator> WWP</dc:creator>
      <pubDate>Mon, 03 Aug 2026 08:58:05 +0000</pubDate>
      <link>https://dev.to/tatsuyawwp/i-had-an-ai-agent-build-3-trading-bots-it-was-losing-to-hft-before-it-even-started-1kia</link>
      <guid>https://dev.to/tatsuyawwp/i-had-an-ai-agent-build-3-trading-bots-it-was-losing-to-hft-before-it-even-started-1kia</guid>
      <description>&lt;p&gt;I run a one-person AI company. A few weeks ago I pointed Claude Code — an AI coding agent — at a simple brief: build a paper-trading bot, watch it run, tell me honestly whether it works.&lt;/p&gt;

&lt;p&gt;It built three: crypto, equities, and options, each against &lt;a href="https://alpaca.markets" rel="noopener noreferrer"&gt;Alpaca&lt;/a&gt;'s paper trading API. Full code is public: &lt;a href="https://github.com/tatsuyawwp/ai-trading-bot-experiment" rel="noopener noreferrer"&gt;github.com/tatsuyawwp/ai-trading-bot-experiment&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This post is about what happened when I asked it the one question that actually mattered, and made it answer honestly instead of just shipping something that looked done.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bots got built. That part was never the hard part.
&lt;/h2&gt;

&lt;p&gt;Within a few sessions there were three working bots: entry/exit logic, stop-losses and take-profits, a circuit breaker that halts everything after a cumulative paper loss, email alerts, isolated paper accounts per asset class so one bot's drawdown couldn't false-trigger another's, and a decision logger that records &lt;em&gt;every&lt;/em&gt; evaluation cycle — not just fills — so nothing could hide in a gap between logs.&lt;/p&gt;

&lt;p&gt;The agent also found and fixed its own bugs along the way. Early on, the crypto bot's price feed was silently broken: a missing parameter meant the API was returning a fixed window from midnight instead of the most recent bars, so the bot had been making live trading decisions off a BTC price frozen at exactly the same number for over an hour. Later, the options bot's stop-loss slipped from -30% to -42% on a real (paper) fill, which turned out to be poll-interval gap plus thin-spread slippage on a real illiquid contract, not a logic bug. These are the kind of bugs that are easy to miss and expensive to leave in — the kind you actually want an agent that never gets bored re-checking for.&lt;/p&gt;

&lt;p&gt;None of that is the interesting part of this post. Building working trading infrastructure is a solved problem. The interesting part is what happened when I stopped asking "does it run" and started asking "does it win."&lt;/p&gt;

&lt;h2&gt;
  
  
  The question that mattered: can this actually compete?
&lt;/h2&gt;

&lt;p&gt;I asked the agent, bluntly: does a retail bot like this have any realistic edge, or is this just an elaborate way to lose money slowly?&lt;/p&gt;

&lt;p&gt;It didn't have an opinion of its own worth trusting on this — so it went and checked. The honest numbers that came back:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: colocated HFT infrastructure sits 10,000–100,000x closer to the exchange than a REST API call from a home machine. Not a rounding error — a different sport.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost&lt;/strong&gt;: at $20/trade with 5-minute polling, realistic round-trip cost (taker fees + real spread, not the optimistic best-case number) runs 0.65–1.08% per crypto symbol. A technical-indicator strategy trying to scalp small moves on that timescale is fighting a cost structure that eats the edge before it exists.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The blunt verdict, once we ran the actual numbers instead of assuming: a retail agent trying to out-trade HFT on speed has zero chance, full stop. The viable move isn't "tune the parameters harder" — it's stop competing on a timescale where the fee structure and the speed gap both work against you, and move to a timescale where they don't.&lt;/p&gt;

&lt;h2&gt;
  
  
  So we tested it properly — and it kept failing
&lt;/h2&gt;

&lt;p&gt;Once the frame was "prove it, don't assume it," the actual work was a strategy going through a real gate: propose a hypothesis, backtest it against real historical data, only ever adopt something that clears a pre-agreed bar (profit factor &amp;gt; 1.2), and — critically — reject it if it doesn't, instead of quietly lowering the bar.&lt;/p&gt;

&lt;p&gt;Five hypotheses went through that gate for the crypto bot alone:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The strategy already running live&lt;/strong&gt; (price-deviation + momentum): 469 trades, 26.9% win rate, profit factor 0.36. A real, statistically real loser — not bad luck on a small sample.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bollinger Band breakout&lt;/strong&gt; (Gemini's first suggestion for something structurally different): 6,712 trades, profit factor 0.06. The exit band was so tight the strategy was closing on every normal pullback before ever reaching its own stop-loss or take-profit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Same entry, fixed stop-loss/take-profit instead of the band exit&lt;/strong&gt;: 339 trades, profit factor 0.36 again — same ceiling, worse win rate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A 4-hour EMA crossover trend strategy&lt;/strong&gt;, tested on 1 year / 4 symbols: profit factor 1.23. This &lt;em&gt;looked&lt;/em&gt; like a pass. It wasn't — 2 outlier trades accounted for almost the entire profit. Extended to 4 years / 10 symbols per the same discipline that flagged the first result as too small to trust: profit factor 0.42. Decisive rejection, and a good reminder that a strategy passing on a small sample is usually a coincidence wearing a lab coat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A liquidation-cascade mean-reversion catcher&lt;/strong&gt;: profit factor 0.68. An early version looked much better (1.36–1.44) until a more conservative cost assumption on some added symbols collapsed it — the "good" number turned out to be an unverified-cost artifact, not real edge.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Somewhere in there, the backtest tooling itself turned out to have a real bug: Alpaca's historical crypto data has genuine multi-hundred-day gaps for some symbols, and the lookup logic didn't detect them — it silently used a stale pre-gap price as "current," which manufactured one fake +672% trade that briefly made an early run look like it had a profit factor of 3.51. Found, fixed, re-verified. The whole point of building the gate was that it had to be trustworthy enough to actually kill bad ideas instead of just rubber-stamping whatever came out of the last backtest run.&lt;/p&gt;

&lt;h2&gt;
  
  
  The sixth one passed
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cross-sectional momentum rotation&lt;/strong&gt; — rank the watchlist by 7-day return, hold only whichever one is #1, rotate daily — cleared the bar: profit factor 1.55 on 116 trades, no small-sample red flags, and every individual trade traced back to a real, explainable market event (BTC's 2023 recovery, ETH's 2024–25 run, DOGE's 2024 spike) rather than a lucky fluke.&lt;/p&gt;

&lt;p&gt;It's live now, on the real (paper) account, holding at most one position at a time. Rolling it out wasn't clean, either — minutes after the new code was saved, the unattended 5-minute scheduler ran it before a code review caught a bug where a still-forming daily candle got treated as a closed one, producing one real (paper) trade on partial data. Caught, fixed, re-verified, redeployed. The fix for &lt;em&gt;that&lt;/em&gt; was procedural, not just technical: disable the scheduled task before editing a live bot's code, not after you find out it did something during the edit.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually take away from this
&lt;/h2&gt;

&lt;p&gt;An AI agent turned out to be genuinely good at the parts of this that reward being tireless and honest: building real risk controls, catching its own stale-data and off-by-one bugs, running five backtests back to back without getting attached to any of them, and rejecting its own best-looking result when a bigger sample said otherwise.&lt;/p&gt;

&lt;p&gt;It was not, on its own, a source of alpha. Nothing here found an edge because the agent was clever — it found one (maybe) because the process refused to accept "looks promising" as good enough, five times in a row, before something finally survived a harder test.&lt;/p&gt;

&lt;p&gt;Code, real numbers (including the losing ones), and the honest per-bot writeups are here: &lt;a href="https://github.com/tatsuyawwp/ai-trading-bot-experiment" rel="noopener noreferrer"&gt;github.com/tatsuyawwp/ai-trading-bot-experiment&lt;/a&gt;. Paper money only — nothing in this post or the repo is a recommendation to trade anything.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>trading</category>
      <category>python</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
