<?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: Bot and Bull</title>
    <description>The latest articles on DEV Community by Bot and Bull (@botandbull).</description>
    <link>https://dev.to/botandbull</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%2F4133644%2F62fe530e-18f8-4209-a2a0-d329ad7f24f3.png</url>
      <title>DEV Community: Bot and Bull</title>
      <link>https://dev.to/botandbull</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/botandbull"/>
    <language>en</language>
    <item>
      <title>Wide Net, Fine Mesh: Why a Bigger Watchlist Didn't Make My Trading Bot Trade More</title>
      <dc:creator>Bot and Bull</dc:creator>
      <pubDate>Tue, 27 Oct 2026 16:00:00 +0000</pubDate>
      <link>https://dev.to/botandbull/wide-net-fine-mesh-why-a-bigger-watchlist-didnt-make-my-trading-bot-trade-more-2hkd</link>
      <guid>https://dev.to/botandbull/wide-net-fine-mesh-why-a-bigger-watchlist-didnt-make-my-trading-bot-trade-more-2hkd</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffnvg9o7wid18yat0l9w4.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffnvg9o7wid18yat0l9w4.jpg" alt="Bot and Bull card: Stop picking the stocks. Part 4 of the build: why scanning a wider slice of the market made my trading bot smarter, not busier. botandbull.com." width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My trading bot started with a short, hand-picked watchlist: stocks I knew and liked. When I widened it to scan a much bigger slice of the market, I braced for the bot to start trading constantly.&lt;/p&gt;

&lt;p&gt;It didn't. Trade count barely moved. What changed was the quality of what it picked, and the reason is in how the shortlist gets built:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;shortlist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;universe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_picks&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Wide net, fine mesh: check everything, keep only what clears every rule.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;passed&lt;/span&gt; &lt;span class="o"&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;universe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;bars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_daily_bars&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;bars&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;  &lt;span class="c1"&gt;# missing data is a skip, not a guess
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bars&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;rule&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;passed&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="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bars&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;passed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;symbol&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&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;passed&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;max_picks&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;  &lt;span class="c1"&gt;# an empty list is a valid answer
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three things this shape gets right:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The universe grows, &lt;code&gt;max_picks&lt;/code&gt; doesn't.&lt;/strong&gt; A bigger list means more candidates competing for the same few slots, so the bar effectively goes up, not down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every symbol gets the same rules.&lt;/strong&gt; The thousandth stock is judged exactly like the first. No fatigue, no favorites.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Empty is allowed.&lt;/strong&gt; On a weak day, nothing clears every rule and the bot does nothing. That's the feature, not a bug.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The trap is the opposite move: loosening the rules so a bigger list produces more trades. That's how you turn a wide net into a lot of mediocre positions.&lt;/p&gt;

&lt;p&gt;The full story, including the day the bot flagged a company I'd never heard of, is here: &lt;a href="https://botandbull.com/trading-bot-watchlist/" rel="noopener noreferrer"&gt;How I expanded my trading bot's watchlist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're earlier in the journey, Part 1 is &lt;a href="https://botandbull.com/automated-trading-bot-no-coding/" rel="noopener noreferrer"&gt;how I built a trading bot with no coding background&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Educational only, not financial advice.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>buildinpublic</category>
      <category>algorithms</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The Hidden Assumption My Trading Bot Made About Market Hours</title>
      <dc:creator>Bot and Bull</dc:creator>
      <pubDate>Wed, 21 Oct 2026 14:06:00 +0000</pubDate>
      <link>https://dev.to/botandbull/the-hidden-assumption-my-trading-bot-made-about-market-hours-44ep</link>
      <guid>https://dev.to/botandbull/the-hidden-assumption-my-trading-bot-made-about-market-hours-44ep</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy5n2uq8x6xqz1mpp8k49.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy5n2uq8x6xqz1mpp8k49.png" alt="Bot and Bull card: Same bot, a market that never sleeps. Part 3 of the build, what changed when I pointed my trading bot at crypto and why the safety net had to be rethought." width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My trading bot worked fine on stocks. Then I pointed it at crypto and found an assumption I didn't know I'd written: that the market closes.&lt;/p&gt;

&lt;p&gt;A lot of stock logic quietly depends on that. Daily opens and closes, overnight gaps, "run this after the bell." None of it exists in a market that trades all day, every day.&lt;/p&gt;

&lt;p&gt;The first fix was making the assumption explicit instead of buried:&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;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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;zoneinfo&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ZoneInfo&lt;/span&gt;

