2 pointsby qkwrv3 hours ago1 comment
  • qkwrv3 hours ago
    I know I say it in the title, but I want to be very clear up front: the predominant output of this tool is "don't place this bet."

    Betting apps want you to bet. If they sense you are tired of losing and might leave, they'll entice you with deposit bonuses, boosted odds and protected picks. There are even people, you see them self-promoting all over X, who sell access to "good" bets. Obviously, they don't refund you if you lose. What the market needed was a way to cut through the noise and the boosted odds and the FOMO and just tell you, based on historical data and known circumstances (weather, recent form), whether this is a good bet.

    NegativeEV is really two completely different pieces of software: the model and simulation engine and then the frontend and grading logic that sits on top of it. That first piece was far and away the hardest. I'm an enterprise software developer by profession, not a data scientist, so my path to what I consider a very solid model and architecture was full of really, really wrong turns.

    I started with Major League Baseball. The way it works now is it takes a decade of pitch-by-pitch historical data, comprising about 450 data points in each row (I put in a ton of historical priors), and it builds a PyTorch model targeting the exact pitch result: strike, ball, foul, single, double, etc. The simulator (built in Rust) then takes that model (converted to ONNX) and simulates an entire baseball game. I also have models for pitching changes and position-player substitutions. The end result of a simulation is one "realistic" baseball game, box score and all. Then I do that 5,000 times. Those are the simulations that I use to calculate "fair value" when evaluating someone's proposed wager. If anyone is curious why I bother with the ONNX conversion, it's so the Rust simulator can run the model itself, with no Python in the loop. I'm doing almost all of this on my personal desktop, with some use of Modal to magically spin up VMs when I really want things to fly (Modal is awesome, btw).

    I knew I had to make this as frictionless as possible for users, since no app would ever want to integrate with me. So I have what I'm referring to as two frontends: I have negativeev.com, and then I have a bot on X. Users can tag @shoulditail under any tweeted-out wager, and my bot will consult the simulation results and return the Expected Value of the bet. Again, it's mostly negative.

    For negativeev.com, I tried to model the frontend after the chat-interface frontends we're so used to now thanks to LLMs. Not that users can chat. More that I needed it to be able to handle any form in which the user wants to communicate their bet. The easiest is pasted screenshots. On mobile, this is really easy. But users could also just type "Aaron Judge over 0.5 home runs +150", and we'll parse that out and give you what we think is the EV.

    I also, on a whim, put an MCP server around it. I'm skeptical it will ever get used, but my thought was how cool would it be if LLMs could reach out to it when users asked if such-and-such play was a good wager that day. Not that LLMs should get into the business of supporting gambling, but at the very least they could consult my backend and come back with some insight into why a bet is probably not a good idea (and maybe just ignore it if it was returned as positive EV).

    So there you have it. This is my first time ever releasing something into the wild like this. There's far more to the story and far more tech details I'd be happy to talk about.

    • janraketean hour ago
      It would be even better if your tool could predict every bet correctly. If everyone could win every bet, then the problem of gambling addicts and the companies that take advantage of them would be quickly solved.

      But your solution is cool, too.

      • qkwrvan hour ago
        Funny enough, this was sort of my north star when developing it. I know it's an impossible dream or expectation (predicting sports is extremely hard), but it's very true that this tool is really only as useful as it is correct.

        My first iteration of the baseball model took this to an extreme. I broke down every single step from the pitcher deciding which pitch to throw to the pitcher deciding where to throw it to the pitcher throwing it at a certain speed in a certain spot, and on and on. It was something like 17 sequential PyTorch models. My directive to myself was to not care how much compute it would take to run, just get it to the most right version it could possibly go.

        Turns out just predicting the end result of each pitch is far more accurate than sequential modeling. I still to this day have a hard time believing it. But the results are pretty stark when I compare the two methods.

        Anyway, I really appreciate the kind words and for taking the time to check it out.