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.GBMMfit
— FunctionGBMMfit(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.GBMM
— FunctionGBMM(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_d
— FunctionGBMA_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)
Stochastic Time Series
Martingales
MCHammer.marty
— Functionmarty(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])
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_a
— Functionmarkov_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_ts
— Functionmarkov_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)