u/PolyResearchRobotics

Using Orderbook Imbalance (OBI) for Polymarket Arbitrage Bots

Using Orderbook Imbalance (OBI) for Polymarket Arbitrage Bots

Hey all. I've been working on an arbitrage strategy for Polymarket's 5-minute crypto up/down markets and after the move to TWAP settlement earlier this month, I've been reevaluating what indicators are best to trigger trade signals within my bot. I wrote this artwork for the members over at Poly Research & Robotics and figured I would share it too incase it helps anymore.

Order-book imbalance is the indicator/signal that my arb bot fires on. We compute it from Binance's order-book depth feed and use it to decide when to open a position on the Polymarket contract, which is a detail worth stating up front because it turns out to matter more than anything else here.

To find out what the indicator is actually worth, we pulled a month of full-depth books, roughly 52,000 markets and 13 million seconds of order book. That tape is from April, which puts it squarely in the old settlement regime. For this particular indicator that matters less than you might expect, because order-book imbalance describes what the book is doing inside the cycle rather than how the market eventually resolves, and the mechanism behind it has nothing to do with settlement. Anything specific to the closing minute is a different story and should be treated with suspicion until somebody re-runs it on post-TWAP data.

The short answer on the indicator itself is that it gives you around 1-1.5 seconds of warning before the price moves on polymarket (it ranges quite a bit).

WHAT OBI IS:

Order-book imbalance is a single number describing how lopsided the order book is.

An order book is really just two queues: the people waiting to buy on one side, and the people waiting to sell on the other. OBI compares how big those two lines are. A book made up entirely of buyers reads +1, a book made up entirely of sellers reads -1, and a balanced book reads zero. It counts the shares waiting at each level and never looks at prices.

You can run the same calculation on any order book you can get depth for. Ours runs on Binance's book for the underlying coin, because that is where the size and the price discovery are. The alternative is to run it on Polymarket's own book for the contract you are trading, and the difference between those two choices is the single most important decision in this whole setup. More on that below.

Here is a real Polymarket book from the tape, taken from an ETH market on april 12:

bid  0.33   456.87 shares
ask  0.35     5.00 shares      OBI +0.80

There were 456 shares trying to get in against 5 shares willing to sell to them. One second later the offer had been cleared, the price had moved three and a half cents, and the imbalance itself had already halved.

That is the entire mechanism. An extreme reading is not a forecast in any deep sense; it is a statement that one side of the book is about to run out. Once the thin side gets cleared the price moves by construction, and the imbalance that predicted the move is consumed in the same instant.

This also explains a property that catches people out, which is that OBI is not a trend indicator. Measured against the price change at every offset around the reading, the correlation is negative at every point before it. The lopsided book appears after price has been pushing the other way, rather than before it. If you are using OBI to confirm a trend, you are using it backwards.

HOW MUCH WARNING YOU GET:

https://preview.redd.it/sxergiufw9kh1.png?width=2400&format=png&auto=webp&s=66843abcaaef90892718b5eaee49fd44d92b97cb

https://preview.redd.it/93y4p4dhw9kh1.png?width=2400&format=png&auto=webp&s=3e39a6721823554314068102eb48fe462f0e0c6a

Once the order book tips heavily to one side, how long is it before the price on Polymarket actually moves?

the short answer is that you get about two seconds of useful warning, and the whole effect is spent inside fifteen.

the clearest way to see it is to follow a single spike forward in time. Each figure below is the share of spikes that had produced a full one-cent price move by that point, either in the direction the imbalance was leaning or against it.

After 1 second, 36% of spikes have already produced a one-cent move in the predicted direction, against only 10% that have moved a cent the other way. This is the point at which the relationship between the imbalance and the price is at its strongest, and nothing that happens later is anywhere near as clean.

After 2 seconds, 44% have moved a cent in the predicted direction and 16% have moved against it. Starting from a randomly chosen second instead of a spike, the equivalent figure is 19%. Counting only the spikes that produce a move at all, the typical wait is two seconds, where from a random starting point the same wait runs to eight.

after 5 seconds, 56% have moved in the predicted direction and 29% have moved against it. This is the widest that gap ever becomes, and it narrows steadily from here.

After 7 seconds, the imbalance reading has decayed to half its original strength. The book you measured has largely been traded away by this point.

