Time-Series Simulation

Overview

MCH Timeseries contains functions to create simulated times series with MCHammer. Current implementation supports Geometric Brownian Motion, Martingales and Markov Chain Time Series. Other methods will be added.

Functions

MCHammer.GBMMfitFunction
GBMMfit(HistoricalData, PeriodsToForecast)

GBMMfit uses a vector of historical data to calculate the log returns and use the mean and standard deviation to project a random walk. It the uses the last datapoint in the set as the starting point for the new forecast.

HistoricalData: Vector containing historical data

PeriodsToForecast: integer >1

Random.seed!(1)
historical = rand(Normal(10,2.5),1000)
GBMMfit(historical, 12)

# output
12×1 Array{Float64,2}:
 6.6992003689078325
 7.062760356166932
 7.103000620460403
 7.420415139367789
 8.514400412609032
 3.943937898162356
 4.146251875790493
 5.262045352529825
 0.7692838668172376
 1.2648073358011491
 1.5912440333414342
 2.1886864479965875
MCHammer.GBMMFunction
GBMM(LastValue, ReturnsMean, ReturnsStd, PeriodsToForecast)

GBMM produces a random wlak using the last data point and requires a mean and standard deviation to be provided.

LastValue: The most recent data point on which to base your random walk.

ReturnsMean and ReturnsStd : Historical Mean and Standard Deviation of Returns

PeriodsToForecast is an integer >1

Random.seed!(1)

GBMM(100000, 0.05,0.05,12)

# output

12×1 Array{Float64,2}:
 106486.4399226773
 113846.7611813516
 116137.16176312814
 121883.36579797923
 122864.3632374885
 130918.80622439094
 152488.25443945627
 142827.4651618234
 153753.52041326065
 164757.82535740297
 177804.24203041938
 195258.14301210243
MCHammer.GBMA_dFunction
GBMA_d(price_0, t, rf, exp_vol)

GBMA_d allows you to forecast the stock price at a given day in the future.

This function uses a multiplicative Geometric Brownian Motion to forecast

Simulating a random walk

ts_trials =[]
dr = collect(Date(2019,1,01):Dates.Month(1):Date(2019,12,31))

#To setup a TimeSeries simulation with MCHammer
for i = 1:1000
     Monthly_Sales = GBMM(100000, 0.05,0.05,12)
     Monthly_Expenses = GBMM(50000, 0.03,0.02,12)
     MonthlyCOGS = Monthly_Sales .* 0.3
     MonthlyProfit = Monthly_Sales - Monthly_Expenses - MonthlyCOGS
     push!(ts_trials, MonthlyProfit)
end

#You can graph the result using trend_chrt()
trend_chrt(ts_trials, dr)
timestamp Jan 1, 2019 Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Jan 1, 2018 2019 2020 2021 Jan 1, 2018 2019 2020 2021 Jan 1, 2018 2019 2020 2021 LowerBound p50 UpperBound variable h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -1.2×10⁵ -1.0×10⁵ -8.0×10⁴ -6.0×10⁴ -4.0×10⁴ -2.0×10⁴ 0 2.0×10⁴ 4.0×10⁴ 6.0×10⁴ 8.0×10⁴ 1.0×10⁵ 1.2×10⁵ 1.4×10⁵ 1.6×10⁵ 1.8×10⁵ 2.0×10⁵ 2.2×10⁵ -1.00×10⁵ -9.50×10⁴ -9.00×10⁴ -8.50×10⁴ -8.00×10⁴ -7.50×10⁴ -7.00×10⁴ -6.50×10⁴ -6.00×10⁴ -5.50×10⁴ -5.00×10⁴ -4.50×10⁴ -4.00×10⁴ -3.50×10⁴ -3.00×10⁴ -2.50×10⁴ -2.00×10⁴ -1.50×10⁴ -1.00×10⁴ -5.00×10³ 0 5.00×10³ 1.00×10⁴ 1.50×10⁴ 2.00×10⁴ 2.50×10⁴ 3.00×10⁴ 3.50×10⁴ 4.00×10⁴ 4.50×10⁴ 5.00×10⁴ 5.50×10⁴ 6.00×10⁴ 6.50×10⁴ 7.00×10⁴ 7.50×10⁴ 8.00×10⁴ 8.50×10⁴ 9.00×10⁴ 9.50×10⁴ 1.00×10⁵ 1.05×10⁵ 1.10×10⁵ 1.15×10⁵ 1.20×10⁵ 1.25×10⁵ 1.30×10⁵ 1.35×10⁵ 1.40×10⁵ 1.45×10⁵ 1.50×10⁵ 1.55×10⁵ 1.60×10⁵ 1.65×10⁵ 1.70×10⁵ 1.75×10⁵ 1.80×10⁵ 1.85×10⁵ 1.90×10⁵ 1.95×10⁵ 2.00×10⁵ -1×10⁵ 0 1×10⁵ 2×10⁵ -1.0×10⁵ -9.0×10⁴ -8.0×10⁴ -7.0×10⁴ -6.0×10⁴ -5.0×10⁴ -4.0×10⁴ -3.0×10⁴ -2.0×10⁴ -1.0×10⁴ 0 1.0×10⁴ 2.0×10⁴ 3.0×10⁴ 4.0×10⁴ 5.0×10⁴ 6.0×10⁴ 7.0×10⁴ 8.0×10⁴ 9.0×10⁴ 1.0×10⁵ 1.1×10⁵ 1.2×10⁵ 1.3×10⁵ 1.4×10⁵ 1.5×10⁵ 1.6×10⁵ 1.7×10⁵ 1.8×10⁵ 1.9×10⁵ 2.0×10⁵ value

