6

I have been working on a virtual stock market game using PHP. The formula that I have been using for deciding the price of a stock is

$price += $ran*0.001*$price + $ratio*0.005*$price

where

$ran = rand(-1*$intensity, 2*$intensity)

$intensity is a number between -5 to 5 depending upon whether the news is good or bad for the company and

$ratio = (1.0*($buy-$sell))/($buy + $sell)

$buy and $sell represent the number of shares bought and sold of a company respectively.

The problem with this formula is that, even if the intensity is negative (even -5) the ratio term is always added to the price which makes the overall term increase. The prices are refreshed every 10 seconds and with the above formula they keep on increasing and never come down. So, can anyone help me out with this formula so that it varies more closely to the actual stock market?

dimo414
  • 42,340
  • 17
  • 131
  • 218
Archit Verma
  • 1,662
  • 4
  • 26
  • 42
  • 4
    You are asking us to provide an algorithm to approximate the behavior of the stock market? – Mike Brant Oct 10 '13 at 17:31
  • 1
    The ratio will be negative if $sell > $buy, or more people are selling than buying. It would then make sense that the price of the stock should decrease. Also, you're putting 5 times more weight on the ratio than you are the random intensity, so your model is going to be way more biased towards buying/selling compared to news. – Dillon Welch Oct 10 '13 at 17:33
  • 1
    If `$itensity` can be negative, then you'll end up with (potentially) `rand(5,-10)`, which is an invalid argument set. the max value cannot be smaller than the min value. – Marc B Oct 10 '13 at 17:34
  • This is a math/economics question. Not a programming question. – Etienne Miret Oct 10 '13 at 17:38
  • @MikeBrant Yes, an improved one. – Archit Verma Oct 10 '13 at 17:41
  • @ArchitVerma If you can accomplish that I'd suggest keeping it under wraps because you've just made yourself a very rich person. Every trader in the world is looking for a similar algorithm. – Mike B Oct 10 '13 at 17:41
  • @MikeB - I think you're inflating OP's expectations; this is a game, and (s)he's looking for an algorithm that behaves *like* a stock market, not the algorithm that models *the real* market. – dimo414 Oct 10 '13 at 17:52
  • Actually, I believe all that's being asked for here is how to adjust the formula so that it does not tend to increase progressively over time. That's a straight-forward programming/math problem, no economics/statistics needed. – RBarryYoung Oct 10 '13 at 18:08
  • @RBarryYoung Yes, that is exactly what I am looking for. – Archit Verma Oct 10 '13 at 18:11
  • How are the `$buy` and `$sell` numbers set? Are the influenced by whether the price has just gone up or down? – RBarryYoung Oct 10 '13 at 18:25
  • @RBarryYoung '$buy' and '$sell' just represent the number of shares of a particular company that have been bought and sold respectively. It depends on the players. – Archit Verma Oct 10 '13 at 18:52
  • 1
    Umm, don't they always have to be equal then? You cannot buy something unless someone else sells it. – RBarryYoung Oct 10 '13 at 18:56
  • Actually my test models keep showing me that your overall trend should be *down* not up, because of `+%increase,-%decrease` inequities. – RBarryYoung Oct 10 '13 at 19:34

1 Answers1

4

If I understand correctly, you're trying to define an algorithm to determine a logical next price based on the current price, some market activity, and a random input. This is called a Random Walk, and the linked page is quite informative.

In economics, the "random walk hypothesis" is used to model shares prices and other factors. Empirical studies found some deviations from this theoretical model, especially in short term and long term correlations.

It's difficult for us to provide an exact function for you, since the exact behavior you expect of a function like this is inherently application specific. However it is possible to test the behavior and improve on it, by pulling it out into its own method and tweaking it until you see the behavior you want.

I would suggest pulling this behavior you've defined into an SSCCE (or a unit test, but assuming you don't already have a PHP unit test framework set up, an example will do fine) and creating some test cases, then you can tweak your algorithm in a vacuum and find behavior you like.

Here's some boilerplate to get started:

<?php

function nextPrice($price, $intensity, $buy, $sell, $rand) {
  // TODO
}

// Can tweak these values between runs, or put them in a loop if you want
$testPrice = 10.0;
$testBuy = 10000;
$testSell = 10000;

for ($i = -5; $i <= 5; $i++) {
  // random float, from http://stackoverflow.com/a/14155720/113632
  // set to a constant if you want to isolate the randomness and test other variables
  $testRand = mt_rand(0, mt_getrandmax() - 1) / mt_getrandmax();
  echo "<p>Intensity: $i - Rand: $testRand = ".
       nextPrice($testPrice, $i, $testBuy, $testSell, $testRand)."</p>";
}

?>

Some additional thoughts:

  • Your $ran definition is definitely flawed, if $intensity is -5 you're executing $ran = rand(5, -10); which generates a warning and doesn't return the value you want. This is likely the root of your issue, as any negative $intensity will essentially set $ran to zero.
  • Furthermore your $ran definition is biased towards positive numbers, meaning the price is - rather quickly - going to rise even if there's bad news. I'd suggest ensuring your random value is equally likely to lower the stock as raise it, and if you intend for the stock to rise in value over time regardless (which seems like a bad idea to me) set a separate $longTermGrowthFactor that always increases the stock by that factor, separately from the randomness.
  • Turn on warning reporting in PHP - since you presumably hadn't seen the warnings related to your rand() call, you likely have warnings and other error types turned off, which quite likely means there are other errors hidden in your code you aren't aware of, and without the reporting they're going to be hard to spot.
  • Use mt_rand() instead of rand(), the latter is deprecated, and mt_rand() is a drop-in replacement providing better randomness.
dimo414
  • 42,340
  • 17
  • 131
  • 218