These measurements are obviously specific to this one moment that I'm featuring here for this article, but you get the idea. Many times the signal has decayed much quicker than 7 seconds. This example is an extreme imbalance.

HOW TO PUT IT IN YOUR BOT:

https://preview.redd.it/sumzd5a42akh1.png?width=2400&format=png&auto=webp&s=b7450b7392f4ec77808a9559537d6d2a4920a683

https://preview.redd.it/ujollt152akh1.png?width=2400&format=png&auto=webp&s=ef2b285f6e149000a8cd4f9e8334ee39d30fc565

The calculation is small. This is the version I run:

n = min(10, len(bids), len(asks))

bidW = sum(bid_size[i] * (n - i) for i in range(n))
askW = sum(ask_size[i] * (n - i) for i in range(n))

obi = (bidW - askW) / (bidW + askW)     # -1 to +1

Take the top ten levels of each side, weight them so the front of the queue counts heaviest, and then compare the two totals. Use the resting sizes only and never the prices they sit at. Every reading is computed fresh from a single snapshot, with no memory of the one before it.

The way you set up your config and what OBI values trigger different actions in your bot make a world of difference. Similar to any betting model, it's all about how you weight the data that makes the difference, not the data itself.

For me, I'm building an arbitrage trading bot on the polymarket up / down crypto markets, so I am using this signal to trigger a buy on one of the sides (mostly the dominant side for my opening trade of the pair) and then once the polymarket price catches up the OBI we observed on Binance, then we capture the other site for a share price that is within range for a profitable pair to be captured.

EXAMPLE:

  1. Observe OBI +.8 (we see that way more people are trying to buy than sell...)
  2. Bot purchases Up share at .60 a share (down is currently .40/.41)
  3. OBI evens out, buyers get in, price moves up...
  4. Down share price drops to .35, and we buy for a captured spread of 5% on the money we deployed into that pair.

now keep in mind, this isn't perfect and I'm still deep in development but I wanted to share this technique because it's been by far the most helpful and reliable indicator/signal for successfully capturing these pairs, and if you've build arbitrage bots before you know it's incredibly hard to main consistent pair accumliation.

If you're interested in polymarket trading bot development, and you're working on something similar...join us over at Poly Research & Robotics. We're a 1,500+ member free community dedicated to developing trading bots and strategies. We offer free guides, free trader reports, and polymarket historical data of many market categories that you can use to test out the above mentioned OBI (or use it to backtest any strategy you're working on).

If you have any tips or suggestions please leave them in the comments!

u/PolyResearchRobotics — 20 hours ago

Polymarket moved 5-minute crypto to a 60-second TWAP. Here's what we found from our TWAP-adjusted dataset

Polymarket has changed crypto up/down settlement twice in a week. On August 7th, it stopped settling on a single closing price and moved to a time-weighted average. Last night it changed again: 5-minute markets went from a 30-second window to a 60-second one.

Every crypto up/down market now settles on the average price across its final 60 seconds.

IF YOU HAVE NOT DEALT WITH A TWAP BEFORE

The old rule took the coin price at one instant, the moment the market closed, and compared it to the open. One number. The new rule averages the final 60 seconds and compares that. Sixty numbers.

The part people get wrong is thinking this runs at the close. It does not. It is a separate Chainlink feed publishing continuously on a rolling window, with its own topics on Polymarket's socket. At any second there is a live TWAP value, each one the average of the 60 seconds behind it. Settlement just reads that feed at second 300.

https://preview.redd.it/3z63liaxwajh1.png?width=3840&format=png&auto=webp&s=89b6652f1f33d4fd072527b51afc89cdc295a063

One randomly chosen BTC cycle. Grey is the price as it printed, blue is the same price as a rolling 60-second average.

Blue is smoother, obviously. It also lags: watch the dip around 200 seconds and the run-up after. Measured by cross-correlation across six coins, the 30-second window trailed spot by 16 seconds and the 60-second one trails by 30. The doubling doubled the lag. Across 3,190 live cycles the 60-second feed moves 19 percent as much as spot second to second, against 29 percent before.

So there are two prices now: the one on your screen, and the one that settles your market, half a minute behind it.

WHAT IS BETTER FOR TRADERS

