<?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: Steve Farmer</title>
    <description>The latest articles on DEV Community by Steve Farmer (@predictandprofit).</description>
    <link>https://dev.to/predictandprofit</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%2F3961756%2Fb83fa494-cf8d-4f6f-937f-d4be15a039ea.jpg</url>
      <title>DEV Community: Steve Farmer</title>
      <link>https://dev.to/predictandprofit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/predictandprofit"/>
    <language>en</language>
    <item>
      <title>The Fix Was Not a Cleverer Model</title>
      <dc:creator>Steve Farmer</dc:creator>
      <pubDate>Thu, 13 Aug 2026 00:01:00 +0000</pubDate>
      <link>https://dev.to/predictandprofit/the-fix-was-not-a-cleverer-model-3oik</link>
      <guid>https://dev.to/predictandprofit/the-fix-was-not-a-cleverer-model-3oik</guid>
      <description>&lt;p&gt;I spent four months tuning a custom weather ensemble. It was worse than guessing. The fix was not a better ensemble. It was admitting someone already built the right thing and giving it away for free.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I built and why it failed
&lt;/h2&gt;

&lt;p&gt;The original weather bot counted forecast members. It pulled raw output from four systems: GFS, AIGEFS, ECMWF IFS, and AIFS. Up to 164 individual simulations per contract. The logic was simple. If at least three of four systems agreed on direction, the bot traded. If they disagreed, it sat out.&lt;/p&gt;

&lt;p&gt;That sounds reasonable. It was not.&lt;/p&gt;

&lt;p&gt;I ran 112 settled trades through the system and scored the model with a Brier score. The model scored 0.2858. Predicting the historical base rate, with no model at all, scores 0.2439. Lower is better. My model was worse than making no prediction.&lt;/p&gt;

&lt;p&gt;The problem was not direction. Direction was right about 60 percent of the time. The problem was confidence. The model spread its probabilities 2.1 to 4.0 times too narrow. It was certain when it should have been uncertain. In prediction markets, confidence sizes your bets. A model that is too confident trades too big on the wrong calls. The confident wrong calls cost more than the confident right ones made.&lt;/p&gt;

&lt;p&gt;There was also a systematic temperature bias at the gridpoint level, peaking around seven degrees Fahrenheit. The model leaned warm in a way that was not in the data. It was in the model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I should have done first
&lt;/h2&gt;

&lt;p&gt;Before building anything, I should have checked whether the thing I was building already existed in better form.&lt;/p&gt;

&lt;p&gt;NOAA publishes the National Blend of Models. It blends dozens of forecast systems and applies statistical post-processing no individual model can match. It produces calibrated, bias-corrected, station-level probabilistic temperature guidance. For exactly the stations Kalshi settles on. For free.&lt;/p&gt;

&lt;p&gt;The NBM already does what I was trying to do by hand. It corrects the biases I was measuring. It produces uncertainty ranges I was approximating with member counts. It runs at individual station level, not gridpoint level, which eliminates the seven-degree bias problem entirely.&lt;/p&gt;

&lt;p&gt;I spent months tuning a member-counting approach when the right answer was a public product I could have downloaded at any time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why member counting was the mistake
&lt;/h2&gt;

&lt;p&gt;Counting ensemble members is seductive. It feels like rigor. You are comparing 164 independent forecasts. That has to be better than one.&lt;/p&gt;

&lt;p&gt;It is not. The members are not independent in the way that matters. They share systematic biases. If GFS runs warm, all 31 GFS members run warm. If ECMWF has a marine layer problem at LAX, all 51 ECMWF members have the same problem. Agreement across members of the same model tells you the model is internally consistent. It does not tell you the model is right.&lt;/p&gt;

&lt;p&gt;The NBM solves this at the source. It does not count members. It uses statistical post-processing to calibrate each model against observed outcomes at each station. The output is not a vote. It is a calibrated probability distribution with honest uncertainty ranges.&lt;/p&gt;

&lt;p&gt;The difference between "164 forecasts agree" and "one calibrated probability distribution" is the difference between confidence and calibration. My ensemble was confident. The NBM is calibrated. In prediction markets, calibrated is what makes money. Confident is what loses it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the rebuild looks like
&lt;/h2&gt;

&lt;p&gt;The v2.5 weather bot runs on NBM as the primary source. NBM weight is 0.75. Five raw models sit behind it at a combined 0.25 weight as a disagreement check: GFS, AIGEFS, ECMWF IFS, AIFS, and HRRR. They used to be the model. Now they are a sanity check on the model.&lt;/p&gt;