Stochastic Time Series

Martingales

MCHammer.martyFunction
marty(Wager, GamesPlayed; GameWinProb = 0.5, CashInHand = Wager)

In probability theory, a martingale is a sequence of random variables (i.e., a stochastic process) for which, at a particular time, the conditional expectation of the next value in the sequence, given all prior values, is equal to the present value. (Wikipedia)

The marty function is designed to simulate a Martigale such as that everytime a wager is lost, the next bet doubles the wagered amount to negate the previous loss. The resulting vector is the balance of cash the gambler has in hand at any given point in the Martingale process.

GameWinProb is the estimated probability of winning. CashInHand is the starting balance for the martigale. At times, this parameter can make a difference in whether your survive the process or go home broke.

For example a gambler with 50$ making wagers of 50$, 10 times using the double or nothing strategy.

marty(50,10)
10-element Array{Any,1}:
    0
 -100
 -200
 -100
  -50
    0
  -50
 -150
 -250
 -350

Now let's assume that the gambler knows the odds of winning at the casino are less than 0.5 and decides to bring additional funds to persist until the bet pays off.

println(marty(50,10; GameWinProb=0.45, CashInHand=400))
Any[350, 450, 400, 300, 400, 350, 450, 500, 550, 500]

Using Gadfly.jl, you can compare outcomes at different win probabilities

Exp11 = plot(y = marty(5, 100, GameWinProb = 0.25, CashInHand = 400), Geom.point)
Exp12 = plot(y = marty(5, 100, GameWinProb = 0.33, CashInHand = 400), Geom.point)
Exp13 = plot(y = marty(5, 100, GameWinProb = 0.5, CashInHand = 400), Geom.point)
Exp14 = plot(y = marty(5, 100, GameWinProb = 0.55, CashInHand = 400), Geom.point)