At Poly Research & Robotics, we have been logging both Chainlink feeds (every tick) since before launch and rebuilt when PM offered the dev preview of the feed, and we've rebuilt our historic datasets against the new rule. So what makes TWAP better or worse for traders?

  • Manipulation costs more. It's still possible, but this has definitely hindered it, or delayed it.
  • You get more time to read direction. The settling number is a lagging average, so it telegraphs itself.
  • The gap between CEX order flow and Polymarket's reaction has been modified. Existing indicators or bots that were trading off indicators such as OBI values might not be as efficient as they were pre-twap.
  • And the honest one: a lot of running bots are now wrong. Plenty of strategies were built to profit from exactly the erratic last-second behaviour this removes. Anything keyed on spot at the close, or sized around end-of-cycle wick risk, is modelling a rule that no longer exists.

OUR COMMUNITY MEMBERS BUILT AN INDICATOR

Some of our members in our free discord built an indicator for their expiry sniping trading bots that had three feeds stacked. The coin price from Binance. The 60-second TWAP on top of it. And the one that matters: the live price the coin would actually have to reach to drag the settlement average across the open.

trigger = (60 * open - sum of the locked seconds) / seconds remaining

Once the window opens, every second that prints is locked forever, so the seconds still to come carry all the remaining work.

Say the open is 61,000 and the price sits there for 40 seconds, then slips to 60,980. With ten seconds left the trigger is not 60,980 or anything near it. It is 61,020. The locked seconds already dominate the average, so the coin would have to rally above the open to flip the result, not fall further. That inversion is the whole reason this is worth tracking.

https://preview.redd.it/7t0wdf2kyajh1.png?width=3840&format=png&auto=webp&s=ee0030223f516deb6203a399af4fb4470342cc54

They took the historical datasets we offer for free inside of our Poly Research & Robotics discord and modeled a live realtime view of what the price needs to drop to, for the cycle to reverse. This gives added insight into the true probability of a last second reversal on the crypto up/down markets.

WHAT TWAP DOES TO LATE-CYCLE REVERSALS

https://preview.redd.it/pky4co9yyajh1.png?width=3840&format=png&auto=webp&s=9f34c7dc08aad5254da27c75ebf87d2fed3a3d72

This is real BTC cycle from 23 July. The horizontal line is the open, black is the coin price the old rule read at the close, blue is the 60-second average.

With fifteen seconds left Up was trading at 96 cents. The price then fell, crossed the open with seven seconds to go, and closed 1.9 basis points the wrong side. Under the old rule that single tick settles it, so Down won and every Up holder was wiped. Blue never leaves the upper band, closing 4.5 basis points above the open and never getting closer than 2.6.

How often that matters, from our June archive, by distance from the open with ten seconds left. Under 1 basis point: 34.6 percent reversed before, 9.2 percent now. Between 1 and 2 bp: 22.9 down to 3.9. Between 5 and 10 bp: 1.3 down to 0.1. Beyond 10 bp it was near zero either way.

If you were comfortably ahead this changes nothing; you were already safe. The entire benefit lands within a basis point or two of the open, which is exactly the population worth attacking.

If you enjoyed reading this and you're developing Polymarket trading bots, check out Poly Research & Robotics. We are a dedicated community of almost 1500 active members that are collaborating, sharing insights, and building trading bots and strategies together. We offer resources, guides and tools for all members.

u/PolyResearchRobotics — 6 days ago

Chinese Horse Betting, E-Sports, and Polymarket...OH MY!

Bill Benter is probably the most successful sports bettor who ever lived, and he did it with pure math. He was betting on Hong Kong horse racing in the 80s and 90s. the tricky thing about racing there is that you are not betting against a bookie you can outsmart, you are betting against one giant shared pot of everyone else's money, and the track quietly skims about 17 cents off every dollar before anyone gets paid. so making money is not about picking winners. it is about being more right than the entire crowd, by a wide enough margin to beat that 17% tax. almost nobody can do that. Benter built a computer model that could.

https://preview.redd.it/ve5i5lv7ql9h1.png?width=1815&format=png&auto=webp&s=c1f3c7c761d8a0d6180461b4eeeec5598812b6f1

