projects | pushover | github | twitter | rss | contact

trying to game (part 2)

posted to writings on mar 10th, 2009 with tag javascript, last updated on aug 12th, 2009

in the first part of this story, i had created a greasemonkey (javascript) script to watch auctions on and log bidding activity to my server. after observing a few auctions, i altered my script to automatically place bids on my behalf every time the auction's counter ran down to 1 second.

the only way i could possibly lose in this scenario would be if some sort of network disruption occurred that prevented my browser from seeing the counter reach 1, or prevented my bid from reaching the server and being placed. my script would keep bidding until my account ran out of money to bid with, continually running the auction time left back up to 10 seconds, until i was no longer outbid.

the first auction that my script was bidding on was for a macbook. the script began watching the auction at $112.58 and 13 hours later, it ended at $172.84. during the auction, my script placed 37 bids, each when the auction counter dropped to 1 second remaining, costing me $27.75.

according to my data for this auction, the final seconds looked like this:

1236315801,bidding at $172.78
1236315802,00:00:01,00:00:10,$172.79,Chronowulf,Single bid
1236315802,00:00:01,00:00:10,$172.80,Swattie77,Single bid
1236315802,00:00:01,00:00:10,$172.81,Your bid!,Single bid
1236315803,00:00:10,00:00:10,$172.82,Womai09,Single bid
1236315804,00:00:10,00:00:10,$172.83,Montysdad,Single bid
1236315816,bidding at $172.84

so the price was $172.78, the counter reached 1, i bid (along with 5 other people at roughly the same time), and the price was then $172.84. the counter reached 1 again and i bid, but my bid was not counted. the auction ended at $172.84, with the "Issoacs" user winning after having bidbutler place his or her 1,435th $0.75 bid.

while it's possible that my connection suddenly got laggy and my bid got in late, the data tells a different story. the other 5 users that bid with me at 1 second remaining just 15 seconds before had previously been bidding every 10 seconds or so, every time the counter got low. am i to believe that five other users (or bots), who had all been watching the auction for at least the past hour and up to at least 15 seconds before the auction ended, and were reliably bidding every single time the counter reached 1 second, all suddenly stopped or had connection problems at the exact same time?

on this one particular auction that swoopo ended up making $12,963 in bids, plus the final $172.84 price, 5 users who were all manually bidding suddenly lost to the 1 user using swoopo's bidbutler service (which placed 1,435 75-cent bids for that user). seems a bit strange.

while this auction was going on, my script was simultaneously logging and bidding on another macbook which i began logging from the start of the auction. it ended 5 hours after the previous auction, at only $44.88.

the data looks very similar to the first:

1236335690,bidding at $44.76
1236335691,00:00:01,00:00:15,$44.77,Dara08,Single bid
1236335692,00:00:15,00:00:15,$44.78,Mykdn,Single bid
1236335692,00:00:15,00:00:15,$44.79,Your bid!,Single bid
1236335692,00:00:15,00:00:15,$44.80,Cg1234,Single bid
1236335692,00:00:15,00:00:15,$44.81,Invicta1698,Single bid
1236335694,00:00:15,00:00:14,$44.82,Twistedcandy,Single bid
1236335695,00:00:14,00:00:15,$44.83,Julev84,Single bid
1236335719,bidding at $44.84
1236335721,00:00:01,00:00:15,$44.85,Dara08,Single bid
1236335722,00:00:15,00:00:15,$44.86,Your bid!,Single bid
1236335722,00:00:15,00:00:15,$44.87,Invicta1698,Single bid
1236335740,bidding at $44.88

once again, a number of users were placing manual bids each time the counter reached 1 second, and again, my script saw the counter reach 1, placed a bid, and that bid was not counted. this auction ended at $44.88 and was won by another user using bidbutler, which placed 706 bids on his or her behalf.

in the first part of this story, i had mentioned that slight timing differences may have accounted for the data i was seeing, where the counter would reach 1, a number of users would bid, and then one or two bids would come in a second later. i presumed that those one or two last bidders were experiencing a delay, and were actually bidding after the counter had already gone back up to 10 seconds from the previous users but before their counter updated.

