patternjavascriptMinor
Artificial Stock Market Algorithm
Viewed 0 times
algorithmartificialstockmarket
Problem
I'm attempting to make a stock trading game in Javascript and I've been trying to find an algorithm to generate fake stock prices. Currently, each
Right now, if the current value is within the allowed range (minimum to maximum), then it has a 50% chance of going up and a 50% chance of going down. If it is out of said range, then it has an 80% chance of heading back towards the range and a 20% chance of heading farther out.
Volatility is how much the stock changes on average. Each turn, it changes by a random number between \$0\$ and \$\frac{volatility}{100} \cdot{range}\$ - that is, the volatility is the percentage of the entire range that it can change each turn (if anyone understands this and can explain it better, I would appreciate it).
The results so far have been pretty believable, but if there's any better algorithm that can be found it would be helpful. I would like something that isn't so, well, random. My algorithm stays between the range but there's not a ton of room for something unexpected to happen.
Some screenshots of results (the second is a new chart, but zoomed in on the lower values):
Stock object has a minimum value, maximum value, and volatility which I will explain later. The code is as follows:Stock.prototype.generateValue = function () {
//mod = probability that the value will decrease next turn
var mod = 0.5;
if (this.value > this.max) mod = 0.8;
if (this.value = mod) ? 1 : -1;
//maxToAdd = max amount that the value can change
var maxToAdd = (this.max - this.min) * this.volatility / 100;
this.value += (Math.random() * maxToAdd * dir);
//value can't be 0 -- random number from 0 to 10
if (this.value < 0) this.value = Math.random()*10;
//rounds to 2 decimal places
this.value = (Math.round(100*this.value))/100;
this.pastValues[this.pastValues.length] = this.value;
return this.value;
};Right now, if the current value is within the allowed range (minimum to maximum), then it has a 50% chance of going up and a 50% chance of going down. If it is out of said range, then it has an 80% chance of heading back towards the range and a 20% chance of heading farther out.
Volatility is how much the stock changes on average. Each turn, it changes by a random number between \$0\$ and \$\frac{volatility}{100} \cdot{range}\$ - that is, the volatility is the percentage of the entire range that it can change each turn (if anyone understands this and can explain it better, I would appreciate it).
The results so far have been pretty believable, but if there's any better algorithm that can be found it would be helpful. I would like something that isn't so, well, random. My algorithm stays between the range but there's not a ton of room for something unexpected to happen.
Some screenshots of results (the second is a new chart, but zoomed in on the lower values):
Solution
This question might be a better fit for another board, since you're asking for different algorithms. CodeReview is more for reviewing your current implementation. As 200_success mentioned, Quantitative Finance can perhaps give you some ideas for what to model, Game Development might have some ideas for "steering" randomness, and of course StackOverflow, if you're unsure of how to implement a different algorithm.
Just know that since it's hideously complicated to make a stock market game that doesn't feel like a total dice roll (and practically impossible to make a truly accurate simulation), most games just use the real stock market but fake money. That way, players have all the right sources of information to help decide their trades, which is the really hard thing to simulate. Will you simulate press releases? Earnings calls? Analyst/stock pundit predictions? The local and global economy? Fraud? Savage rabbits attacking Foxconn's factory and disrupting production for practically every electronics manufacturer in the world? Yeah... it's tough.
And of course, there's the thing that a stock price actually reflects: Trading activity. All the news in the world won't move a stock's price if no one is buying or selling. But it also means that the market is a feedback system, so your players' trades may impact prices (if the trades are large enough). So again: It's hideously complicated.
The best I can offer here is a review of your current code.
-
Your original question's code was very, very dense. You've since added some comments and whitespace, which was otherwise the first thing I'd suggest.
-
Your use of randomness introduces a potential problem: The stock rising or falling forever. Improbable, yes, but possible. You guard against the stock going negative, but still. Your guard mechanism is also a bit blunt. Theoretically a stock could trade below $1 for a while, and then suddenly - because it was about to go negative - it's at $10 regardless of its volatility or range. I'd probably invest in some of those penny stocks, on the off-chance that that happens. You should probably have a mechanism for delisting a stock instead, if it falls too low.
-
With your current solution, there's always at least a 20% chance that the market goes your way. Having 1-in-5 odds isn't great, but in real life there are much worse odds to be had (like betting on a company that's suddenly gone into bankruptcy after an accounting scandal and its CEO being eaten by wombats or something). It just feels like the 20/50/80 odds are a bit too coarse.
-
Having both a min/max price and a "volatility factor" might be redundant. Setting the min/max close to the current price should reduce volatility, and setting them further away should increase volatility. Or you might only use volatility, and let the stock do what it wants with no special min/max.
In terms of code, things look ok, except that this line
could just be
I'd also consider extracting the round-to-two-decimals code, since I'm sure you'll find it useful elsewhere.
As for changes, I'd probably change the price by a percentage instead. That way, it can't fall below zero:
Of course, you'll want to continually update the min/max range to "steer" the price one way or the other (just make sure that max >= min >= 0).
Regardless, how you want to do all this really depends on how the game part plays.
Just know that since it's hideously complicated to make a stock market game that doesn't feel like a total dice roll (and practically impossible to make a truly accurate simulation), most games just use the real stock market but fake money. That way, players have all the right sources of information to help decide their trades, which is the really hard thing to simulate. Will you simulate press releases? Earnings calls? Analyst/stock pundit predictions? The local and global economy? Fraud? Savage rabbits attacking Foxconn's factory and disrupting production for practically every electronics manufacturer in the world? Yeah... it's tough.
And of course, there's the thing that a stock price actually reflects: Trading activity. All the news in the world won't move a stock's price if no one is buying or selling. But it also means that the market is a feedback system, so your players' trades may impact prices (if the trades are large enough). So again: It's hideously complicated.
The best I can offer here is a review of your current code.
-
Your original question's code was very, very dense. You've since added some comments and whitespace, which was otherwise the first thing I'd suggest.
-
Your use of randomness introduces a potential problem: The stock rising or falling forever. Improbable, yes, but possible. You guard against the stock going negative, but still. Your guard mechanism is also a bit blunt. Theoretically a stock could trade below $1 for a while, and then suddenly - because it was about to go negative - it's at $10 regardless of its volatility or range. I'd probably invest in some of those penny stocks, on the off-chance that that happens. You should probably have a mechanism for delisting a stock instead, if it falls too low.
-
With your current solution, there's always at least a 20% chance that the market goes your way. Having 1-in-5 odds isn't great, but in real life there are much worse odds to be had (like betting on a company that's suddenly gone into bankruptcy after an accounting scandal and its CEO being eaten by wombats or something). It just feels like the 20/50/80 odds are a bit too coarse.
-
Having both a min/max price and a "volatility factor" might be redundant. Setting the min/max close to the current price should reduce volatility, and setting them further away should increase volatility. Or you might only use volatility, and let the stock do what it wants with no special min/max.
In terms of code, things look ok, except that this line
this.pastValues[this.pastValues.length] = this.value;could just be
this.pastValues.push(this.value);I'd also consider extracting the round-to-two-decimals code, since I'm sure you'll find it useful elsewhere.
As for changes, I'd probably change the price by a percentage instead. That way, it can't fall below zero:
Stock.prototype.generateValue = function () {
var minPercentage = this.min / this.value,
maxPercentage = this.max / this.value,
range = maxPercentage - minPercentage,
change = Math.random() * range + minPercentage;
this.value = Math.round(this.value * change * 100) / 100;
this.pastValues.push(this.value);
return this.value;
};Of course, you'll want to continually update the min/max range to "steer" the price one way or the other (just make sure that max >= min >= 0).
Regardless, how you want to do all this really depends on how the game part plays.
Code Snippets
this.pastValues[this.pastValues.length] = this.value;this.pastValues.push(this.value);Stock.prototype.generateValue = function () {
var minPercentage = this.min / this.value,
maxPercentage = this.max / this.value,
range = maxPercentage - minPercentage,
change = Math.random() * range + minPercentage;
this.value = Math.round(this.value * change * 100) / 100;
this.pastValues.push(this.value);
return this.value;
};Context
StackExchange Code Review Q#88595, answer score: 4
Revisions (0)
No revisions yet.