his whole approach came down to three simple ideas:

  • use the crowd, do not fight it. he took the public's own betting odds and fed them into his model as one of its most important ingredients. the crowd is mostly right, so he started from their answer and improved on it.
  • only bet when you actually disagree. he placed a bet only when his model thought a horse's real chance was clearly better than the price everyone else was offering. no disagreement, no bet.
  • bet bigger when you are more sure. the bigger the gap between his number and the crowd's price, the more he put down. small edge, small bet. big edge, big bet.

he ran that fully automated, across hundreds of thousands of bets, and reportedly walked away with close to a billion dollars.

Okay, so what does a horse racing legend have to do with Polymarket?

Wellll..... one of the members in my community submitted a wallet called BillBenter2026 in for a trader report, and when I looked into the profile, I realized the name is not a coincidence. it is a bot, fully automated, that trades sports and esports markets around the clock. and when you pull apart what it is actually doing, it is running the real Bill Benter's exact playbook, just on Polymarket instead of the racetrack. here are some of the the PM traders stats:

  • around 890k trades in the 27 days of logs i pulled, across about 10k+ different markets, roughly $15M of volume, for a net profit of about +$97k
  • on about 80% of its markets it buys BOTH sides, the yes and the no. on the surface that looks like plain market making, just quoting both sides and pocketing the spread

Here is the twist though: that both-sides buying actually loses money. normally, if you can buy both sides of a market for less than a dollar total, you lock in a tiny risk-free profit. this bot does the opposite. its two sides cost about $1.03 together for every $1.00 they can pay out, so the both-sides part is bleeding, somewhere around $288k over the month. that sounds insane until you realize it is not trying to make money there. the smaller opposite-side bet is insurance. it keeps the bot covered on the games its model gets wrong, and it gets plenty wrong. paying that little 3-cent premium is what lets it bet big on the side it likes without one bad night wiping it out. the real profit comes from somewhere else.

And this is the part that proves there is a real brain behind it. the bot does not split its money evenly across the two sides. when it likes a side, it loads up on it. so i grouped its markets by how lopsided the bet was, from a slight lean all the way to all-in, and then checked how often the side it favored actually won:

  • when it barely leaned, its pick won about 54% of the time, basically a coin flip
  • when it leaned harder, that rose to about 58%, then 61%
  • when it went all-in on a side, that side won about 73% of the time

that climb is the whole story. a bot that was just guessing would win around 50% whether it bet big or small. this one wins more the harder it bets. that leads us to believe it is running its own model locally, something that scans the markets, spots where Polymarket's price is wrong, and scales the bet size up to match how big it thinks that mispricing is. small edge, small bet. big edge, big bet. that is Benter's third rule, bet bigger when you are more sure, showing up right there in the data.

https://preview.redd.it/n0czyuiqsl9h1.png?width=2160&format=png&auto=webp&s=08d07846bc22f43a52daa72db8686ecffb8e3ff0

Here is the parallel in one picture, and to be clear this is our hypothesis, not something the logs prove. we can only see the bot's bets, not the model behind them, so this is our read on why it works. Benter would spot a horse the crowd had priced at 10-to-1, decide his model made it more like 5-to-1, and bet it hard, because the crowd had it too cheap. the bot looks like it is doing the identical thing on Polymarket. say it sees a League of Legends team trading at 60 cents (the market calling it about a 60% chance to win), and its own model says that team is really closer to 75%. that 15-point gap would be the green light, so it loads up on that side and only lightly covers the other. same move, just a video game instead of a horse: find a price the crowd has wrong, then bet it in proportion to how wrong it is. that is our best guess at the why, anyway.

https://preview.redd.it/ve8gb8essl9h1.png?width=2160&format=png&auto=webp&s=7ac1fc07eb5b1eefd228cef6253269f284141116

And where does it make the most money? esports. it trades everything, NBA, soccer, tennis, but the standout is esports, League of Legends, Counter-Strike, Valorant. single matches there made it +$8k to +$12k each on only a couple hundred trades (one Dplus KIA vs KT Rolster League of Legends game alone was about +$13k). my guess at why: esports is the perfect target for a model like this. there is a ton of structured history to learn from, the big leagues like the LCK, LEC and LPL have years of match data, but the betting is thinner and softer than NBA or soccer, where every pro is already grinding the prices razor-sharp. so a good model gets paid a lot more per game on a League match than it would on an NBA game. that is the exact same thing Benter did, find the corner of the market the smart money has not bothered to sharpen up yet, and clean it out.