&lt;p&gt;The bot scans 291 weather series across 20 cities. The old scanner asked for category "Climate" when the real value was "Climate and Weather." It matched nothing. A fallback scanned the raw catalogue and every log line looked normal while the bot saw 39 to 63 of 291 series. That is fixed.&lt;/p&gt;

&lt;p&gt;NBM coverage begins at forecast hour 24. Same-day markets are inside that window. Rather than fall back to the old model that lost money, the bot skips same-day markets entirely. It does not price what it cannot price.&lt;/p&gt;

&lt;p&gt;This costs candidates. A trade that does not get opened is a trade that does not generate a return. That is the point. The most important thing a trading system can do is refuse to act when the conditions it trusts are not present.&lt;/p&gt;

&lt;p&gt;Chicago settles on Midway, not O'Hare. Houston on Hobby, not Bush. San Antonio's ticker reads SATX but the climate product is issued as SAT. Every station is pulled from Kalshi's own metadata and pinned in a test suite that runs 426 tests across 33 files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this stands
&lt;/h2&gt;

&lt;p&gt;The weather bot is rebuilt and undergoing validation. There are zero settled trades under the v2.5 model. The last trade under the old model settled August 7. v2.5 shipped August 9. Nothing has been measured.&lt;/p&gt;

&lt;p&gt;Forecast quality can be assessed in roughly two weeks once daily verification runs accumulate. Whether the strategy makes money needs 100 or more completed trades, which is four to six months at current rates.&lt;/p&gt;

&lt;p&gt;I am not going to tell you the new model performs because I do not know. I will publish what I find when I find it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The lesson that transfers
&lt;/h2&gt;

&lt;p&gt;The lesson is not about weather models. It is about checking whether the thing you are building already exists in more rigorous form before you build it.&lt;/p&gt;

&lt;p&gt;I assumed the right approach was more data, more models, more members. The right approach was less data, better processed, by an organization that has been doing this longer than I have. NOAA's National Blend of Models is not a secret. It is published. It is free. It is better than what I built.&lt;/p&gt;

&lt;p&gt;The instinct that cost me four months was the builder's instinct. I wanted to build it myself. I wanted to understand it from the ground up. That instinct is valuable. It is also expensive when the public good already exists.&lt;/p&gt;

&lt;p&gt;The fix was not a cleverer model. It was the humility to use one that was already done.&lt;/p&gt;




&lt;p&gt;Predict &amp;amp; Profit is a $75 one-time source-code package. Two Kalshi bots, a dashboard, and the full Python source. Discount code HOME15. The public results ledger is at predictandprofit.io/results. This is software, not financial advice. Prediction-market trading involves real risk of loss.&lt;/p&gt;

</description>
      <category>python</category>
      <category>datascience</category>
      <category>ai</category>
      <category>automation</category>
    </item>
    <item>
      <title>I Audited My Trading Bot Using a Brier Score. It Had No Skill.</title>
      <dc:creator>Steve Farmer</dc:creator>
      <pubDate>Wed, 12 Aug 2026 00:26:08 +0000</pubDate>
      <link>https://dev.to/predictandprofit/i-audited-my-trading-bot-using-a-brier-score-it-had-no-skill-be4</link>
      <guid>https://dev.to/predictandprofit/i-audited-my-trading-bot-using-a-brier-score-it-had-no-skill-be4</guid>
      <description>&lt;h1&gt;
  
  
  I Audited My Trading Bot Using a Brier Score. It Had No Skill.
&lt;/h1&gt;

&lt;p&gt;I ran a weather trading bot on Kalshi for four months. 112 settled trades. Then I tore it apart with a proper scoring rule. The result was worse than doing nothing.&lt;/p&gt;

&lt;p&gt;A Brier score of 0.2858 against a base-rate baseline of 0.2439. My model was subtracting information from reality.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a Brier score tells you that win rate does not
&lt;/h2&gt;

&lt;p&gt;Win rate said the model was directionally right about 60 percent of the time. That sounds fine. But a Brier score decomposes into calibration and refinement. It showed the model's probabilities were spread 2.1 to 4.0 times too narrow.&lt;/p&gt;

