Loading [MathJax]/extensions/MathMenu.js

Saturday, 30 August 2014

Markets, stocks simulations and Markov chains

This article is some sort of continuation from this one.

Our previous model for stock simulations did not take in account the following idea:
when a stock (or the market) is going up, then it should be (intuitively) at least, more likely that it will continue to go up. Or at the very least, as it is the case for a football game, it does not feel right to believe that the probability of either of the two possible outcomes is exactly 50%.

The idea behind Markov chains is really versatile, we can apply it also to the markets.
With a “bit” of study (I’m being sarcastic here), you can come up with something pretty complicated like this, however, the model I’m going to show here is much more naive and easier.

Suppose a Markov chain with two states, market up and market down. Once you found the probabilities of each state, you can easily simulate a random walk (based on a Markov chain of course).

Here is the code for this model:

import numpy as np
from matplotlib import pyplot as plt
path = "C:\\"
#data is stored in a .txt file in format DOHLCV
def readData(stock):
file = open(path+stock+'.txt',"r")
data = file.read()
file.close()
return data
#We read data and get a list with each line in string format
data = readData('stock').split('\n')
#This function returns a list with float mean values
#from two columns (1st and 4th in this case)
def getColumn(list1):
dataAr = []
for i in range(len(list1)-1):
dataToGet = (float(list1[i].split(',')[1]) + float(list1[i].split(',')[4]))/2
dataAr.append(dataToGet)
return dataAr
#Here is our data (type(data[1]) = float)
data = getColumn(data)
#Calculate percentage change
def getPercentageChange(v1,v2):
pc = (v2-v1)/abs(v1)
return pc
#Given an array of numbers, this function returns an array
#with percentage changes between each pair of values
def getPcArray(list1):
pcArray = []
for i in range(len(list1)-2):
pcArray.append(getPercentageChange(list1[i],list1[i+1]))
return pcArray
dataPerc = getPcArray(data)
#Now we need to calculate conditional probabilities
negativesP = 0
negativesN = 0
for i in range(1,len(dataPerc)):
if dataPerc[i-1] <= 0 and dataPerc[i] > 0:
negativesP += 1
elif dataPerc[i-1] <= 0 and dataPerc[i] < 0:
negativesN += 1
positivesP = 0
positivesN = 0
for i in range(1,len(dataPerc)):
if dataPerc[i-1] > 0 and dataPerc[i] > 0:
positivesP += 1
elif dataPerc[i-1] > 0 and dataPerc[i] < 0:
positivesN += 1
#pUp_givenUp = probability of going up, given that
#the previous step was upwards
pUp_givenUp = positivesP/(positivesP+positivesN)
pDown_givenUp = positivesN/(positivesP+positivesN)
pUp_givenDown = negativesP/(negativesP+negativesN)
pDown_givenDown = negativesN/(negativesP+negativesN)
#Transition matrices for our model
stateUp = [pUp_givenUp,pDown_givenUp]
stateDown = [pUp_givenDown,pDown_givenDown]
#This function simulates n random walks according
#to the parameters specified and the Markov model.
def simulate(n):
k = 0
for i in range(n):
#Initial value
initial = 100
#Possible percentage change [up,down]
variat = [0.02,-0.02]
#Initial percentage change
invar = np.random.choice(variat,replace=True)
#List of simulated data
simulatedData = []
#Simulation process
for i in range(255):
if invar >= 0:
invar = np.random.choice(variat,replace=True,p=stateUp)
else:
invar = np.random.choice(variat,replace=True,p=stateDown)
initial = initial*(1+invar)
simulatedData.append(initial)
#x axis
index = list(range(len(simulatedData)))
#Plot the data
print(k)
k += 1
plt.plot(index,simulatedData)
plt.title(str(n)+" simulated random walks")
#Let's simulate 2 random processes
simulate(2)
plt.show()
# Output (conditional probabilities)
#
# pUp_givenUp pDown_givenUp pUp_givenDown pDown_givenDown
# 0.60360 0.39639 0.44806 0.55193

The graphs below represent respectively, 2, 200 and 500 random paths.


2 random walks
2_random_waks


200 random walks


200_random_waks


500 random walks


500_random_waks


Hope this was interesting.





Disclaimer
This article is for educational purpose only. The numbers are invented. The author is not responsible for any consequence or loss due to inappropriate use. It may contain mistakes and errors. You should never use this article for purposes different from the educational one.

2 comments:

  1. Buy Speakers at Cheapest Price with Amazing Quality
    https://seventysevenstyle.com/collections/wireless-products/products/touch-bedside-lamp-night-light-bluetooth-speaker-rechargeable

    ReplyDelete