<jupyter_start><jupyter_text>Monte Carlo PlaygroundPlaying around with some Monte Carlo Simulations, eventually the goal is to replicate some examples and logic from <NAME>., 2020. The Statistical Consequences of Fat Tails.<jupyter_code>import pandas as pd
import numpy as np
import random
import datetime as dt
from scipy.stats import sem, t

import matplotlib.pyplot as plt

# Pretty Display of Variables
#from IPython.core.interactiveshell import InteractiveShell
#InteractiveShell.ast_node_interactivity = 'all'

# Double resolution plotting for retina display
%config InlineBackend.figure_format ='retina'

%matplotlib inline<jupyter_output><empty_output><jupyter_text>Read in S&P500 data<jupyter_code>sp500 = pd.read_csv("data/sp500_daily_train_data.csv")
sp500.head(1)<jupyter_output><empty_output><jupyter_text>SP500 return simulation with price evolution<jupyter_code>start = sp500['loctimestamp'][0]
end = sp500['loctimestamp'][-1:]

returns = sp500['ret']

last_price = 2472.54

#Number of Simulations
num_simulations = 1000
num_days = 252

simulation_df = pd.DataFrame()

for x in range(num_simulations):
    count = 0
    daily_vol = returns.std()
    
    price_series = []
    
    price = last_price * (1 + np.random.normal(0, daily_vol))
    price_series.append(price)
    
    for y in range(num_days):
        if count == 251:
            break
        price = price_series[count] * (1 + np.random.normal(0, daily_vol))
        price_series.append(price)
        count += 1
    
    simulation_df[x] = price_series
    
fig = plt.figure()
fig.suptitle('Monte Carlo Simulation: SP500')
plt.plot(simulation_df)
plt.axhline(y = last_price, color = 'r', linestyle = '-')
plt.xlabel('Day')
plt.ylabel('Price')
plt.show()<jupyter_output><empty_output><jupyter_text>ToDo- Binomial Distribution- Other Distributions- Fat tailed Distributions- Calculate Max Drawdowns and VaR  Coin Flip<jupyter_code># from https://colab.research.google.com/drive/1ZniHyaE7AqkNYpypw8Qn7dGv62MlSrGG?usp=sharing#scrollTo=VrB1-X_zclHT
# 1. Coin Flip Example
#Coin flip function :

#0 --> Heads
#1 --> Tails

def coin_flip():
    return random.randint(0,1) 

#Monte Carlo Simulation :

#Empty list to store the probability values.
list1 = []

def monte_carlo(n):
    results = 0
    for i in range(n):
        flip_result = coin_flip()
        results = results + flip_result
        
        #Calculating probability value :
        prob_value = results/(i+1)
        
        #Append the probability values to the list :
        list1.append(prob_value)

        #Plot the results :
        plt.axhline(y=0.5, color='r', linestyle='-')
        plt.xlabel("Iterations")
        plt.ylabel("Probability")
        plt.plot(list1)
       
    return results/n
  
#Calling the function :

answer = monte_carlo(5000)
print("Final value :",answer)<jupyter_output>Final value : 0.5014<jupyter_text>Gamblers RuinSunday probability puzzle form Michael Harris: https://twitter.com/mikeharrisNY/status/1315426197413621760Three fair coins tossed. Heads gets +1, tails -1, pay-offs are added and net pay-off added to equity. The 3 tosses are repeated 1000 times. Initial equity is 10$\$$. What is the probability of total ruin (within +/- 0.05 error)?Help from: https://github.com/claudian37/Gamblers_Ruin_Webapp/blob/master/gamblers_ruin.pyTheoretical stuff: http://www.columbia.edu/~ks20/stochastic-I/stochastic-I-GRP.pdf<jupyter_code>from GamblersRuin import GamblersRuin
# probability of success
p = 0.5
# initial amount
init_bal = 10
# number of rounds
no_rounds = 1000
# number of simulations
no_simulations = 100

play_one_round_list = []

for no_simulations in range(1, 100000+1):
    gr = GamblersRuin(p=float(p), init_bal=int(init_bal))
    res = gr.play_one_round()
    play_one_round_list.append(res)
    
plt.hist(play_one_round_list)
plt.title(f'Distribution one round with n = {no_simulations}')
np.var(play_one_round_list)
gr = GamblersRuin(p=float(p), init_bal=int(init_bal))
# simulate no_simulations number of gains
gr.simulate(no_simulations=no_simulations, no_rounds=no_rounds)
# find out number of ruins, with length < 100
no_ruins = sum(len(list_elem) < no_rounds for list_elem in gr.simulation_results)
# find out number of non-ruins
no_non_ruins = sum(len(list_elem) == no_rounds for list_elem in gr.simulation_results)

# calculate probability of ruin 
prob_ruin = no_ruins / (no_ruins + no_non_ruins)
print(f"Probability of ruin for n = {len(gr.simulation_results)}: {prob_ruin * 100}%")<jupyter_output>Probability of ruin for n = 1000: 85.6%<jupyter_text>Plot balance evolution<jupyter_code>fig, ax = plt.subplots()

for list_elem in gr.simulation_results:
    x = range(1, len(list_elem) + 1)
    y = list_elem
    ax.plot(x, y)

ax.set(xlabel='round', ylabel='balance',
       title='Balance evolution in Gamblers Ruin Simulation')
ax.grid()

plt.show()<jupyter_output><empty_output><jupyter_text>Additional layer of simulation for increasing no_simulations<jupyter_code># probability of success
p = 0.5
# initial amount
init_bal = 10
# number of rounds
no_rounds = 1000

prob_ruin_list = []

for no_simulations in range(1000, 10000, 2000):
    gr = GamblersRuin(p=float(p), init_bal=int(init_bal))
    # simulate no_simulations number of gains
    gr.simulate(no_simulations=no_simulations, no_rounds=no_rounds)
    
    # find out number of ruins, with length < 100
    no_ruins = sum(len(list_elem) < no_rounds for list_elem in gr.simulation_results)
    # find out number of non-ruins
    no_non_ruins = sum(len(list_elem) == no_rounds for list_elem in gr.simulation_results)

    # calculate probability of ruin 
    prob_ruin = no_ruins / (no_ruins + no_non_ruins)
    print(f"Probability of ruin for n = {len(gr.simulation_results)}: {prob_ruin * 100}%")
    
    prob_ruin_list.append(prob_ruin)
# Data for plotting
x = range(1000, 10000, 2000)
y = prob_ruin_list

fig, ax = plt.subplots()
ax.plot(x, y)

ax.set(xlabel='number of simulations', ylabel='probability of ruin',
       title='Probability of ruin in Gamblers Ruin Simulation')
ax.grid()

plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10435779816513761, 'fraction_numerical': 0.031618610747051114, 'mean_word_length': 4.475336322869955, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 30, 'https://': 3, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '230001', 'license': 'MIT', 'n_tokens_mistral': 2322, 'n_tokens_neox': 2101, 'n_words': 520, 'path': 'monte_carlo_playground.ipynb', 'repo_name': 'tobikuhlmann/monte-carlo-playground', 'size': '6108'}