gridstack([Exp11 Exp12; Exp13 Exp14])
-150 -100 -50 0 50 100 150 200 250 -100 -95 -90 -85 -80 -75 -70 -65 -60 -55 -50 -45 -40 -35 -30 -25 -20 -15 -10 -5 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175 180 185 190 195 200 -100 0 100 200 -100 -90 -80 -70 -60 -50 -40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? 50 100 150 200 250 300 350 400 450 500 550 600 650 700 750 800 850 900 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 210 220 230 240 250 260 270 280 290 300 310 320 330 340 350 360 370 380 390 400 410 420 430 440 450 460 470 480 490 500 510 520 530 540 550 560 570 580 590 600 610 620 630 640 650 660 670 680 690 700 710 720 730 740 750 760 770 780 790 800 810 820 830 840 850 0 500 1000 0 20 40 60 80 100 120 140 160 180 200 220 240 260 280 300 320 340 360 380 400 420 440 460 480 500 520 540 560 580 600 620 640 660 680 700 720 740 760 780 800 820 840 860 y -150 -100 -50 0 50 100 150 200 250 -100 -95 -90 -85 -80 -75 -70 -65 -60 -55 -50 -45 -40 -35 -30 -25 -20 -15 -10 -5 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175 180 185 190 195 200 -100 0 100 200 -100 -90 -80 -70 -60 -50 -40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? 150 200 250 300 350 400 450 500 550 600 650 700 200 205 210 215 220 225 230 235 240 245 250 255 260 265 270 275 280 285 290 295 300 305 310 315 320 325 330 335 340 345 350 355 360 365 370 375 380 385 390 395 400 405 410 415 420 425 430 435 440 445 450 455 460 465 470 475 480 485 490 495 500 505 510 515 520 525 530 535 540 545 550 555 560 565 570 575 580 585 590 595 600 605 610 615 620 625 630 635 640 645 650 0 200 400 600 800 200 210 220 230 240 250 260 270 280 290 300 310 320 330 340 350 360 370 380 390 400 410 420 430 440 450 460 470 480 490 500 510 520 530 540 550 560 570 580 590 600 610 620 630 640 650 y -150 -100 -50 0 50 100 150 200 250 -100 -95 -90 -85 -80 -75 -70 -65 -60 -55 -50 -45 -40 -35 -30 -25 -20 -15 -10 -5 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175 180 185 190 195 200 -100 0 100 200 -100 -90 -80 -70 -60 -50 -40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -1200 -1000 -800 -600 -400 -200 0 200 400 600 800 1000 1200 1400 1600 -1000 -950 -900 -850 -800 -750 -700 -650 -600 -550 -500 -450 -400 -350 -300 -250 -200 -150 -100 -50 0 50 100 150 200 250 300 350 400 450 500 550 600 650 700 750 800 850 900 950 1000 1050 1100 1150 1200 1250 1300 1350 1400 -1000 0 1000 2000 -1000 -950 -900 -850 -800 -750 -700 -650 -600 -550 -500 -450 -400 -350 -300 -250 -200 -150 -100 -50 0 50 100 150 200 250 300 350 400 450 500 550 600 650 700 750 800 850 900 950 1000 1050 1100 1150 1200 1250 1300 1350 1400 y -150 -100 -50 0 50 100 150 200 250 -100 -95 -90 -85 -80 -75 -70 -65 -60 -55 -50 -45 -40 -35 -30 -25 -20 -15 -10 -5 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175 180 185 190 195 200 -100 0 100 200 -100 -90 -80 -70 -60 -50 -40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -600 -500 -400 -300 -200 -100 0 100 200 300 400 500 600 700 800 900 1000 1100 -500 -480 -460 -440 -420 -400 -380 -360 -340 -320 -300 -280 -260 -240 -220 -200 -180 -160 -140 -120 -100 -80 -60 -40 -20 0 20 40 60 80 100 120 140 160 180 200 220 240 260 280 300 320 340 360 380 400 420 440 460 480 500 520 540 560 580 600 620 640 660 680 700 720 740 760 780 800 820 840 860 880 900 920 940 960 980 1000 -500 0 500 1000 -500 -450 -400 -350 -300 -250 -200 -150 -100 -50 0 50 100 150 200 250 300 350 400 450 500 550 600 650 700 750 800 850 900 950 1000 y

Markov Chains

Analytic Solution

Using linear algebra and matrix math, you can calculate the final state of equilibrium of the Markov Chain directly from the transition matrix.

MCHammer.markov_aFunction
markov_a(t_matrix)

markov_a produces the calculated end state of a Markov chain using a sqaure transition matrix.

For example, we want to see how many people will still be married once the Markov chain has stabilized. In the example below we will calculate what is the probability of still being married in 25 or 50 yrs assuming we are still alive.

Lets define the Marital Status Transition Matrix = [Single Married Separated Divorced]

As we can see, from a starting point of 88% of the people who are married, we have a 44% of them are still being married at the end of the process while 47% of the population is divorced.

Marital_StatM = [0.85	0.12	0.02	0.01;
0	0.88	0.08	0.04;
0	0.13	0.45	0.42;
0	0.09	0.02	0.89;
]