https://preview.redd.it/scmqsi4usl9h1.png?width=2160&format=png&auto=webp&s=2ee3706e6a2d6264a447aa00c1ec7749bb7c5c6e

Thanks for reading, this was probably one of the most interesting posts I've worked on. Learning about the similarities between them, although not 1 to 1 (after all it's polymarket vs 1980's horse racing) was actually really surprising to me. Hope you enjoyed it as well.

If you found this interesting and want to read more or share your results from this method, join us at Poly Research & Robotics, we're a free community 1,000+ members all building trading bots and applications for prediction markets. We have guides, tutorials, and free historical data for you to use for backtesting or planning out your next project.

👉 https://discord.gg/BU9EjyqesV

u/PolyResearchRobotics — 2 months ago

Comparative Iteration: Improving Your Bot by Learning From Wallets That Already Win

This is a method that I've been using lately on when developing a bot that trades the crypto up/down markets. I've been developing an arbitrage bot that captures both sides of each cycle with a cumulative share price under $1. This method can be applied to many different strategies, but works best with strategies that have recognizable patterns, and receptive market cycles.

One of the trickiest parts of running an arb strategy is handling runaway markets, where one side takes the lead early and steadily climbs through the cycle, making it hard to capture both outcomes and keep a locked cycle P/L.

So I started finding other wallets running the same strategy. I downloaded their logs, validated the outcomes for each cycle, and vetted that they were in fact running the strategy I'm trying to build.

https://preview.redd.it/em1wse0b8e9h1.png?width=1408&format=png&auto=webp&s=15701c8374fe0c46e594631a8b3b46eee7ceaeab

Once I had a list of 3 other wallets that were profitably trading these cycles, I then built a monitoring engine that ran alongside my bot. I subscribed to each of these traders trading activity via a websocket directly through Polymarket's api and began logging all activity from them, and my own bot.

Then, I set up a cronjob all within claude code to run every hour and evaluate all of the markets that my bot was not profitable, against the logged other traders.

Overall, it's a simple method, but giving the coding agent a realtime context stream produced suggestions I hadn't thought of, or hadn't gotten from the agent otherwise.

https://preview.redd.it/i9ns31wa9e9h1.png?width=1608&format=png&auto=webp&s=a0b475e1cd294e70f562d5893cb0632debafe803

One of the keys to meaningful suggestions from this method is context...many successful bots on polymarket are running their own models offline, those kinds of things aren't exactly visible through the logs...however you can build systems to reverse engineer what kinds of other decision making logic is factoring in. To do this, you need to provide your agent with all data inputs that any other trader will have, these things can include CEX orderbook sockets to track order flow, price streams, of course the polymarket price/order book as well. ou can even integrate a few indicators on the underlying coin price, leave those values variable, and have the agent evaluate what values would've better informed your bot's logic each hourly iteration.

https://preview.redd.it/g6i7evab9e9h1.png?width=1608&format=png&auto=webp&s=b80c916173c8b5e6273a76bd0788cc8c1459ba2a

HOW TO GET GOOD SUGGESTIONS:

how you point the coding agent at this matters more than which model you use. ask it 'how do i make my bot better' and you get generic filler, it has no way to know what actually wins these markets. you get useful output only by handing it checkable work:

  • Give it as much data and context as you can, and make sure the evaluation agent has documentation explaining everything you're logging.
  • Have the model cite the specific scenario(s) that triggered each suggestion. If it can't point to the exact gap that produced a suggestion, that's a red flag. This keeps the model focused on the situations where your bot was actually lacking efficiency.
  • Change one thing at a time. Have it rank the suggestions by impact, and get creative with how you score them based on what matters most to fix in your bot.
  • When you start implementing, pick one suggestion at a time and stay on top of version control so you can revert if needed.

If you found this interesting and want to read more or share your results from this method, join us at Poly Research & Robotics, we're a free community 1,000+ members all building trading bots and applications for prediction markets. We have guides, tutorials, and free historical data for you to use for backtesting or planning out your next project.

👉 https://discord.gg/BU9EjyqesV

