Random walks get you nowhere

This entry is part of 23 in the series Numpy Strategies

Numpy Strategies 0.0.6

Well, you might bump into a wall repeatedly or get hit by a car. The best you can do is get pretty close to your desired destination. So I made some random walk simulations using a trinomial model and a pentanomial model. I also devised a strategy based on a “high band”, but that has nothing to do with the random walks.

Stops update

It was a good week for the Numpy 4 portfolio.

The Numpy 5 portfolio had some startup issues.

Trinomial model

According to the trinomial tree model – the stock price can go up, down or stay the same. The logic is undeniable. For each node in the tree we multiply the stock price at that node with a certain factor. This factor is equal to 1, of course if the price is supposed to stay the same. The probabilities for each price change possibility should be calculated using all kinds of parameters. Instead I estimated the probabilities empirically.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
...
def pPos( arr ):
   pos = where( array( arr ) > 0 )
   return len(  pos[ 0 ] ) / float( len( arr ) )
 
def pNeg( arr ):
   neg = where( array( arr ) < 0 )
   return len(  neg[ 0 ] ) / float( len( arr ) )
...
   actual = pPos( numbers )
   self.assertAlmostEqual( 3/6.0,  actual )
 
   actual = pNeg( numbers )
   self.assertAlmostEqual( 2/6.0,  actual )
...
c,v = loadtxt(path( argv[ 1 ] + '.csv' ), delimiter=',', usecols=(6,7), unpack=True) 
 
returns = get_returns( c ) 
 
prices = []
madC = mad( returns )
pincrease = pPos( returns )
pdecrease = pNeg( returns )
n = 2 ** int( argv[ 2 ] )
madSqrt = madC * sqrt(3)
 
for j in range(0, n):
   curve = []
   curve.append( c[ 0 ] )
   rands = uniform(0, 1, len(c))
 
   for i in range(1, len( c ) ):
      factor = 1
 
      if rands[i] < pincrease:
         factor = exp( madSqrt  )
      elif rands[i] < (pincrease + pdecrease):
         factor = exp( -1 * madSqrt )
 
      curve.append( curve[i - 1] * factor )
 
   prices.append( array( curve ) )
 
prices = array( prices )
prices = prices.T
 
 
aggregated = []
 
for curve in prices:
   aggregated.append( midhinge(curve) )
...

Notice that I “average” the values for each point in time with midhinge formula.

1
2
3
4
5
6
7
8
9
10
...
def q1(arr):
   return stats.scoreatpercentile(arr, 25)
 
def q3(arr):
   return stats.scoreatpercentile(arr, 75)
 
def midhinge(arr):
   return (q1(arr) + q3(arr)) / 2
...

The resulting plot for AAPL looks a bit boring, but at least we did not end up in a river or something.

trinomial10AAPL

Pentanomial tree

The pentanomial tree is an enhancement of the trinomial tree, with two extra levels added.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
...
def pBigUp( arr, limit ):
   pos = where( array( arr ) > limit )
   return len(  pos[ 0 ] ) / float( len( arr ) )
 
def pSmallUp( arr, limit ):
   pos = where( array( arr ) < limit )
   pos = where( array( take( arr, pos ) ) > 0)
   return len(  pos[ 0 ] ) / float( len( arr ) )
 
def pBigDown( arr, limit ):
   neg = where( array( arr ) < -1 * limit )
   return len(  neg[ 0 ] ) / float( len( arr ) )
 
def pSmallDown( arr, limit ):
   neg = where( array( arr ) > -1 * limit)
   neg = where( array( take( arr, neg ) ) < 0)
 
   return len(  neg[ 0 ] ) / float( len( arr ) )
 
c,v = loadtxt(path( argv[ 1 ] + '.csv' ), delimiter=',', usecols=(6,7), unpack=True) 
 
returns = get_returns( c ) 
 
prices = []
madC = mad( returns )
ev = rgeomean( returns )
limit = ev + 2 * madC
pbu = pBigUp( returns, limit)
pbd = pBigDown( returns, limit )
psu = pSmallUp( returns, limit )
psd = pSmallDown( returns, limit )
n = 2 ** int( argv[ 2 ] )
smallPower = madC
S = stats.skew( returns )
K = stats.kurtosis( returns )
bigPower = smallPower +  abs( S ) / (K * 6 )
 
