Random walk in Python

This is a memo of a random walk by Python. I'm writing a little mathematical formula, but it's not mathematically strict, so don't be afraid.

Simple random walk

Price $ p (n) $ at time $ n $,

p(n) = p(n-1) + d(n)

Time series calculated by adding $ d (n) $ (however, $ d (n) $ is $ 1 $ or $ -1 $) to the price $ p (n-1) $ one sample before. Is called a simple random walk.

First, $ d (n) $ can be written in Python as follows:

%matplotlib inline
import numpy as np
import pandas as pd

dn = np.random.randint(2, size=1000)*2-1

If you generate a random number of 0 or 1, double it and subtract 1, you get -1 or 1. Alternatively, you can randomly select either [-1,1] as follows.

dn = np.random.choice([-1,1], size=1000)

If you add these in order, it will be a simple random walk. Here, the initial value is $ p (0) = 100 $.

p0 = 100
swalk = np.cumsum(dn)+p0

Let's plot it in the Series class of pandas.

pd.Series(swalk).plot()

index.png

Geometric random walk

A simple random walk adds $ + 1 $ or $ -1 $ to the previous price, but if you continue to do this, the price may become negative. It is strange that the stock price will be negative, so in order to simulate the actual movement of the stock price, we will use a geometric random walk that is a slightly modified version of the simple random walk.

Geometric random walks use the logarithmic value of the price instead of the price to formulate a similar formula.

\log p(n) = \log p(n-1) + d(n)

In this equation, transpose $ \ log p (n-1) $

\log\frac{p(n)}{p(n-1)}= d(n)

If you take exp () on both sides,

\frac{p(n)}{p(n-1)}=e^\{d(n)\}

It will be. In other words, the formula for finding $ p (n) $ from $ p (n-1) $ is

p(n)=e^\{d(n)\} p(n-1)

It will be. Here, $ d (n) $ is the price of the previous sample because it can be approximated as $ e ^ \ {d (n) } \ approx 1 + d (n) $ when $ d (n) $ is small. You can see that it is the rate of change from.

However, if $ d (n) $ is the rate of change, $ + 1 $ or $ -1 $ will be the rate of change of 100%, which is too large. Here, since the change of 1 yen for 100 yen is 1%, $ d (n) $ is calculated as $ 0.01 $ or $ -0.01 $. If you use the dn obtained by the simple random walk, the initial value is also $ p (0) = 100 $.

gwalk = np.cumprod(np.exp(dn*0.01))*p0

It is OK if you multiply ʻexp (dn * 0.01) `in order like this. This is plotted as follows:

pd.Series(gwalk).plot()

index.png

Since it uses the same $ d (n) $ as the simple random walk, it looks almost the same, but the difference between changing in 1-yen units and changing in 1% units appears a little away from 100 yen. I am.

Random walk close to the actual market price

Whether it's stocks or Forex, the actual market price isn't exactly a random walk, but you can think of it as a random walk. Here, I will try to make something close to the actual market price with a random walk.

The parameter of the geometric random walk is the fluctuation rate. In the previous example, the fluctuation rate per sample was set to 1%, but in the market world, the standard deviation of the fluctuation rate on a yearly basis is expressed by the term "volatility". Below is a site that shows the actual Forex volatility.

History Volatility (Central Tanshi FX)

A volatility of 10% means that the probability that the price will fall within $ \ pm 10 $% one year later is in the normal distribution of $ \ pm 1 \ sigma $ (approximately 68%), but in reality volatility is time. It fluctuates with. There is also a random walk model that fluctuates volatility, but here we will fix the volatility. In the case of Forex, the volatility is about 10% to 20%, so this time I will set it to 15%.

Next, it cannot be the actual market price that changes at the same rate of change each time. Therefore, we will make the changing time frame finer. For example, if you execute a random walk at 1-minute intervals, you will have performed a random walk of 60 samples in 1 hour, so the fluctuation rate per hour will change each time. As the number of samples increases, the probability of fluctuation rate becomes a normal distribution, which is closer to the actual movement.

So, let's use pandas to create a one-minute index for one year.

idx = pd.date_range('2015/01/01', '2015/12/31 23:59', freq='T')

Since the FX market does not move on weekends, only the weekday part is taken out from ʻidx`.

weekidx = idx[idx.weekday<5]

Next, create $ d (n) $ that is the same size as weekidx.

dn = np.random.randint(2, size=len(weekidx))*2-1

Volatility is a one-year volatility, so convert this to a one-minute volatility. Calculated by dividing by the square root of the total number of 1-minute bars for the number of business days in a year (260 days).

Vola = 15.0 #Volatility(%)
scale = Vola/100/np.sqrt(260*24*60)
gwalk = np.cumprod(np.exp(scale*dn))*p0

Based on this 1-minute random walk, let's make a 4-hour random walk, for example.

df = pd.Series(gwalk, index=weekidx).resample('4H').ohlc().dropna()

Use pandas's resample () method to create 4-value data. If you display only the closing price, it will be as follows.

df['close'].plot()

index.png

Here is an example of a random walk with 15% volatility. However, the random walk has a different chart each time, so I'm not sure if it fits.

Recommended Posts

Random walk in Python
Balanced Random Forest in python
Use Random Forest in Python
Weighted random choice in python
Testing with random numbers in Python
Create a random string in Python
Quadtree in Python --2
CURL in python
Metaprogramming in Python
Python 3.3 in Anaconda
Geocoding in python
SendKeys in Python
Meta-analysis in Python
Unittest in python
Discord in Python
Sudoku in Python
DCI in Python
quicksort in python
nCr in python
N-Gram in Python
Programming in python
Plink in Python
Constant in python
Lifegame in Python.
FizzBuzz in Python
Sqlite in python
StepAIC in Python
N-gram in python
LINE-Bot [0] in Python
Csv in python
Disassemble in Python
Reflection in Python
Constant in python
nCr in Python.
format in python
Scons in Python3
Puyo Puyo in python
python in virtualenv
PPAP in Python
Quad-tree in Python
Reflection in Python
Chemistry in Python
Hashable in python
DirectLiNGAM in Python
LiNGAM in Python
Flatten in python
flatten in python
Disease classification in Random Forest using Python
[Python] Disease classification in random forest-with LDA-
Sorted list in Python
Daily AtCoder # 36 in Python
Clustering text in Python
Daily AtCoder # 2 in Python
Implement Enigma in python
Daily AtCoder # 32 in Python
Daily AtCoder # 6 in Python
Edit fonts in Python
Singleton pattern in Python
File operations in Python
Read DXF in python
Daily AtCoder # 53 in Python