My first thought is a publish/subscribe model for the market. Said market receives buy/sell orders, adjusts the stock's price, then publishes the new price for the stock. All the members have subscribed to publications regarding the stocks they hold (or are interested in), so all receive notifications of price changes. What they do as a result is up to them.

This is a single-threaded environment, so you can't just have the member make a buy/sell decision and have it acted on: that would automatically cause a price adjustment publication and whoever gets notified first will get to make their decision before any other member has even seen the notification. Some sort of turn-based model, then. Market publishes, everyone acts on the notifications they received (or maybe choose not to do anything), then when it's the market's turn again it acts on all the buy/sell orders made and then publishes its adjustments.

Weedpacket I appreciate your thoughts here. While I was considering a cronjob to randomly adjust stock prices up or down a give a hint of real market fluctuations, I certainly think that all real price moves for a stock should be driven by the humans playing this stock market game. A couple of questions arise:

1) If a human purchases the stock at $100, how much should our algorithm adjust it? I was thinking of adjusting the stock price upwards using a function of the total number of human players, the total shares of the stock in existence, and the amount purchased by the player. But what's the formula? There are some problematic scenarios: a) user buys stock, stock gets marked up, user immediately sells stock, gaming the system and increasing their money without bound; b) user buys ALL shares of stock, preventing any action by other players (is this really bad? Or an interesting game dynamic?); c) player introduces a new stock, buys some shares (which increase in value due to his purchase action) and nobody else buys the stock -- if nobody else likes the stock (an unpopular IPO) then shouldn't the player be punished by a drop in stock price?

2) Does a player purchase the stock at the market price exactly as they see it? Or do we apply the price increase first? E.g., if I see stock at $100 and choose to buy enough shares to raise its price to $110, does the system charge me $100 or $110? This might prevent the system-gaming described in 1a above.