&lt;span class="n"&gt;ET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ZoneInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;America/New_York&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;OPEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CLOSE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&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="mi"&gt;16&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;market_is_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asset_class&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&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;datetime&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&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;asset_class&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;crypto&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;  &lt;span class="c1"&gt;# no bell, no weekends off
&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;now&lt;/span&gt; &lt;span class="ow"&gt;or&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;now&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ET&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;now&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="c1"&gt;# Saturday, Sunday
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;OPEN&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="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="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;CLOSE&lt;/span&gt;  &lt;span class="c1"&gt;# holidays need their own check
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Small function, big consequences:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Every scheduled job asks this first,&lt;/strong&gt; so stock-only logic can't accidentally run against a 24/7 market.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It forced a harder question:&lt;/strong&gt; if crypto never closes, who's watching at 3 AM? The answer had to be the bot itself, so every protective rule became automatic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing changed too.&lt;/strong&gt; A crypto change isn't tested until it has run on paper through a full weekend, because weekends are where the differences show up.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The rest of what changed (the safety net, the signals, position sizing) is in the full write-up: &lt;a href="https://botandbull.com/crypto-trading-bot/" rel="noopener noreferrer"&gt;How I added crypto to my trading bot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're setting up your first bot, the step-by-step setup is in &lt;a href="https://botandbull.com/set-up-robinhood-trading-bot/" rel="noopener noreferrer"&gt;Part 2 of the build&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Educational only, not financial advice.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>buildinpublic</category>
      <category>cryptocurrency</category>
    </item>
    <item>
      <title>The One Flag That Kept My Trading Bot From Spending Real Money Too Early</title>
      <dc:creator>Bot and Bull</dc:creator>
      <pubDate>Wed, 14 Oct 2026 14:00:00 +0000</pubDate>
      <link>https://dev.to/botandbull/the-one-flag-that-kept-my-trading-bot-from-spending-real-money-too-early-247f</link>
      <guid>https://dev.to/botandbull/the-one-flag-that-kept-my-trading-bot-from-spending-real-money-too-early-247f</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftyqyed16ootkzvwf83sk.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftyqyed16ootkzvwf83sk.png" alt="Bot and Bull card: From an empty account to a trading bot that runs itself. Part 2 of the build, the setup step by step. botandbull.com." width="800" height="420"&gt;&lt;/a&gt;&lt;br&gt;
When I set up my first trading bot, the scariest moment wasn't the code. It was the first time the code could place a real order.&lt;/p&gt;

&lt;p&gt;So before any buying logic existed, every order went through one function with one switch in front of it:&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;os&lt;/span&gt;

&lt;span class="n"&gt;DRY_RUN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DRY_RUN&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;true&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;place_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&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;qty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;side&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;DRY_RUN&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;[DRY RUN] would &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;side&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;qty&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;symbol&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;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="o"&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;qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;qty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;side&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three things I like about this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;It defaults to safe.&lt;/strong&gt; If I forget to set the variable, nothing real happens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;There's one door.&lt;/strong&gt; No other part of the bot talks to the broker's order endpoint directly, so there's one place to check.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keys and switches live in the environment, not the code.&lt;/strong&gt; Nothing sensitive ends up in a repo.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I ran in dry-run mode, then on a paper account, for weeks before flipping it. Boring was the goal.&lt;/p&gt;

&lt;p&gt;That's one step of nine. I wrote up the full setup, from an empty account to a bot that runs on a schedule, here: &lt;a href="https://botandbull.com/set-up-robinhood-trading-bot/" rel="noopener noreferrer"&gt;How to set up a trading bot from scratch, step by step&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're starting from zero like I did, the story of how it began is in &lt;a href="https://botandbull.com/automated-trading-bot-no-coding/" rel="noopener noreferrer"&gt;Part 1 of the build&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Educational only, not financial advice.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>buildinpublic</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Couldn't Code, So I Made AI My Pair Programmer and Built a Trading Bot</title>
      <dc:creator>Bot and Bull</dc:creator>
      <pubDate>Wed, 07 Oct 2026 18:15:35 +0000</pubDate>
      <link>https://dev.to/botandbull/i-couldnt-code-so-i-made-ai-my-pair-programmer-and-built-a-trading-bot-2cem</link>
      <guid>https://dev.to/botandbull/i-couldnt-code-so-i-made-ai-my-pair-programmer-and-built-a-trading-bot-2cem</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5825z1ep27xuv0upaksu.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5825z1ep27xuv0upaksu.png" alt="Bot and Bull Build Log Part 1 card: No coding background. One automated trading bot. Terminal badge shows bot status running."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A couple of years ago I could not have told you what an API was. Today a bot I built runs on a small cloud server every evening, checks the market against rules I wrote, and flags what's worth a look. I still don't have a coding background. What I have is a workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plain English in, working code out
&lt;/h2&gt;

&lt;p&gt;I never sat down to "learn to code" first. I described what I wanted in plain English, got code back from an AI, ran it, watched it break, and pasted the error back in. Repeat until it works. Then make it explain every line until I understand why it works.&lt;/p&gt;