&lt;p&gt;In plain terms: the bot was confident when it should have been uncertain. And in prediction markets, confidence sizes your positions. A model that is too sure trades too big. Direction can be right 60 percent of the time and you can still lose money.&lt;/p&gt;

&lt;p&gt;The second mechanism was a systematic temperature bias at the gridpoint level, peaking around seven degrees Fahrenheit. The model leaned warm in a way that was not in the data. A larger position on a biased forecast destroys whatever edge the directional signal might have provided.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix was not a cleverer model
&lt;/h2&gt;

&lt;p&gt;NOAA's National Blend of Models already publishes calibrated, bias-corrected, station-level probabilistic temperature guidance for exactly the stations Kalshi settles on. For free. I was hand-rolling a worse version of a public good.&lt;/p&gt;

&lt;p&gt;The bot was counting ensemble members across raw forecast systems. The NBM blends dozens of models and applies statistical post-processing no individual system can match. The uncertainty ranges come baked in. The bias correction runs at individual station level.&lt;/p&gt;

&lt;p&gt;I spent months tuning a member-counting approach when the right answer was published by a government agency I could have downloaded at any time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The test suite that caught everything the old one missed
&lt;/h2&gt;

&lt;p&gt;The rebuild ships with 426 tests across 33 files. The old suite was smaller and missed a lot.&lt;/p&gt;

&lt;p&gt;The scanner had been looking for Kalshi category "Climate" when the real value was "Climate and Weather." It matched nothing. A fallback scanned the raw catalogue, and every log line looked normal while the bot saw 39 to 63 of 291 available series. The count changed between runs, so entire cities blinked in and out for four months.&lt;/p&gt;

&lt;p&gt;Chicago settles on Midway, not O'Hare. Houston on Hobby, not Bush. Every station code is now pulled from Kalshi's own metadata and pinned in a test.&lt;/p&gt;

&lt;p&gt;Three money bugs shared the same shape: the daily-loss kill switch reads settled P&amp;amp;L, so a mis-recorded trade silently moved the limit. Partial fills never settled. Weather P&amp;amp;L was booked gross of fees. The econ bot never recorded a position it closed. All three are fixed, and the fixes touched the ledger.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters if you are building a model
&lt;/h2&gt;

&lt;p&gt;Brier-score your model before you trade it. The baseline is always predicting the historical base rate. If your model scores worse than that, it is subtracting information and you would be better off flat. Directional accuracy is not enough. Confidence calibration is what determines position sizing, and position sizing determines whether you survive.&lt;/p&gt;

&lt;p&gt;The rebuild is on NOAA's NBM now. Same-day markets are skipped because NBM coverage starts at forecast hour 24. Rather than fall back to a model that lost money, the bot declines. That costs candidates. The most important thing a trading system can do is refuse to act when the conditions it trusts are not present.&lt;/p&gt;

&lt;p&gt;Zero settled trades under the new model. The last trade settled August 7. The new version shipped August 9. Forecast verification needs about two weeks. Strategy evaluation needs 100 or more trades, which is four to six months. I will publish what I find.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The full audit, including the bug stories and the NBM rebuild, is at &lt;a href="https://stfarm.substack.com/p/i-audited-my-own-trading-bot-and" rel="noopener noreferrer"&gt;stfarm.substack.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>datascience</category>
      <category>testing</category>
      <category>automation</category>
    </item>
    <item>
      <title>We Turned Down Google's AI Weather Model</title>
      <dc:creator>Steve Farmer</dc:creator>
      <pubDate>Fri, 07 Aug 2026 02:01:44 +0000</pubDate>
      <link>https://dev.to/predictandprofit/we-turned-down-googles-ai-weather-model-1blc</link>
      <guid>https://dev.to/predictandprofit/we-turned-down-googles-ai-weather-model-1blc</guid>
      <description>&lt;p&gt;Google released a weather model earlier this year that beats the best forecast in the world 97% of the time. Free. Clean API. Drop-in compatible with what we already run.&lt;/p&gt;

&lt;p&gt;Every data engineering instinct I have said: adopt this immediately.&lt;/p&gt;

&lt;p&gt;I spent one afternoon testing it instead. We declined to ship it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we actually measure
&lt;/h2&gt;

&lt;p&gt;Kalshi temperature contracts settle on one number: the official daily high temperature at a specific airport, reported by NOAA. Not the mean. Not the overnight low. The daily high.&lt;/p&gt;

