How it works...

In Steps 2 to 4, we downloaded Microsoft's stock prices and calculated simple returns. In the next step, we divided the data into the training and test sets. We calculated the average and standard deviation of the returns from the training set to obtain the drift (mu) and diffusion (sigma) coefficients, which we used later for simulations. Additionally, in Step 6, we defined the following parameters:

  • T: Forecasting horizon; in this case, the number of days in the test set.
  • N: Number of time increments in the forecasting horizon.
  • S_0: Initial price. For this simulation, we take the last observation from the training set.
  • N_SIM: Number of simulated paths.

Monte Carlo simulations use a process called discretization. The idea is to approximate the continuous pricing of financial assets by splitting the considered time horizon into a large number of discrete intervals. That is why, except for considering the forecasting horizon, we also need to indicate the number of time increments to fit into the horizon.

Step 7 is where we defined the function for running the simulations. It is good practice to define a function/class for such a problem, as it will also come in handy in the following recipes. We started by defining the time increment (dt) and the Brownian increments (dW). In the matrix of increments (size: n_sims x N), each row describes one sample path. From there, we calculated the Brownian paths (W) by running a cumulative sum (np.cumsum) over the rows. Then, we created a matrix containing the time steps (time_steps). To do so, we created an array of evenly spaced values within an interval (the horizon of the simulation). For that, we used np.linspace. Afterward, we broadcasted the array to the intended shape using np.broadcast_to. We used the closed-form formula to calculate the stock price at each point in time. Finally, we inserted the initial value into the first position of each row.

There was no explicit need to broadcast the vector containing time steps. It would have been done automatically to match the required dimensions (the dimension of W). However, in languages such as R, there is no automatic broadcasting. This also gives us more control over what we are doing and makes the code easier to debug.

In the preceding steps, we can recognize the drift as (mu - 0.5 * sigma ** 2) * time_steps and the diffusion as sigma * W.

While defining this function, we followed the vectorized approach. By doing so, we avoided writing any for loops, which would be inefficient in the case of large simulations.

For reproducible results, use np.random.seed before simulating the paths.

In Step 8, we visualized the simulated sample paths. To do so, we transposed the data and converted it into a pandas DataFrame. We did the transposition so that we had one path per column, which simplifies using the plot method of pandas DataFrame. This can also be done using pure matplotlib.

Aside from the main plot, we added two extra lines. The first one represents the average value of all sample paths at a given point in time. The second one is the actual stock price of Microsoft in the test set. To visualize the simulated stock prices, we chose alpha=0.2 to make the lines transparent. By doing this, it is easier to see the two extra lines.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.225.113