&lt;p&gt;The first real version looked roughly like 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;# What I asked for, in plain English:
# "Every evening, check my watchlist. If a stock fits my rules,
#  flag it. Never buy anything without asking me first."
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;evening_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;watchlist&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;watchlist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;bars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_daily_bars&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="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;fits_my_rules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bars&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="nf"&gt;flag_for_review&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="c1"&gt;# a human makes the final call
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing clever. Watch, decide with rules, act. That's the whole shape of a trading bot. Everything else is detail on top of those three moves.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the AI didn't do for me
&lt;/h2&gt;

&lt;p&gt;It wrote code fast. It did not tell me what to build, which assumptions were wrong, or when "it runs" wasn't the same as "it's right." That part was on me, and it's where most of the real lessons came from.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell another beginner
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Build the guardrails before the exciting parts.&lt;/li&gt;
&lt;li&gt;Make the AI explain its code. If you can't read it, you can't debug it.&lt;/li&gt;
&lt;li&gt;Keep the stack lean: a broker with an API, a small server, Python.&lt;/li&gt;
&lt;li&gt;Start before you feel ready. The mental block is harder than the building.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wrote the full story, including the fears that almost stopped me and the mistakes I'd skip, in &lt;a href="https://botandbull.com/automated-trading-bot-no-coding/" rel="noopener noreferrer"&gt;How I Built an Automated Trading Bot With No Coding Background&lt;/a&gt;. If you want the actual stack, the &lt;a href="https://botandbull.com/trading-bot-tools-i-recommend/" rel="noopener noreferrer"&gt;trading bot tools I recommend&lt;/a&gt; page has it.&lt;/p&gt;

&lt;p&gt;This is education, not financial advice.&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>ai</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>The Bug That Passed Every Test and Still Lost Me Money</title>
      <dc:creator>Bot and Bull</dc:creator>
      <pubDate>Sun, 20 Sep 2026 04:46:31 +0000</pubDate>
      <link>https://dev.to/botandbull/the-bug-that-passed-every-test-and-still-lost-me-money-1gl5</link>
      <guid>https://dev.to/botandbull/the-bug-that-passed-every-test-and-still-lost-me-money-1gl5</guid>
      <description>&lt;p&gt;I am building an automated stock trading bot in public. I am not a developer by trade, so I lean hard on tests to feel safe shipping. Which is exactly why this one stung: a bug that passed every single test I had, and still lost me money the moment it touched the real market.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The suite was green, so I trusted it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every test passed. I deployed. That green checkmark felt like permission.&lt;/p&gt;

&lt;p&gt;The problem was hiding in plain sight: my tests fed the bot clean, well behaved data that I made up myself. The code did exactly what I told it to do. My tests just never told it to handle the real world.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What actually happened&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The bot runs a routine at the end of the trading day. My tests used fixed timestamps, so timing itself was never really under test.&lt;/p&gt;

&lt;p&gt;Live, the server ran on UTC while the market runs on Eastern time. The end of day routine fired before the session's data was actually final, so the bot made decisions on half baked numbers.&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;# what I had (naive)
&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;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;          &lt;span class="c1"&gt;# server's timezone, not the market's
&lt;/span&gt;&lt;span class="k"&gt;if&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;hour&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;            &lt;span class="c1"&gt;# "after close"... in the wrong timezone
&lt;/span&gt;    &lt;span class="nf"&gt;run_end_of_day&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looked correct. It passed. It was wrong about the one thing that mattered: which clock the market actually runs on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why the tests missed it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unit tests prove your code does what you told it to do. They do not prove your assumptions about the outside world are right.&lt;/p&gt;

&lt;p&gt;I had tested the logic and skipped the environment. Market hours, timezones, holidays, missing data, none of it was in my tests, because I was hand feeding the inputs. A green suite told me my code was consistent. It said nothing about whether it was correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I changed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tests now use messy, realistic data: wrong timezones, missing bars, holidays, odd prices.&lt;br&gt;
Anything time related is explicit and timezone aware. No more datetime.now() and a hopeful guess.&lt;br&gt;
New rule: nothing goes live until it has survived small, real stakes, not just the test suite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The takeaway&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A green test suite means your code is consistent, not that it is correct. For anything that touches the real world, and money most of all, test the world, not just the function.&lt;/p&gt;

&lt;p&gt;I am documenting this whole build in public, including the &lt;a href="https://botandbull.com/trading-bot-tools-i-recommend/" rel="noopener noreferrer"&gt;tools I recommend&lt;/a&gt; to run it and the bruises like this one. If you want to follow along, everything lives at &lt;a href="https://botandbull.com" rel="noopener noreferrer"&gt;Bot and Bull&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is education, not financial advice.&lt;/p&gt;

</description>
      <category>python</category>
      <category>automation</category>
      <category>beginners</category>
      <category>buildinpublic</category>
    </item>
  </channel>
</rss>