u/PolyResearchRobotics — 2 months ago

Did I discover an edge in tennis matches on Polymarket?

I've been collecting a ton of data from polymarket over the past few weeks, all full depth orderbook snapshots on crypto markets, finance markets, sports...weather etc and I wanted to comb through some of the data and look into how accurate is the polymarket implied probability. From what I knew, it's extremely accurate, but I wanted to look closer and see if there were any sets of ranges where the actual % of the outcome resolving was different than what is implied by the price. Sharing the results here in case they're useful to anyone

The first dataset I went through is composed of settled sports markets. For each market I recorded the pre-match price and compared it against the final result. The goal wasn't to test a trading strategy. It was simply to answer a basic question: how well does the market price reflect the true probability of an outcome?

Overall findings

Across the full dataset, Polymarket prices are extremely well calibrated. An outcome priced around 50¢ went on to win close to 50% of the time, and an outcome priced around 80¢ went on to win close to 80% of the time (so the 80¢ side resolved YES about 80% of the time, and lost the remaining ~20%). In other words, the share price lined up closely with how often that exact outcome actually occurred, across most of the price range.

The chart below summarizes the relationship between market price and actual win rate.

https://preview.redd.it/wdlwq4x76y8h1.png?width=1288&format=png&auto=webp&s=28e3124bcd899ac256c9a615eca79eb7f92ea8b8

One thing worth noting is that the favorite/longshot bias commonly seen in traditional sportsbooks appears to be much smaller here. There are some deviations, but the overall calibration stays fairly tight, meaning what the share price is almost always equals the actual % likeihood that the outcome will win.

One area that stood out

the first chart above throws both sides of every match into the same pool, which is part of why it looks so clean... problem is that can paper over an effect that only shows up on one side, since every 72¢ favorite is sitting next to a 28¢ underdog and averaging them together kind of cancels things out. so for the next one i pulled out just the favorite side of each match. x-axis is in the graph below is only the favorite's price (starts at 50¢ since a favorite can't really go lower than even) and the y-axis is how often that favorite actually won. thats where the dip in the middle shows up.

When isolating only the favorite side of each match, a pattern emerged in roughly the 65¢–80¢ range: favorites in this band won somewhat less often than their market price would suggest. For example, a favorite priced around 72¢ went on to win closer to 64% of the time in this sample, rather than the ~72% the price implied. THIS IS POTENTIALLY TRADABLE...

https://preview.redd.it/t5tcc38j6y8h1.png?width=1328&format=png&auto=webp&s=99575eb7ac8f0e4a5a3c2d8d853d04697ff85cea

Keep in mind, my sample set is rather small on the grand scheme of things, and primarily made up of ATP/WTP tennis matches, but maybe there is something there. Worth looking into if you're running a bot trading these matches. I doubled checked this by the way and this inefficiency did persist.

How you can trade this *potential* edge

you would want to buy the underdog when the favorite is priced between 65 and 80¢. in that range the favorite wins less than its price says it should, which means the underdog is cheap. you're paying around 29¢ for a dog that actually wins closer to 35% of the time, so there's a small edge built in there.

However, blindly betting every match following this rule would more than likely end up...not good. What I would do is go over this dataset again and segment out all of the matches where the above example actually was present...and then start digging in deeper to identify what other variables seem to be present in the matches where the underdog was mispriced, and compare that to the games where it the edge didn't show up and try to identify what other factors are true signal and not just noise.

https://preview.redd.it/f8nmz702zy8h1.png?width=1368&format=png&auto=webp&s=fe7368c7655fe545811b5a50fc36996c24473e6f

overall takeaways

The main conclusion from this study is that Polymarket prices appear to be reasonably well calibrated overall. In most cases, the market price was a fairly accurate reflection of how often an outcome will resolve correctly. The only notable deviation I found was in the moderate-favorite range, where favorites appeared to underperform their quoted probabilities within this particular sample of tennis matches. I'm going to do another analysis of other categories of sports as well and report back.

Thanks for reading, if you're interested in running your own analysis like this, i'll drop a link below to some free datasets i put together for my community, just leave a comment and i'll dm it to you. Otherwise, stay tuned for the next analysis...I might even build a bot to trade some of these edges and report back

u/PolyResearchRobotics — 2 months ago