while watching another auction in real-time, i noticed that occasionally when the counter reached 3 or 2 seconds remaining, it locked up. the counter stayed on 3, a second passed, and another, and the next time the counter updated, it was back at 10 seconds.

while my data was always showing that the script saw the display read 00:00:01 and bid, i thought that bidding before that point may be helpful. bidding when the display read 3 or 2 would cost a lot more money, though, since i would always be the one to bump up the clock. waiting for 1 second cost much less, since other users would see 3 or 2 and make their presence known by bidding. in this scenario, while i would probably not win against the other manually bidding users, at least the auction would not be able to end. one of us would always be bidding at 3, 2, or 1 seconds remaining.

after thinking about it some, i changed my script to be able to do a "blind" bid. when the counter reached 3, it would start an internal timer and fire 1500 milliseconds later. if the counter had not updated to read 2 or 1 second (or something higher, indicating that another user bid), it would bid. if the counter updated before the 1500 milliseconds to read 2 or 1, the previous code would catch it and bid at 1. this way i would be covered if the counter ran down normally, but also catch the counter locking up.

i let this new code run on a third auction, but with the same results. it had to use the blind bidding routine twice, but again it saw the counter reach 1, placed a final bid for the amount that the auction ended at, and did not win. and again, i was joined by at least 6 other manually bidding users that had previously been bidding at 1 second remaining just before the auction ended that also did not win.

with all of this data available, i concluded that there is no way to reliably win an auction on without using their bidbutler service. there are delays on their network/servers in processing manual bids, whether intentional or just due to bad design, that cause manual bids placed with 1 or 2 seconds remaining not to be cast. users of their bidbutler service have an unfair advantage in that their bids are placed on the server side and are not subject to these delays.

since it is not possible to reliably place manual bids, the only way to guarantee that an auction can be won (while still coming out ahead) is to use the site's bidbutler service with high ceilings on the number of bids and amount that one will let it bid up to. those ceilings have to take into account the item's current price, and will be lower the longer an item is being bid on.

on a $1,299 macbook auction with each bid costing a user 75 cents and raising the auction price 1 cent, assuming a user has someone else raising his bid every time, the maximum number of bids for him to place would be 1,687 from the start of the auction. 1,687 bids * 0.75 = $1,265.25 in bids, plus the final value of $33.74 (the other user bid 1,687 times, too, for 3,374 1-cent bid increments, or $33.74) totaling $1,298.99. if the user is not the high bidder at that point, he must give up and lose $1,298.99, or continue and spend more on the item than it is worth.

if that user had started bidding when the auction price was already, say, $100, and allowed bidbutler to place the same 1,687 bids, it would top out the item price at $133.74 and result in the user paying more than its $1,299 value. so the later the user enters the bidding, the fewer amount of bids he can have bidbutler place to still come out ahead. eventually this will reach 0 when the item's price reaches $1,299 (when 129,900 total bids have been placed by other users).

since the original idea of always bidding at 1 second remaining proved to be ineffective, i have been thinking about how to make a script use bidbutler to its advantage. at any given point, the script could produce a probability of there being any other users still bidding with bidbutler, based on the historical data of bidding activity the script is maintaining. since bidbutler bids at random times and rarely with only 1 or 2 seconds remaining, it would "show itself" over the past few 10-to-2-back-to-10 second cycles. if there is a high probability of there only being one other bidbutler user (or none), then the script could activate bidbutler and allow it to place a small number of bids over the next few cycles, hoping to beat out the other manual bidders since they obviously can't win against bidbutler. if there ever appears to be more than one user using bidbutler, the script would cancel bidbutler, saving the remaining bids it would have cast, and allow the other two users' bidbutlers to battle it out until the probability goes back up that there is only one (or none) left.

i haven't written the code for this last concept. i spent $75 on the bids used during these experiments and since the only way to win is still a gamble that will probably end up costing many hundreds of dollars in bids (though still less than the value of the item), i'm giving up on trying to game joshua was right; the only winning move is not to play.

update: the greasemonkey script that i used for this now is available on github.

Comments? Contact me via Twitter or e-mail.