3) What happens if two players try and purchase the same stock in rapid succession? E.g., both players see the stock listed at $100 and click "buy." One player gets the $100 price, the other will see the increased price. I'm thinking the second player (even if it's only milliseconds) should get a 'denied' message that informs the user that their order was not fulfilled due to a price jump and offer them the option to buy at the new, higher price.

    (Caveat: I am not a financier).

    1) Real answer? No-one knows how prices are adjusted. If anyone figured that out they'd briefly become rich until everyone else caught on and the advantage of knowing is lost into irrelevancy.

    2) I take it you're not going to go into differing bid/ask prices (what the buyer will pay versus what the seller will receive); the difference is paid to the broker (the exchange has to make their money somehow). The difference in prices comes from buyers making bid offers and sellers making ask offers, and the two parties having different ideas what they're worth. The broker then matches sufficiently high bids that intersect with sufficiently low asks, takes the bid/ask prices that held when the respective offers were made, charges the buyer the bid price, pays the seller the ask price, and pockets the difference. So you'll need to timestamp offers and price history, and maybe add lifetime instructions to the offers so that they expire if not matched soon enough.

    Um, something something buy/sell spread something liquidity something.

    To keep things simple: 3) the other will see the increased price (whatever that turns out to be). But remember that they're only making an offer: they get to say what price they're willing to pay when they make that offer. Remember that buyers can only purchase shares that are being sold: sellers choose what price tag to put on their shares (maybe a range of prices within which they're willing to deal), and buyers make offers (ditto). If your buy orders are too low or sell orders are too high, you won't find any takers.

    But stocks often aren't traded so bluntly. You can have "put" or "call" options, where you buy the option to buy a certain number of shares at a certain price at a certain time in the future (the price could be the one when the option is bought, or the price on maturity, it could have clauses to automatically revoke or go through with the share purchase if and when various conditions are met). And of course options can be bought and sold. Sometimes optionally. Often bundled, with the whole package being bought or sold based on the performance of its constituents. Entire programming languages have been designed just to describe the various instruments in play—and that's a scary thought.

    What about tracking real-time or historical stock-price data to add a pseudo-randomness factor?

      Weedpacket 1) given my experience with websites and gaming, I expect someone would figure out that a purchase automatically yields a price increase and some kind of abuse method would be common knowledge within a week. Murphy's law blah blah blah.

      2 & 3) I was rather hoping to avoid all the complexity of bids and offers and price negotiation, etc. I'm thinking that's a huge gigantic mess of UI options and probably some AI logic to pretend to be some kind of haggling buyer/seller or something. I'd prefer not to open up the Pandora's box of put/call/etc. I don't want to force my users to find some other player that owns a stock and negotiate with them. That's tedious. I want to simulate a huge, liquid exchange with a simple algorithm that increases stock prices when users buy it and reduces the stock prices even more rapidly when people want to get rid of it.

      So far, two options seem easy, but with limitations.
      A) stock price immediately goes up by some amount when a user purchases it. The amount of increase is a function of how much stock is purchased and the number of players. If there are lots of players, the amount is smaller. If there are fewer, the amount is greater. PRO: very simple. CON: folks will quickly figure out they can buy then sell immediately ad nauseam.

      B ) option A, but mitigated by some surcharge that almost exactly cancels out the price increase of the stock.

      C) something like A or B but where the stock price increase is delayed for some period of time to hamper any attempts to gain the system. Like maybe wait 24 hours to apply the increase? I.e., we introduce a delay sorta like fail2ban to prevent high speed gaming of the system. Combined with additional price changes driven by user purchasing, this delay might effectively confound users ability to game things.

        If you used "C" and the delay was random .... hmm.

          Just reminds me all of someone I knew who did stock options trading, where they had mathematical formulas that virtually guaranteed they'd make money whichever way the market moved -- until it moved drastically in a way that emphasized that "virtually", and virtually ( 😉 ) all of them lost money.

          NogDog Fortunately, I'm not dealing with real money at all here. I'm just trying to cook up an algorithm to "gamify" maintenance of a list of celebrities by creating an make-believe stock market of these celebrity names. The idea is that the "value" of a celebritiy's name should increase or decrease based on the enthusiasm of the community to purchase fake "stocks" for that celebrity name. If players buy the name, it goes up. If they sell it, it goes down.

            21 days later

            There are two types of buy/sell orders. "Limit" and "Market".

            Limited orders have monetary values attached: "bids" are offers to buy shares at a certain price, "asks" are offers to sell shares at a certain price. Have a priority queue for each (so two per stock), with bids ordered in descending order of per-share price, and asks ordered ascending.

            Whenever the highest bid is at least as high as the lowest ask, a transaction can be made. The number of shares transferred is as many as possible as long as the buyer doesn't get more than they asked for and the seller doesn't give more than they have. The buyer pays the price they bid for each share, the seller receives what they asked, and the exchange pockets the difference. The two prices are the "buying/selling" prices of the stock.

            Meanwhile, others are just straight-up buying or selling their shares ("market orders"). If you buy, you pay the lowest asking price from the lowest-asking seller; if you sell, it's to the highest bidder at the highest asking price. The share price of that transaction becomes the stock's "market price" at that instant.

            If there were no limit orders then the market price wouldn't budge from whatever it started out with.

            10 days later

            Weedpacket while your responses are definitely helpful -- and are actually helping me understand the investment options for my 401k plan better -- that approach is considerably more complex than what I was hoping for. Rather than soliciting bids at specific prices and maintaining data structures and so on, I'd much rather just offer users BUY and SELL buttons where they can buy at the current market price or not.

            However, it's slowly dawning on me that I could in fact just offer these buttons and still implement your suggestion. In fact, your suggestion might address possible concurrency concerns, which are only beginning to form in my sluggish ape-brain.

            sneakyimp I'd much rather just offer users BUY and SELL buttons where they can buy at the current market price or not.

            Yeah; question is how you get "current market price". As I said in the last line it's driven by those limit orders. Without them you need some other mechanism for making the market price fluctuate. If you don't mind the market price being totally divorced from real agents' buying/selling then the geometric brownian motion model could be used to simulate the market they're acting in.

            Weedpacket I had imagined the price-driving mechanism to be an algorithm. Something like:

            • set price to $100/share (assume infinite shares available)
            • when someone clicks "buy" for some number of shares, increase the price by some multiplier, calculated from a function F(U, n) where U is the total number of users and n is the number of shares purchased. I imagine the multiplier should be proportional to 1/U so that one's purchasing influence is proportional. With many users, one user action means little. With few users, each individual has more power. Not sure what to do with the number of shares purchased, but purchasing more shares should probably mean larger influence.
            • when someone clicks "sell", we use some other function G(U, n) to decrease the current market price. Also proportional to 1/U. Also not sure what to do with n.

            As I mentioned above, this method is too easily gamed, though gaming the system might be mitigated with some minor adjustments like a surcharge -- or perhaps forcing the user to pay the adjusted price to buy the shares or something. I think the ideal cheat mitigation would be some transaction surcharge that exactly offsets the gain in value caused by the purchase action so that a purchase action yields zero immediate benefit, but transfers one's "cash" directly into stock value at a perfect 1-to-1 ratio. The ideal algorithm would reward early actors for buying a stock that everyone else subsequently buys and penalizes anyone who invests in a stock that experiences no purchase actions and also penalizes the last user to unload a stock that everyone is selling. I'm thinking the penalty applied for a sale should be greater than the bonus applied for a purchase, which would emphasize the panic when a stock starts to crater.

              You could use the act of buying/selling to tune the random walk (a buy increases the chance that the next price change will be upwards, a sell would encourage a downward tendency).

              Say, if Z[t] is generated by standard Brownian motion (Z[t+1] = Z[t]±1 where the sign is picked randomly) then the price X[t] would be proportional to exp((μ-σ**2/2)*t+σ*Z[t]).

              μ would usually be 0, but if you make it slightly negative (based on a tendency of agents to sell) the price would drift downwards and a positive value would make it drift upwards. Say start with it at zero and then each sale would bump it down a bit and each buy would bump it up a bit. You'd have each bump decay over time so that if nothing happens the amount of drift would eventually go back to zero and the price would go back to simulating the rest of the world (none of your real agents are trading in that stock). But if the bumps are coming thick and fast (and the size of the bump would be proportional to the size of the trade) then the amount of drift could become quite severe and you'd get some boom/bust drama happening. An appropriate value of σ, and how much to nudge μ by, is something that would have to be determined from experiment.

              Weedpacket oooh this sounds very interesting! Will try to work up some simulations when I get a chance.

                Write a Reply...