Skip to main content
GameDev.net gamedev.net
🔒 Locked

Mathematical Problem!

Started by RRMessiah Sep 28, 2008 at 11:37 AM 5 replies 850+ views
Original Post
RRMessiah
RRMessiah
Hi, I'm fairly new to programming and I'm trying to create a stock trading simulator using minute-by-minute price data from a text file. Here is an example of the text file output: FNM. [180 bars] Time, Date, Open, High, Low, Close, Volume 13:01:00, 09/26/2008, 1.740000, 1.770000, 1.740000, 1.770000, 942722 During that minute, the price opened at 1.74, went as high as 1.77, went as low as 1.74, and closed at 1.77 at the 60th second. All during each second, the price ticks up and down and arrives at a specific price per second. The problem I'm having is trying to simulate the price action during that time period given the following parameters: 1. The price hits the high and low at random points during the timeline of 60 seconds. 2. The price never exceeds the high or the low during that 60 second period. 3. The price ticks up and down between $-.03 and $.03, but ultimately I'd like it to be customizable. 4. There can be more than 1 price tick up or down per second. So I'd setup variables that represent those prices: var_open, var_high, var_low, var_close. I'd setup array second[60] to represent the timeline. second[0] would be var_open, second[59] would be var_close. Then I would randomly choose second locations for var_low and var_high that were at least 2-3 elements from second[0] and second[59]. The next part is where I'm stuck. I really lack the expertise to create an algorithm that creates valid prices between those points given the parameters outlined above. Of course it's very easy to do it all linearly, but that's not emulating real stock price action. Can anyone help? Thanks!
CProgrammer
CProgrammer
Admitedly I didnt put too muc thought into it but what comes to mind is to just do the following:
Bear in mind that this has no justification in the stock market but I wasnt under the impression that you actually wanted to analyze the real market (is this just for a game?).
Randomly pick 2-3 points on te timeline as highs and the same for lows. Then create a polynomial function between the given points you have. Alter the polynomial function by randomly moving values on the timeline up or down, whilst ensuring that they dont surpass high and they are not lower than low. How many iterations is up to you.

-CPogrammer
chairthrower
chairthrower

Do it by simulating what actually happens in the market, and by preserving the relationship between the ticker period (minutes) and the underlying unit that the market moves in (seconds).

Fill a vector/array using the smaller timeperiod (seconds) for the total time range that you
are interested in by,

1) picking a starting value for the price eg 100.
2) then adjusting this up and down - every second by adding a normally distributed random number
with mean=0, and std deviation = what you choose (eg 1).
3) storing the result until you hit the end of the array/end of time period.

Then loop the array in segments of your ticker period (eg minutes mean 60 seconds). then for each segment,

0 index corresponds to open
59 index corresponds to close
max value of range ( 0..59) is the high
min value of range ( 0..59) is the low

You can store these in up a new array of records that record the open,high,low,close.

This will give you are a reasonable set of randomly simulated data for the market. some market models often presuppose non-normal distributions with 'fattened tails' but its not really important. If you get it working correctly you can probably dispense with the first array and just use a single loop that calculates the second set from accumulated values.

You dont mention what langugage you are working in but you should be able to find a library that will give you a single function call to obtain a normally distributed random value. I have never used it but I think that such a thing exists in boost if you are using c++.



CProgrammer
CProgrammer
I agree that simulating the whole thing start to finish is the better way to go, however the OP said he alreadyhad fixed max and min values. If this doesnt have to be the case then go with chairthrower's approach it makes much more sense. If you need the initial values then I guess you could also stretch the curve obtained to fit the requirements, wouldnt be ideal but it would work.
Bregma
Bregma
Quote:
Original post by RRMessiah
The problem I'm having is trying to simulate the price action during that time period given the following parameters:

Do you need to simlate second-by-second action or just generate the statistics for a minute's worth of trading action? Ar you just trying to generate a list of trades during that minute (ie. a list of (volume, settle price) pairs, ignoring bid and ask? If you specify the problem you're trying to solve it would make proposing a solution easier.
Quote:

1. The price hits the high and low at random points during the timeline of 60 seconds.
2. The price never exceeds the high or the low during that 60 second period.

Er, yes, there will always be a min and a max in any set of numbers.
Quote:

3. The price ticks up and down between $-.03 and $.03, but ultimately I'd like it to be customizable.
4. There can be more than 1 price tick up or down per second.

So I'd setup variables that represent those prices: var_open, var_high, var_low, var_close. I'd setup array second[60] to represent the timeline. second[0] would be var_open, second[59] would be var_close. Then I would randomly choose second locations for var_low and var_high that were at least 2-3 elements from second[0] and second[59].


I would suggest that you use some sort of uniform random number generate to produce a Brownian motion for the moment price in a given second (ie. generate a random number between, say -3 and 3, and add it to the previous moment price). Actual behaviour of the sock market is not linear: it would be more accurately modeled by some sort of differential equation with feedback since an active market tends to beget a more active market. If you want more than simple uniform Brownian motion, read up on differential equations.

The min/max for a given moment would be most accurately modeled by generating variance from the moment price on a chi-square distribution. Boost and the C++ standard tr1 have appropriate random distribution generation functions (you can use the gamma distribution to generate a chi-square distribution).

Wow, that sounds like technobabble. Sorry. Away team, one top beam up.
Stephen M. Webb
Professional Free Software Developer
Antheus
Antheus
Quote:
Do it by simulating what actually happens in the market


Realistic simulation right now would be:
while (stock.is_trading()) {  stock_value--;}
Extrarius
Extrarius
Here is how I would do it:
void GenerateStockPrices(MTRandom &RandGen,	const vector<double>::iterator First, const vector<double>::iterator Last,	double Low, double High, double LineContribution = 0.0){	const vector<double>::size_type RangeSize = Last - First + 1;	const vector<double>::iterator Middle = First + (RangeSize / 2);	const double LineBase = min(*First, *Last);	const double LineRange = max(*First, *Last) - LineBase;	const double RangeRange = High - Low;	const double LineBlend = LineContribution * RandGen.RandDouble();	const double RangeSelection = RandGen.RandDouble();	*Middle = LineBlend * (RangeSelection * LineRange + LineBase)		+ (1.0 - LineBlend) * (RangeSelection * RangeRange + Low);	const double NextLineContribution = (1.0 - (1.0 - LineContribution) / 2.0);	if(Middle - First > 1)	{		GenerateStockPrices(RandGen, First, Middle,			Low, High, NextLineContribution);	}	if(Last - Middle > 1)	{		GenerateStockPrices(RandGen, Middle, Last,			Low, High, NextLineContribution);	}}
MTRandom is an implementation of the Mersenne Twister generator, and the method RandDouble() generates a psuedorandom number in the inclusive range from 0.0 to 1.0.

This algorithm works by semi-randomly weighting (using the LineContribution parameter, whose distance to 1.0 is halved each recursion) two ranges(First..Last and Low..High) and then selecting a random number in the blended range[1]. The way I have it coded means that the middle value is selected from Low..High, while subsequent values are more and more likely to lie on the line from First..Last as the range sizes become smaller. However, since it's multiplied by a random value, it's still possible for occasional large jumps.

[1] It's less code and more efficient to blend the result from each range than to blend the ranges and then pick the result.

Edit: Ok, mine doesn't necessarily hit the high's or lows. That's easy to fix - randomly place a high and low in there and then run the recursive subdivision from First..LowIter, LowIter..HighIter, HighIter..Last (reordered as appropriate).
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.