markov_a(Marital_StatM)
4-element Array{Float64,1}:
 1.1102230246251565e-16
 0.44416027280477405
 0.08184143222506393
 0.473998294970162

Times Series (Iterative Approach)

MCHammer.markov_tsFunction
markov_ts(t_matrix, start_arr, trials=1)

markov_ts is a time-series method that allows you to see the transition states trial by trial. Extremely useful for market share or account receivables problems where you want to see the states change over time.

t_matrix is the transition Matrix start_arr is the starting values for the chain. trials is the number of iterations you want to run through the Markov Chain Process.

A large bottling company wants to calculate market share based on clients switching to and from their beverage brands. The transition matrix below represents the probabilities of switching for the company's various beverage type

Drink Preferences Transition Matrix = [CherryCola DietCola CaffeinFree Classic Zero]

Assumming that each trial is equal to 1 year, we can calculate the brand shares at different points in time (e.g. 5 or 10 yrs.) using the markov_ts()

DrinkPreferences =
[0.6	0.03 0.15 0.2 0.02;
0.02 0.4 0.3 0.2 0.08;
0.15	0.25	0.3 0.25	0.05;
0.15	0.02	0.1	0.7	0.03;
0.15	0.3 0.05	0.05	0.45]

# This array represents the starting brand share. It must total 1.

BrandShare = [0.1, 0.25, 0.05, 0.35, 0.25]

 markov_ts(DrinkPreferences, BrandShare, 10)
5×10 Array{Any,2}:
 0.1625  0.19745  0.216356  0.227091  …  0.240679   0.241465   0.241929
 0.1975  0.17305  0.155916  0.144678     0.129541   0.128699   0.128212
 0.1525  0.17075  0.17347   0.172522     0.168707   0.168422   0.168255
 0.34    0.3555   0.3708    0.381555     0.395846   0.396574   0.396982
 0.1475  0.10325  0.083458  0.074154     0.0652264  0.0648395  0.0646213

To visualize the changes in state over time, we can chart the results using Gadfly.jl

DrinkPreferences =
[0.6	0.03 0.15 0.2 0.02;
0.02 0.4 0.3 0.2 0.08;
0.15	0.25	0.3 0.25	0.05;
0.15	0.02	0.1	0.7	0.03;
0.15	0.3 0.05	0.05	0.45]

# This array represents the starting brand share. It must total 1.

BrandShare = [0.1, 0.25, 0.05, 0.35, 0.25]

#Organize results using DataFrames for plot
ms = markov_ts(DrinkPreferences, BrandShare, 10)
ms = DataFrame(hcat(transpose(ms), collect(1:10)), [:CherryCola, :DietCola, :CaffeinFree, :Classic, :Zero, :Yr])

#Plot Brandshare over time
plot(stack(ms, Not(:Yr)), x=:Yr, y=:value, color=:variable, Geom.line)
Yr -12.5 -10.0 -7.5 -5.0 -2.5 0.0 2.5 5.0 7.5 10.0 12.5 15.0 17.5 20.0 22.5 -10.0 -9.5 -9.0 -8.5 -8.0 -7.5 -7.0 -6.5 -6.0 -5.5 -5.0 -4.5 -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0 12.5 13.0 13.5 14.0 14.5 15.0 15.5 16.0 16.5 17.0 17.5 18.0 18.5 19.0 19.5 20.0 -10 0 10 20 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CherryCola DietCola CaffeinFree Classic Zero variable h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 -0.40 -0.38 -0.36 -0.34 -0.32 -0.30 -0.28 -0.26 -0.24 -0.22 -0.20 -0.18 -0.16 -0.14 -0.12 -0.10 -0.08 -0.06 -0.04 -0.02 0.00 0.02 0.04 0.06 0.08 0.10 0.12 0.14 0.16 0.18 0.20 0.22 0.24 0.26 0.28 0.30 0.32 0.34 0.36 0.38 0.40 0.42 0.44 0.46 0.48 0.50 0.52 0.54 0.56 0.58 0.60 0.62 0.64 0.66 0.68 0.70 0.72 0.74 0.76 0.78 0.80 0.82 -0.5 0.0 0.5 1.0 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 value