for j in range(0, n):
   curve = []
   curve.append( c[ 0 ] )
   rands = uniform(0, 1, len(c))
 
   for i in range(1, len( c ) ):
      factor = 1
 
      if rands[i] < psu:
         factor = exp( smallPower )
      elif rands[i] < (psu + psd):
         factor = exp( -1 * smallPower )
      elif rands[i] < (psu + psd + pbu):
         factor = exp( bigPower )
      elif rands[i] < (psu + psd + pbu + pbd):
         factor = exp( -1 * bigPower )
 
      curve.append( curve[i - 1] * factor )
 
   prices.append( array( curve ) )
 
prices = array( prices )
prices = prices.T
 
 
aggregated = []
aggregated2 = []
 
for curve in prices:
   aggregated.append( (max( curve ) + min( curve )) / 2 )
   aggregated2.append( midhinge( curve ) )
...

There seems to be a little bit more action in this plot.

penta10rAAPL

A Borg Portfolio

Resistance is futile.

Her Borg name was 7 of 24. She couldn’t remember her real name any more. 7 of 24 thought her new name appropriate, because all she did was work 24/7. The only thing that was promised to her was Borg heaven, where she would be truly assimilated in the Borg. Probably it was because a verse was constantly pumped into her brain.

The Borg believes
that we can achieve
The Borg works 24/7
until we reach heaven

In a previous life Seven was a private detective. In her last year as individual she followed a guy called N.S. who did something with computers. One day, when she was following him something fell out of his pocket. Seven picked it up. It was a piece of paper with some kind of a trading strategy and code scribbled on it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
def within_bands_ratio(a,b,sigma,arr):
   count = 0
 
   for i in range(0, len(arr)):
      if(arr[i] < ( a * i + b ) and arr[i] > ( a * i + b - 2 * sigma) ):
         count += 1
 
   return float(count)/len(arr)
 
for file in get_files():
   if(not file.endswith('.csv') ):
      print file + 'skipped'
      continue
 
   c,v = loadtxt(path( file ), delimiter=',', usecols=(6,7), unpack=True) 
 
   if check_data( c ):
      continue
 
   returns = get_returns( c ) 
   ev = geomean( returns )
 
   beforeLast = len( c ) - 2
   indices = where( returns > ev)
   tops = take(c[: beforeLast ], indices )
   (a, b, residuals) = fitline( indices[0], tops[0] )
 
   if len( residuals ) == 0:
      continue
 
   t = arange(0, len(c), 1)
   madC = mad( c )
 
   if c[ beforeLast ] < a * beforeLast + b - 2 * madC:
      wbr = within_bands_ratio( a, b, madC, c )
 
      if wbr > float( argv[ 1 ] ):
...

Seven found it funny, that a computer guy would do something so old school like writing on paper. She reread the note at home several times. The strategy defined a “band” and the idea was to pick stocks that temporarily fell below their band.

The next day she followed N. after he left his home as usual. However, this time he took a completely different route and looked really upset for some reason. N. went into a dark alley and Seven followed. Suddenly the guy turned around, grabbed something from his pocket and pointed it at her. A phaser blast hit Seven.

7 of 24 woke up on a Borg ship, still a bit stunned. A funny verse was playing through her head. Her body was covered with cold pieces of metal. The Borg had the habit of buying slaves cheaply, whenever possible. In these hard economic times, this was becoming increasingly easier.

The planet Rasabanana was also badly hit by the financial crisis. Many Rasabananese lost their homes and some even had to sell themselves as slaves. This was of course a golden opportunity for the Borg, so funds had to be raised to purchase more recruits. The Borg hive sensed a trading strategy floating around in Seven’s brain tissue. She was tasked with assembling an investment portfolio.

numpy6

The Collective had very strict trading regulations. Seven would have to wait at least six weeks until seeing the results. The Borg prepared their standard welcome message for the new drones.

We are the Borg. We will add your biological and technological distinctiveness to our own. Your culture will adapt to service us. Resistance is futile.

THE END

Random links of interest

Series NavigationSecret Transitions of a Markov Chain
By the author of NumPy Beginner's Guide, NumPy Cookbook and Instant Pygame. If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.
Share
This entry was posted in programming and tagged , , . Bookmark the permalink.