Monte Carlo Simulation serverless using Python Shiny Live + Code!
aktieanalys
    shinylive
    python
    interactive
    valuation
    Monte
    Carlo
  
    Monte Carlo Simulations are powerful. Using Shinylive with Python, you can leverage web assebely to distribute your insights with users who do not have the possibility to access your dynamic analysis otherwise.
  
Example of a Monte Carlo Simulation
#| standalone: true
#| layout-nrow: 1
#| viewerHeight: 820
from shiny import App, render, ui, Inputs, Outputs, Session
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def monte_carlo_simulation(years, initial_revenue, revenue_growth_range, profit_margin_range,fair_value):
    final_results = []
    num_simulations=10000
    #fair_value=np.number(fair_value)
    #print(fair_value)
    for _ in range(num_simulations):
        yearly_revenues = [initial_revenue]
        yearly_profits = []
        yearly_valuation = []
        for year in range(years):
            growth_rate = np.random.lognormal(revenue_growth_range[0], revenue_growth_range[1])
            profit_margin = np.random.uniform(profit_margin_range[0], profit_margin_range[1])
            
            new_revenue = yearly_revenues[-1] * (1 + growth_rate)
            profit = new_revenue * profit_margin
            valuation = profit*fair_value
            yearly_revenues.append(new_revenue)
            yearly_profits.append(profit)
            yearly_valuation.append(valuation)
        final_results.append({'Revenue': yearly_revenues[-1], 'Profit': yearly_profits[-1],
        'Valuation': yearly_valuation[-1]})
        
    return final_results
app_ui = ui.page_fluid(
    ui.layout_sidebar(
        ui.sidebar(
            ui.h1("Monte Carlo Simulation"),
            ui.input_slider("fair_value", "Fair P/E", min=5, max=40, value=25),
            ui.input_slider("years", "Number of Years", min=1, max=10, value=3),
            ui.input_numeric("initial_revenue", "Initial Revenue", value=27.5),
            ui.input_slider("revenue_growth_min", "Mean Revenue Growth", min=-0.2, max=1, value=0.25, step=0.05),
            ui.input_slider("revenue_growth_max", "Std Revenue Growth", min=0, max=1, value=0.1, step=0.05),
            ui.input_slider("profit_margin_min", "Min Profit Margin", min=0, max=1, value=0.30, step=0.01),
            ui.input_slider("profit_margin_max", "Max Profit Margin", min=0, max=1, value=0.50, step=0.01),
        ),
        ui.layout_column_wrap(
            ui.output_plot("simulation_plot")
        )
    )
)
def server(input: Inputs, output: Outputs, session: Session):
    @output
    @render.plot
    def simulation_plot():
        fair_value = input.fair_value()
        years = input.years()
        initial_revenue = input.initial_revenue()
        revenue_growth_range = (input.revenue_growth_min(), input.revenue_growth_max())
        profit_margin_range = (input.profit_margin_min(), input.profit_margin_max())
        
        results = monte_carlo_simulation(years, initial_revenue, revenue_growth_range, profit_margin_range,fair_value)
        Valuation = [result['Valuation'] for result in results]
        Valuation_mean = round(np.mean(Valuation),1)
        Valuation_std = round(np.std(Valuation),1)
        plt.hist(Valuation, bins=30)
        plt.title('Monte Carlo Simulation of Company Valuation over ' + str(years) + ' Years. Mean: ' + str(Valuation_mean)+'+-'+str(Valuation_std))
        plt.xlabel('Valuation')
        plt.ylabel('Frequency')
app = App(app_ui, server)
Code below to recreate dashboard above
```{shinylive-python}
#| standalone: true
#| layout-nrow: 1
#| viewerHeight: 820
from shiny import App, render, ui, Inputs, Outputs, Session
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def monte_carlo_simulation(years, initial_revenue, revenue_growth_range, profit_margin_range,fair_value):
    final_results = []
    num_simulations=10000
    #fair_value=np.number(fair_value)
    #print(fair_value)
    for _ in range(num_simulations):
        yearly_revenues = [initial_revenue]
        yearly_profits = []
        yearly_valuation = []
        for year in range(years):
            growth_rate = np.random.lognormal(revenue_growth_range[0], revenue_growth_range[1])
            profit_margin = np.random.uniform(profit_margin_range[0], profit_margin_range[1])
            
            new_revenue = yearly_revenues[-1] * (1 + growth_rate)
            profit = new_revenue * profit_margin
            valuation = profit*fair_value
            yearly_revenues.append(new_revenue)
            yearly_profits.append(profit)
            yearly_valuation.append(valuation)
        final_results.append({'Revenue': yearly_revenues[-1], 'Profit': yearly_profits[-1],
        'Valuation': yearly_valuation[-1]})
        
    return final_results
app_ui = ui.page_fluid(
    ui.layout_sidebar(
        ui.sidebar(
            ui.h1("Monte Carlo Simulation"),
            ui.input_slider("fair_value", "Fair P/E", min=5, max=40, value=25),
            ui.input_slider("years", "Number of Years", min=1, max=10, value=3),
            ui.input_numeric("initial_revenue", "Initial Revenue", value=27.5),
            ui.input_slider("revenue_growth_min", "Mean Revenue Growth", min=-0.2, max=1, value=0.25, step=0.05),
            ui.input_slider("revenue_growth_max", "Std Revenue Growth", min=0, max=1, value=0.1, step=0.05),
            ui.input_slider("profit_margin_min", "Min Profit Margin", min=0, max=1, value=0.30, step=0.01),
            ui.input_slider("profit_margin_max", "Max Profit Margin", min=0, max=1, value=0.50, step=0.01),
        ),
        ui.layout_column_wrap(
            ui.output_plot("simulation_plot")
        )
    )
)
def server(input: Inputs, output: Outputs, session: Session):
    @output
    @render.plot
    def simulation_plot():
        fair_value = input.fair_value()
        years = input.years()
        initial_revenue = input.initial_revenue()
        revenue_growth_range = (input.revenue_growth_min(), input.revenue_growth_max())
        profit_margin_range = (input.profit_margin_min(), input.profit_margin_max())
        
        results = monte_carlo_simulation(years, initial_revenue, revenue_growth_range, profit_margin_range,fair_value)
        Valuation = [result['Valuation'] for result in results]
        Valuation_mean = round(np.mean(Valuation),1)
        Valuation_std = round(np.std(Valuation),1)
        plt.hist(Valuation, bins=30)
        plt.title('Monte Carlo Simulation of Company Valuation over ' + str(years) + ' Years. Mean: ' + str(Valuation_mean)+'+-'+str(Valuation_std))
        plt.xlabel('Valuation')
        plt.ylabel('Frequency')
app = App(app_ui, server) ```