&lt;p&gt;Our entire edge, if we have one, lives or dies on the accuracy of one number, at one station, for one 24-hour window.&lt;/p&gt;

&lt;h2&gt;
  
  
  The test
&lt;/h2&gt;

&lt;p&gt;I pulled WeatherNext 2 forecasts for 16 Kalshi settlement stations over two weeks and compared against NOAA observed highs. Then against the models we already run.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Mean Error (°F)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GFS&lt;/td&gt;
&lt;td&gt;+0.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECMWF IFS&lt;/td&gt;
&lt;td&gt;-0.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ICON&lt;/td&gt;
&lt;td&gt;-0.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GEM&lt;/td&gt;
&lt;td&gt;-0.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WeatherNext 2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-5.2&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Minus 5.2 degrees Fahrenheit, cold, on the exact temperature type our contracts settle on.&lt;/p&gt;

&lt;p&gt;Kalshi temperature contracts span 2-3 degree ranges. A 5.2°F cold bias does not introduce noise. It systematically points to the wrong contract on almost every trade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this happens
&lt;/h2&gt;

&lt;p&gt;WeatherNext 2 is benchmarked primarily on 500hPa geopotential height, wind fields, and mean 2-meter temperature. Daily maximum 2-meter temperature is a different problem. It depends on the planetary boundary layer, local surface energy balance, urban heat island effects, and the specific observing conditions at individual ASOS stations.&lt;/p&gt;

&lt;p&gt;WeatherNext was built for global forecast skill. We need local daily-high accuracy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The nuance
&lt;/h2&gt;

&lt;p&gt;WeatherNext's spread — its estimate of its own uncertainty — is roughly twice as well calibrated as the model we run today. That part is genuinely valuable and stays on the roadmap.&lt;/p&gt;

&lt;p&gt;We're not anti-AI. We're anti-assumption.&lt;/p&gt;

&lt;h2&gt;
  
  
  The lesson
&lt;/h2&gt;

&lt;p&gt;The industry ships the shiny thing and calls it innovation. What almost nobody does is measure the shiny thing against the specific problem they are actually solving, find the gap, and say no.&lt;/p&gt;

&lt;p&gt;Anyone can adopt a model. Knowing when not to is the actual skill.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I built this system after 30 years as a data engineer. The forecast is easy. The honesty is hard.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>datascience</category>
      <category>automation</category>
      <category>ai</category>
    </item>
    <item>
      <title>Most weather traders check one app. My bot reads 164 forecasts.</title>
      <dc:creator>Steve Farmer</dc:creator>
      <pubDate>Mon, 01 Jun 2026 01:06:46 +0000</pubDate>
      <link>https://dev.to/predictandprofit/most-weather-traders-check-one-app-my-bot-reads-164-forecasts-28o0</link>
      <guid>https://dev.to/predictandprofit/most-weather-traders-check-one-app-my-bot-reads-164-forecasts-28o0</guid>
      <description>&lt;p&gt;I am a data engineer 30 years in and I trade weather contracts on Kalshi as a hobby. For a while I did it the way everyone does. Check a forecast app pick a side and hope. Then it hit me that the market price is just that same single forecast everyone else looked at.&lt;/p&gt;

&lt;p&gt;When Kalshi prices a temperature contract it is pricing whatever the average trader believes after glancing at one app. A weather ensemble does NOT work that way. The GFS runs 31 simulations from slightly different starting conditions. ECMWF runs 51. The newer AI ensembles NOAA AIGEFS and ECMWF AIFS add more. My bot pulls all four at once up to 164 independent forecasts for the same city and day.&lt;/p&gt;

&lt;p&gt;Then it counts. If 118 of 164 members clear the threshold that is a 72% model read. If the market is at 40 cents that gap is the trade. It only fires when at least 3 of the 4 forecast families agree. Most scans produce zero trades. That is the design working NOT a bug.&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%2F93o7e73dbafrc16o1oxn.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%2F93o7e73dbafrc16o1oxn.png" alt=" " width="800" height="655"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It all runs on my RackNerd VPS on Ubuntu, logs every decision to SQLite, and the data sources are free.&lt;/p&gt;

&lt;p&gt;What's everyone else here building? I'd like to hear what bots you run and where they fight you the most. For me the boring parts, fills and accounting, have been way more trouble than the model ever was.&lt;/p&gt;

</description>
      <category>python</category>
      <category>kalshi</category>
    </item>
  </channel>
</rss>
