diff --git a/.ipynb_checkpoints/MCForecastTools-checkpoint.py b/.ipynb_checkpoints/MCForecastTools-checkpoint.py new file mode 100644 index 0000000..9560dd9 --- /dev/null +++ b/.ipynb_checkpoints/MCForecastTools-checkpoint.py @@ -0,0 +1,171 @@ +# Import libraries and dependencies +import numpy as np +import pandas as pd +import os +import datetime as dt +import pytz + +class MCSimulation: + """ + A Python class for runnning Monte Carlo simulation on portfolio price data. + + ... + + Attributes + ---------- + portfolio_data : pandas.DataFrame + portfolio dataframe + weights: list(float) + portfolio investment breakdown + nSim: int + number of samples in simulation + nTrading: int + number of trading days to simulate + simulated_return : pandas.DataFrame + Simulated data from Monte Carlo + confidence_interval : pandas.Series + the 95% confidence intervals for simulated final cumulative returns + + """ + + def __init__(self, portfolio_data, weights="", num_simulation=1000, num_trading_days=252): + """ + Constructs all the necessary attributes for the MCSimulation object. + + Parameters + ---------- + portfolio_data: pandas.DataFrame + DataFrame containing stock price information from Alpaca API + weights: list(float) + A list fractions representing percentage of total investment per stock. DEFAULT: Equal distribution + num_simulation: int + Number of simulation samples. DEFAULT: 1000 simulation samples + num_trading_days: int + Number of trading days to simulate. DEFAULT: 252 days (1 year of business days) + """ + + # Check to make sure that all attributes are set + if not isinstance(portfolio_data, pd.DataFrame): + raise TypeError("portfolio_data must be a Pandas DataFrame") + + # Set weights if empty, otherwise make sure sum of weights equals one. + if weights == "": + num_stocks = len(portfolio_data.columns.unique()) + weights = [1.0/num_stocks for s in range(0,num_stocks)] + else: + if round(sum(weights),2) < .99: + raise AttributeError("Sum of portfolio weights must equal one.") + + # Calculate daily return if not within dataframe + if not "daily_return" in portfolio_data.columns.get_level_values(1).unique(): + close_df = portfolio_data.xs('close',level=1,axis=1).pct_change() + tickers = portfolio_data.columns.get_level_values(0).unique() + column_names = [(x,"daily_return") for x in tickers] + close_df.columns = pd.MultiIndex.from_tuples(column_names) + portfolio_data = portfolio_data.merge(close_df,left_index=True,right_index=True).reindex(columns=tickers,level=0) + + # Set class attributes + self.portfolio_data = portfolio_data + self.weights = weights + self.nSim = num_simulation + self.nTrading = num_trading_days + self.simulated_return = "" + + def calc_cumulative_return(self): + """ + Calculates the cumulative return of a stock over time using a Monte Carlo simulation (Brownian motion with drift). + + """ + + # Get closing prices of each stock + last_prices = self.portfolio_data.xs('close',level=1,axis=1)[-1:].values.tolist()[0] + + # Calculate the mean and standard deviation of daily returns for each stock + daily_returns = self.portfolio_data.xs('daily_return',level=1,axis=1) + mean_returns = daily_returns.mean().tolist() + std_returns = daily_returns.std().tolist() + + # Initialize empty Dataframe to hold simulated prices + portfolio_cumulative_returns = pd.DataFrame() + + # Run the simulation of projecting stock prices 'nSim' number of times + for n in range(self.nSim): + + if n % 10 == 0: + print(f"Running Monte Carlo simulation number {n}.") + + # Create a list of lists to contain the simulated values for each stock + simvals = [[p] for p in last_prices] + + # For each stock in our data: + for s in range(len(last_prices)): + + # Simulate the returns for each trading day + for i in range(self.nTrading): + + # Calculate the simulated price using the last price within the list + simvals[s].append(simvals[s][-1] * (1 + np.random.normal(mean_returns[s], std_returns[s]))) + + # Calculate the daily returns of simulated prices + sim_df = pd.DataFrame(simvals).T.pct_change() + + # Use the `dot` function with the weights to multiply weights with each column's simulated daily returns + sim_df = sim_df.dot(self.weights) + + # Calculate the normalized, cumulative return series + portfolio_cumulative_returns[n] = (1 + sim_df.fillna(0)).cumprod() + + # Set attribute to use in plotting + self.simulated_return = portfolio_cumulative_returns + + # Calculate 95% confidence intervals for final cumulative returns + self.confidence_interval = portfolio_cumulative_returns.iloc[-1, :].quantile(q=[0.025, 0.975]) + + return portfolio_cumulative_returns + + def plot_simulation(self): + """ + Visualizes the simulated stock trajectories using calc_cumulative_return method. + + """ + + # Check to make sure that simulation has run previously. + if not isinstance(self.simulated_return,pd.DataFrame): + self.calc_cumulative_return() + + # Use Pandas plot function to plot the return data + plot_title = f"{self.nSim} Simulations of Cumulative Portfolio Return Trajectories Over the Next {self.nTrading} Trading Days." + return self.simulated_return.plot(legend=None,title=plot_title) + + def plot_distribution(self): + """ + Visualizes the distribution of cumulative returns simulated using calc_cumulative_return method. + + """ + + # Check to make sure that simulation has run previously. + if not isinstance(self.simulated_return,pd.DataFrame): + self.calc_cumulative_return() + + # Use the `plot` function to create a probability distribution histogram of simulated ending prices + # with markings for a 95% confidence interval + plot_title = f"Distribution of Final Cumuluative Returns Across All {self.nSim} Simulations" + plt = self.simulated_return.iloc[-1, :].plot(kind='hist', bins=10,density=True,title=plot_title) + plt.axvline(self.confidence_interval.iloc[0], color='r') + plt.axvline(self.confidence_interval.iloc[1], color='r') + return plt + + def summarize_cumulative_return(self): + """ + Calculate final summary statistics for Monte Carlo simulated stock data. + + """ + + # Check to make sure that simulation has run previously. + if not isinstance(self.simulated_return,pd.DataFrame): + self.calc_cumulative_return() + + metrics = self.simulated_return.iloc[-1].describe() + ci_series = self.confidence_interval + ci_series.index = ["95% CI Lower","95% CI Upper"] + return metrics.append(ci_series) \ No newline at end of file diff --git a/.ipynb_checkpoints/Project1-checkpoint.ipynb b/.ipynb_checkpoints/Project1-checkpoint.ipynb index ed8b75a..6fd6a54 100644 --- a/.ipynb_checkpoints/Project1-checkpoint.ipynb +++ b/.ipynb_checkpoints/Project1-checkpoint.ipynb @@ -50,105 +50,10 @@ "cell_type": "code", "execution_count": 4, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - " | Price | \n", - "Open | \n", - "High | \n", - "Low | \n", - "Change % | \n", - "
---|---|---|---|---|---|
Date | \n", - "\n", - " | \n", - " | \n", - " | \n", - " | \n", - " |
2019-12-19 | \n", - "1,479.15 | \n", - "1,475.44 | \n", - "1,481.97 | \n", - "1,473.01 | \n", - "0.25% | \n", - "
2019-12-18 | \n", - "1,475.44 | \n", - "1,476.45 | \n", - "1,479.67 | \n", - "1,470.32 | \n", - "-0.07% | \n", - "
2019-12-17 | \n", - "1,476.45 | \n", - "1,476.25 | \n", - "1,480.78 | \n", - "1,474.23 | \n", - "0.01% | \n", - "
2019-12-16 | \n", - "1,476.25 | \n", - "1,475.60 | \n", - "1,480.03 | \n", - "1,472.99 | \n", - "0.03% | \n", - "
2019-12-13 | \n", - "1,475.81 | \n", - "1,469.47 | \n", - "1,478.22 | \n", - "1,462.48 | \n", - "0.43% | \n", - "
\n", + " | AUS | \n", + "AUT | \n", + "BEL | \n", + "CAN | \n", + "CHE | \n", + "CHL | \n", + "CZE | \n", + "DEU | \n", + "DNK | \n", + "ESP | \n", + "... | \n", + "NLD | \n", + "NOR | \n", + "NZL | \n", + "OECD | \n", + "POL | \n", + "PRT | \n", + "SVK | \n", + "SVN | \n", + "SWE | \n", + "USA | \n", + "
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1999 | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "... | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "NaN | \n", + "
2000 | \n", + "12.135159 | \n", + "11.596064 | \n", + "10.964750 | \n", + "12.678546 | \n", + "9.682128 | \n", + "31.212001 | \n", + "33.267924 | \n", + "12.361811 | \n", + "12.301337 | \n", + "14.765660 | \n", + "... | \n", + "10.886288 | \n", + "14.890065 | \n", + "17.038504 | \n", + "13.410651 | \n", + "26.795116 | \n", + "20.356821 | \n", + "36.422146 | \n", + "19.702377 | \n", + "16.241839 | \n", + "10.250640 | \n", + "
2001 | \n", + "12.097517 | \n", + "11.715860 | \n", + "11.015469 | \n", + "12.829300 | \n", + "9.406466 | \n", + "30.615049 | \n", + "31.921325 | \n", + "12.363368 | \n", + "12.314300 | \n", + "14.958176 | \n", + "... | \n", + "10.810441 | \n", + "14.644936 | \n", + "16.860158 | \n", + "13.378683 | \n", + "25.492497 | \n", + "20.431686 | \n", + "36.705827 | \n", + "19.078521 | \n", + "16.180853 | \n", + "10.243433 | \n", + "
2002 | \n", + "13.756140 | \n", + "13.218977 | \n", + "12.234188 | \n", + "14.812164 | \n", + "10.604931 | \n", + "34.749611 | \n", + "34.461509 | \n", + "14.070608 | \n", + "13.782313 | \n", + "17.040883 | \n", + "... | \n", + "12.335434 | \n", + "16.099960 | \n", + "18.944814 | \n", + "15.255201 | \n", + "29.274821 | \n", + "23.404415 | \n", + "39.962768 | \n", + "21.780667 | \n", + "18.287409 | \n", + "11.636402 | \n", + "
2003 | \n", + "15.939053 | \n", + "15.450707 | \n", + "14.257604 | \n", + "17.356947 | \n", + "12.462596 | \n", + "39.872596 | \n", + "37.559258 | \n", + "16.439237 | \n", + "15.763595 | \n", + "20.077096 | \n", + "... | \n", + "14.358362 | \n", + "18.623119 | \n", + "21.425247 | \n", + "17.712157 | \n", + "33.900962 | \n", + "27.498258 | \n", + "45.957989 | \n", + "25.007655 | \n", + "21.255882 | \n", + "13.475395 | \n", + "
5 rows × 36 columns
\n", + "0&&ye(a,!u&&ve(e,\"script\")),s},cleanData:function(e){for(var t,n,r,i=b.event.special,o=0;void 0!==(n=e[o]);o++)if(X(n)){if(t=n[G.expando]){if(t.events)for(r in t.events)i[r]?b.event.remove(n,r):b.removeEvent(n,r,t.handle);n[G.expando]=void 0}n[Y.expando]&&(n[Y.expando]=void 0)}}}),b.fn.extend({detach:function(e){return Me(this,e,!0)},remove:function(e){return Me(this,e)},text:function(e){return B(this,(function(e){return void 0===e?b.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)}))}),null,e,arguments.length)},append:function(){return Re(this,arguments,(function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||qe(this,e).appendChild(e)}))},prepend:function(){return Re(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=qe(this,e);t.insertBefore(e,t.firstChild)}}))},before:function(){return Re(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}))},after:function(){return Re(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}))},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(b.cleanData(ve(e,!1)),e.textContent=\"\");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map((function(){return b.clone(this,e,t)}))},html:function(e){return B(this,(function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if(\"string\"==typeof e&&!Ne.test(e)&&!ge[(de.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=b.htmlPrefilter(e);try{for(;n 5 rows × 36 columns\n",
+ " \n",
+ "
\n",
+ "\n",
+ " \n",
+ " \n",
+ " open \n",
+ " high \n",
+ " low \n",
+ " close \n",
+ " volume \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " Date \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 2019-12-19 \n",
+ " 1,475.44 \n",
+ " 1,481.97 \n",
+ " 1,473.01 \n",
+ " 1,479.15 \n",
+ " 0.25% \n",
+ " \n",
+ " \n",
+ " 2019-12-18 \n",
+ " 1,476.45 \n",
+ " 1,479.67 \n",
+ " 1,470.32 \n",
+ " 1,475.44 \n",
+ " -0.07% \n",
+ " \n",
+ " \n",
+ " 2019-12-17 \n",
+ " 1,476.25 \n",
+ " 1,480.78 \n",
+ " 1,474.23 \n",
+ " 1,476.45 \n",
+ " 0.01% \n",
+ " \n",
+ " \n",
+ " 2019-12-16 \n",
+ " 1,475.60 \n",
+ " 1,480.03 \n",
+ " 1,472.99 \n",
+ " 1,476.25 \n",
+ " 0.03% \n",
+ " \n",
+ " \n",
+ " \n",
+ "2019-12-13 \n",
+ " 1,469.47 \n",
+ " 1,478.22 \n",
+ " 1,462.48 \n",
+ " 1,475.81 \n",
+ " 0.43% \n",
+ " \n",
+ " \n",
+ "
\n",
+ "\n",
+ " \n",
+ " \n",
+ " open \n",
+ " high \n",
+ " low \n",
+ " close \n",
+ " volume \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " Date \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 2019-12-19 \n",
+ " 1475.44 \n",
+ " 1481.97 \n",
+ " 1473.01 \n",
+ " 1479.15 \n",
+ " 0.25% \n",
+ " \n",
+ " \n",
+ " 2019-12-18 \n",
+ " 1476.45 \n",
+ " 1479.67 \n",
+ " 1470.32 \n",
+ " 1475.44 \n",
+ " -0.07% \n",
+ " \n",
+ " \n",
+ " 2019-12-17 \n",
+ " 1476.25 \n",
+ " 1480.78 \n",
+ " 1474.23 \n",
+ " 1476.45 \n",
+ " 0.01% \n",
+ " \n",
+ " \n",
+ " 2019-12-16 \n",
+ " 1475.60 \n",
+ " 1480.03 \n",
+ " 1472.99 \n",
+ " 1476.25 \n",
+ " 0.03% \n",
+ " \n",
+ " \n",
+ " \n",
+ "2019-12-13 \n",
+ " 1469.47 \n",
+ " 1478.22 \n",
+ " 1462.48 \n",
+ " 1475.81 \n",
+ " 0.43% \n",
+ " \n",
+ " \n",
+ "
\n",
+ "\n",
+ " \n",
+ " \n",
+ " GOLD \n",
+ " \n",
+ " \n",
+ " \n",
+ " open \n",
+ " high \n",
+ " low \n",
+ " close \n",
+ " volume \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " Date \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 2019-12-19 \n",
+ " 1475.44 \n",
+ " 1481.97 \n",
+ " 1473.01 \n",
+ " 1479.15 \n",
+ " 0.25% \n",
+ " \n",
+ " \n",
+ " 2019-12-18 \n",
+ " 1476.45 \n",
+ " 1479.67 \n",
+ " 1470.32 \n",
+ " 1475.44 \n",
+ " -0.07% \n",
+ " \n",
+ " \n",
+ " 2019-12-17 \n",
+ " 1476.25 \n",
+ " 1480.78 \n",
+ " 1474.23 \n",
+ " 1476.45 \n",
+ " 0.01% \n",
+ " \n",
+ " \n",
+ " 2019-12-16 \n",
+ " 1475.60 \n",
+ " 1480.03 \n",
+ " 1472.99 \n",
+ " 1476.25 \n",
+ " 0.03% \n",
+ " \n",
+ " \n",
+ " \n",
+ "2019-12-13 \n",
+ " 1469.47 \n",
+ " 1478.22 \n",
+ " 1462.48 \n",
+ " 1475.81 \n",
+ " 0.43% \n",
+ " \n",
- " \n",
- "
\n",
- "\n",
- " \n",
- " \n",
- " Price \n",
- " Open \n",
- " High \n",
- " Low \n",
- " Change % \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " Date \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " 2019-12-19 \n",
- " 1,479.15 \n",
- " 1,475.44 \n",
- " 1,481.97 \n",
- " 1,473.01 \n",
- " 0.25% \n",
- " \n",
- " \n",
- " 2019-12-18 \n",
- " 1,475.44 \n",
- " 1,476.45 \n",
- " 1,479.67 \n",
- " 1,470.32 \n",
- " -0.07% \n",
- " \n",
- " \n",
- " 2019-12-17 \n",
- " 1,476.45 \n",
- " 1,476.25 \n",
- " 1,480.78 \n",
- " 1,474.23 \n",
- " 0.01% \n",
- " \n",
- " \n",
- " 2019-12-16 \n",
- " 1,476.25 \n",
- " 1,475.60 \n",
- " 1,480.03 \n",
- " 1,472.99 \n",
- " 0.03% \n",
- " \n",
- " \n",
- " \n",
- "2019-12-13 \n",
- " 1,475.81 \n",
- " 1,469.47 \n",
- " 1,478.22 \n",
- " 1,462.48 \n",
- " 0.43% \n",
- " \n",
+ " \n",
+ "
\n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " AUS \n",
+ " AUT \n",
+ " BEL \n",
+ " CAN \n",
+ " CHE \n",
+ " CHL \n",
+ " CZE \n",
+ " DEU \n",
+ " DNK \n",
+ " ESP \n",
+ " ... \n",
+ " NLD \n",
+ " NOR \n",
+ " NZL \n",
+ " OECD \n",
+ " POL \n",
+ " PRT \n",
+ " SVK \n",
+ " SVN \n",
+ " SWE \n",
+ " USA \n",
+ " \n",
+ " \n",
+ " 1999 \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " ... \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " NaN \n",
+ " \n",
+ " \n",
+ " 2000 \n",
+ " 12.135159 \n",
+ " 11.596064 \n",
+ " 10.964750 \n",
+ " 12.678546 \n",
+ " 9.682128 \n",
+ " 31.212001 \n",
+ " 33.267924 \n",
+ " 12.361811 \n",
+ " 12.301337 \n",
+ " 14.765660 \n",
+ " ... \n",
+ " 10.886288 \n",
+ " 14.890065 \n",
+ " 17.038504 \n",
+ " 13.410651 \n",
+ " 26.795116 \n",
+ " 20.356821 \n",
+ " 36.422146 \n",
+ " 19.702377 \n",
+ " 16.241839 \n",
+ " 10.250640 \n",
+ " \n",
+ " \n",
+ " 2001 \n",
+ " 12.097517 \n",
+ " 11.715860 \n",
+ " 11.015469 \n",
+ " 12.829300 \n",
+ " 9.406466 \n",
+ " 30.615049 \n",
+ " 31.921325 \n",
+ " 12.363368 \n",
+ " 12.314300 \n",
+ " 14.958176 \n",
+ " ... \n",
+ " 10.810441 \n",
+ " 14.644936 \n",
+ " 16.860158 \n",
+ " 13.378683 \n",
+ " 25.492497 \n",
+ " 20.431686 \n",
+ " 36.705827 \n",
+ " 19.078521 \n",
+ " 16.180853 \n",
+ " 10.243433 \n",
+ " \n",
+ " \n",
+ " 2002 \n",
+ " 13.756140 \n",
+ " 13.218977 \n",
+ " 12.234188 \n",
+ " 14.812164 \n",
+ " 10.604931 \n",
+ " 34.749611 \n",
+ " 34.461509 \n",
+ " 14.070608 \n",
+ " 13.782313 \n",
+ " 17.040883 \n",
+ " ... \n",
+ " 12.335434 \n",
+ " 16.099960 \n",
+ " 18.944814 \n",
+ " 15.255201 \n",
+ " 29.274821 \n",
+ " 23.404415 \n",
+ " 39.962768 \n",
+ " 21.780667 \n",
+ " 18.287409 \n",
+ " 11.636402 \n",
+ " \n",
+ " \n",
+ " \n",
+ "2003 \n",
+ " 15.939053 \n",
+ " 15.450707 \n",
+ " 14.257604 \n",
+ " 17.356947 \n",
+ " 12.462596 \n",
+ " 39.872596 \n",
+ " 37.559258 \n",
+ " 16.439237 \n",
+ " 15.763595 \n",
+ " 20.077096 \n",
+ " ... \n",
+ " 14.358362 \n",
+ " 18.623119 \n",
+ " 21.425247 \n",
+ " 17.712157 \n",
+ " 33.900962 \n",
+ " 27.498258 \n",
+ " 45.957989 \n",
+ " 25.007655 \n",
+ " 21.255882 \n",
+ " 13.475395 \n",
+ " 0){this.index=new e.default(n.length);for(const t of n){const{x0:n,y0:i,x1:e,y1:s}=t;this.index.add(n,i,e,s)}this.index.finish()}}_normalize(n){let{x0:t,y0:i,x1:e,y1:s}=n;return t>e&&([t,e]=[e,t]),i>s&&([i,s]=[s,i]),{x0:t,y0:i,x1:e,y1:s}}get bbox(){if(null==this.index)return s.empty();{const{minX:n,minY:t,maxX:i,maxY:e}=this.index;return{x0:n,y0:t,x1:i,y1:e}}}search(n){if(null==this.index)return[];{const{x0:t,y0:i,x1:e,y1:s}=this._normalize(n);return this.index.search(t,i,e,s).map(n=>this.points[n])}}indices(n){return this.search(n).map(({i:n})=>n)}}i.SpatialIndex=r,r.__name__=\"SpatialIndex\"},\n",
+ " function _(t,s,i){Object.defineProperty(i,\"__esModule\",{value:!0});const e=t(1).__importDefault(t(87)),h=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];class n{static from(t){if(!(t instanceof ArrayBuffer))throw new Error(\"Data must be an instance of ArrayBuffer.\");const[s,i]=new Uint8Array(t,0,2);if(251!==s)throw new Error(\"Data does not appear to be in a Flatbush format.\");if(i>>4!=3)throw new Error(`Got v${i>>4} data when expected v3.`);const[e]=new Uint16Array(t,2,1),[o]=new Uint32Array(t,4,1);return new n(o,e,h[15&i],t)}constructor(t,s=16,i=Float64Array,n){if(void 0===t)throw new Error(\"Missing required argument: numItems.\");if(isNaN(t)||t<=0)throw new Error(`Unpexpected numItems value: ${t}.`);this.numItems=+t,this.nodeSize=Math.min(Math.max(+s,2),65535);let o=t,r=o;this._levelBounds=[4*o];do{o=Math.ceil(o/this.nodeSize),r+=o,this._levelBounds.push(4*r)}while(1!==o);this.ArrayType=i||Float64Array,this.IndexArrayType=r<16384?Uint16Array:Uint32Array;const a=h.indexOf(this.ArrayType),_=4*r*this.ArrayType.BYTES_PER_ELEMENT;if(a<0)throw new Error(`Unexpected typed array class: ${i}.`);n&&n instanceof ArrayBuffer?(this.data=n,this._boxes=new this.ArrayType(this.data,8,4*r),this._indices=new this.IndexArrayType(this.data,8+_,r),this._pos=4*r,this.minX=this._boxes[this._pos-4],this.minY=this._boxes[this._pos-3],this.maxX=this._boxes[this._pos-2],this.maxY=this._boxes[this._pos-1]):(this.data=new ArrayBuffer(8+_+r*this.IndexArrayType.BYTES_PER_ELEMENT),this._boxes=new this.ArrayType(this.data,8,4*r),this._indices=new this.IndexArrayType(this.data,8+_,r),this._pos=0,this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0,new Uint8Array(this.data,0,2).set([251,48+a]),new Uint16Array(this.data,2,1)[0]=s,new Uint32Array(this.data,4,1)[0]=t),this._queue=new e.default}add(t,s,i,e){const h=this._pos>>2;return this._indices[h]=h,this._boxes[this._pos++]=t,this._boxes[this._pos++]=s,this._boxes[this._pos++]=i,this._boxes[this._pos++]=e,t>1;s[h]>t?e=h:i=h+1}return s[i]}function a(t,s,i,e,h){const n=t[e];t[e]=t[h],t[h]=n;const o=4*e,r=4*h,a=s[o],_=s[o+1],d=s[o+2],x=s[o+3];s[o]=s[r],s[o+1]=s[r+1],s[o+2]=s[r+2],s[o+3]=s[r+3],s[r]=a,s[r+1]=_,s[r+2]=d,s[r+3]=x;const l=i[e];i[e]=i[h],i[h]=l}function _(t,s){let i=t^s,e=65535^i,h=65535^(t|s),n=t&(65535^s),o=i|e>>1,r=i>>1^i,a=h>>1^e&n>>1^h,_=i&h>>1^n>>1^n;i=o,e=r,h=a,n=_,o=i&i>>2^e&e>>2,r=i&e>>2^e&(i^e)>>2,a^=i&h>>2^e&n>>2,_^=e&h>>2^(i^e)&n>>2,i=o,e=r,h=a,n=_,o=i&i>>4^e&e>>4,r=i&e>>4^e&(i^e)>>4,a^=i&h>>4^e&n>>4,_^=e&h>>4^(i^e)&n>>4,i=o,e=r,h=a,n=_,a^=i&h>>8^e&n>>8,_^=e&h>>8^(i^e)&n>>8,i=a^a>>1,e=_^_>>1;let d=t^s,x=e|65535^(d|i);return d=16711935&(d|d<<8),d=252645135&(d|d<<4),d=858993459&(d|d<<2),d=1431655765&(d|d<<1),x=16711935&(x|x<<8),x=252645135&(x|x<<4),x=858993459&(x|x<<2),x=1431655765&(x|x<<1),(x<<1|d)>>>0}i.default=n},\n",
+ " function _(s,t,i){Object.defineProperty(i,\"__esModule\",{value:!0});i.default=class{constructor(){this.ids=[],this.values=[],this.length=0}clear(){this.length=0}push(s,t){let i=this.length++;for(this.ids[i]=s,this.values[i]=t;i>0;){const s=i-1>>1,h=this.values[s];if(t>=h)break;this.ids[i]=this.ids[s],this.values[i]=h,i=s}this.ids[i]=s,this.values[i]=t}pop(){if(0===this.length)return;const s=this.ids[0];if(this.length--,this.length>0){const s=this.ids[0]=this.ids[this.length],t=this.values[0]=this.values[this.length],i=this.length>>1;let h=0;for(;h=t)break;this.ids[h]=e,this.values[h]=l,h=s}this.ids[h]=s,this.values[h]=t}return s}peek(){if(0!==this.length)return this.ids[0]}peekValue(){if(0!==this.length)return this.values[0]}}},\n",
+ " function _(t,i,e){Object.defineProperty(e,\"__esModule\",{value:!0});const{min:h,max:r}=Math;e.empty=function(){return{x0:1/0,y0:1/0,x1:-1/0,y1:-1/0}},e.positive_x=function(){return{x0:Number.MIN_VALUE,y0:-1/0,x1:1/0,y1:1/0}},e.positive_y=function(){return{x0:-1/0,y0:Number.MIN_VALUE,x1:1/0,y1:1/0}},e.union=function(t,i){return{x0:h(t.x0,i.x0),x1:r(t.x1,i.x1),y0:h(t.y0,i.y0),y1:r(t.y1,i.y1)}};class s{constructor(t){if(null==t)this.x0=0,this.y0=0,this.x1=0,this.y1=0;else if(\"x0\"in t){const{x0:i,y0:e,x1:h,y1:r}=t;if(!(i<=h&&e<=r))throw new Error(`invalid bbox {x0: ${i}, y0: ${e}, x1: ${h}, y1: ${r}}`);this.x0=i,this.y0=e,this.x1=h,this.y1=r}else if(\"x\"in t){const{x:i,y:e,width:h,height:r}=t;if(!(h>=0&&r>=0))throw new Error(`invalid bbox {x: ${i}, y: ${e}, width: ${h}, height: ${r}}`);this.x0=i,this.y0=e,this.x1=i+h,this.y1=e+r}else{let i,e,h,r;if(\"width\"in t)if(\"left\"in t)i=t.left,e=i+t.width;else if(\"right\"in t)e=t.right,i=e-t.width;else{const h=t.width/2;i=t.hcenter-h,e=t.hcenter+h}else i=t.left,e=t.right;if(\"height\"in t)if(\"top\"in t)h=t.top,r=h+t.height;else if(\"bottom\"in t)r=t.bottom,h=r-t.height;else{const i=t.height/2;h=t.vcenter-i,r=t.vcenter+i}else h=t.top,r=t.bottom;if(!(i<=e&&h<=r))throw new Error(`invalid bbox {left: ${i}, top: ${h}, right: ${e}, bottom: ${r}}`);this.x0=i,this.y0=h,this.x1=e,this.y1=r}}toString(){return`BBox({left: ${this.left}, top: ${this.top}, width: ${this.width}, height: ${this.height}})`}get left(){return this.x0}get top(){return this.y0}get right(){return this.x1}get bottom(){return this.y1}get p0(){return[this.x0,this.y0]}get p1(){return[this.x1,this.y1]}get x(){return this.x0}get y(){return this.y0}get width(){return this.x1-this.x0}get height(){return this.y1-this.y0}get rect(){return{x0:this.x0,y0:this.y0,x1:this.x1,y1:this.y1}}get box(){return{x:this.x,y:this.y,width:this.width,height:this.height}}get h_range(){return{start:this.x0,end:this.x1}}get v_range(){return{start:this.y0,end:this.y1}}get ranges(){return[this.h_range,this.v_range]}get aspect(){return this.width/this.height}get hcenter(){return(this.left+this.right)/2}get vcenter(){return(this.top+this.bottom)/2}contains(t,i){return t>=this.x0&&t<=this.x1&&i>=this.y0&&i<=this.y1}clip(t,i){return t=0;t--)e.lineTo(s[t],i[t]);e.closePath(),r.call(e)}_render(e,t,{sx1:s,sx2:i,sy:r}){this.visuals.fill.doit&&(this.visuals.fill.set_value(e),this._inner(e,s,i,r,e.fill)),this.visuals.hatch.doit2(e,0,()=>this._inner(e,s,i,r,e.fill),()=>this.renderer.request_render())}_hit_point(e){const t=this.sy.length,s=new Float64Array(2*t),i=new Float64Array(2*t);for(let e=0,r=t;e=0;s--)e.lineTo(t[s],i[s]);e.closePath(),r.call(e)}_render(e,t,{sx:s,sy1:i,sy2:r}){this.visuals.fill.doit&&(this.visuals.fill.set_value(e),this._inner(e,s,i,r,e.fill)),this.visuals.hatch.doit2(e,0,()=>this._inner(e,s,i,r,e.fill),()=>this.renderer.request_render())}scenterx(e){return this.sx[e]}scentery(e){return(this.sy1[e]+this.sy2[e])/2}_hit_point(e){const t=this.sx.length,s=new Float64Array(2*t),i=new Float64Array(2*t);for(let e=0,r=t;e=0;t--)e.lineTo(this._upper_sx[t],this._upper_sy[t]);e.closePath(),this.visuals.fill.doit&&(this.visuals.fill.set_value(e),e.fill()),e.beginPath(),e.moveTo(this._lower_sx[0],this._lower_sy[0]);for(let t=0,s=this._lower_sx.length;tnew o.ColumnDataSource],x_range_name:[a.String,\"default\"],y_range_name:[a.String,\"default\"]}),this.override({fill_color:\"#fff9ba\",fill_alpha:.4,line_color:\"#cccccc\",line_alpha:.3})}}s.Band=h,h.__name__=\"Band\",h.init_Band()},\n",
+ " function _(t,i,e){Object.defineProperty(e,\"__esModule\",{value:!0});const s=t(1),n=t(31),o=t(14),l=s.__importStar(t(23)),a=s.__importStar(t(18)),r=t(88);e.EDGE_TOLERANCE=2.5;class h extends n.AnnotationView{connect_signals(){super.connect_signals(),this.connect(this.model.change,()=>this.plot_view.request_paint(this)),this.connect(this.model.data_update,()=>this.plot_view.request_paint(this))}render(){if(!this.model.visible)return;if(null==this.model.left&&null==this.model.right&&null==this.model.top&&null==this.model.bottom)return;const{frame:t}=this.plot_view,i=t.xscales[this.model.x_range_name],e=t.yscales[this.model.y_range_name],s=(t,i,e,s,n)=>{let o;return o=null!=t?this.model.screen?t:\"data\"==i?e.compute(t):s.compute(t):n,o};this.sleft=s(this.model.left,this.model.left_units,i,t.xview,t._left.value),this.sright=s(this.model.right,this.model.right_units,i,t.xview,t._right.value),this.stop=s(this.model.top,this.model.top_units,e,t.yview,t._top.value),this.sbottom=s(this.model.bottom,this.model.bottom_units,e,t.yview,t._bottom.value),this._paint_box(this.sleft,this.sright,this.sbottom,this.stop)}_paint_box(t,i,e,s){const{ctx:n}=this.layer;n.save(),n.beginPath(),n.rect(t,s,i-t,e-s),this.visuals.fill.doit&&(this.visuals.fill.set_value(n),n.fill()),this.visuals.line.doit&&(this.visuals.line.set_value(n),n.stroke()),n.restore()}interactive_bbox(){const t=this.model.properties.line_width.value()+e.EDGE_TOLERANCE;return new r.BBox({x0:this.sleft-t,y0:this.stop-t,x1:this.sright+t,y1:this.sbottom+t})}interactive_hit(t,i){if(null==this.model.in_cursor)return!1;return this.interactive_bbox().contains(t,i)}cursor(t,i){return Math.abs(t-this.sleft)<3||Math.abs(t-this.sright)<3?this.model.ew_cursor:Math.abs(i-this.sbottom)<3||Math.abs(i-this.stop)<3?this.model.ns_cursor:t>this.sleft&&t=1;r?s++:s--){if(t){e[0]=i[0].toExponential(s);for(let t=1;tnew a.TeeHead({level:\"underlay\",size:10})],upper:[h.DistanceSpec],upper_head:[h.Instance,()=>new a.TeeHead({level:\"underlay\",size:10})],base:[h.DistanceSpec],dimension:[h.Dimension,\"height\"],source:[h.Instance,()=>new o.ColumnDataSource],x_range_name:[h.String,\"default\"],y_range_name:[h.String,\"default\"]}),this.override({level:\"underlay\"})}}s.Whisker=l,l.__name__=\"Whisker\",l.init_Whisker()},\n",
+ " function _(i,a,e){Object.defineProperty(e,\"__esModule\",{value:!0});var r=i(150);e.Axis=r.Axis;var s=i(152);e.CategoricalAxis=s.CategoricalAxis;var x=i(155);e.ContinuousAxis=x.ContinuousAxis;var A=i(156);e.DatetimeAxis=A.DatetimeAxis;var o=i(157);e.LinearAxis=o.LinearAxis;var t=i(170);e.LogAxis=t.LogAxis;var n=i(173);e.MercatorAxis=n.MercatorAxis},\n",
+ " function _(e,t,i){Object.defineProperty(i,\"__esModule\",{value:!0});const s=e(1),a=e(151),l=s.__importStar(e(23)),n=s.__importStar(e(18)),o=e(9),r=e(8),_=e(90),{abs:h,min:c,max:m}=Math;class d extends a.GuideRendererView{constructor(){super(...arguments),this.rotate=!0}get panel(){return this.layout}render(){if(!this.model.visible)return;const e={tick:this._tick_extent(),tick_label:this._tick_label_extents(),axis_label:this._axis_label_extent()},t=this.tick_coords,i=this.layer.ctx;i.save(),this._draw_rule(i,e),this._draw_major_ticks(i,e,t),this._draw_minor_ticks(i,e,t),this._draw_major_labels(i,e,t),this._draw_axis_label(i,e,t),null!=this._render&&this._render(i,e,t),i.restore()}connect_signals(){super.connect_signals(),this.connect(this.model.change,()=>this.plot_view.request_paint());const e=this.model.properties;this.on_change(e.visible,()=>this.plot_view.request_layout())}get_size(){if(this.model.visible&&null==this.model.fixed_location){const e=this._get_size();return{width:0,height:Math.round(e)}}return{width:0,height:0}}_get_size(){return this._tick_extent()+this._tick_label_extent()+this._axis_label_extent()}get needs_clip(){return null!=this.model.fixed_location}_draw_rule(e,t){if(!this.visuals.axis_line.doit)return;const[i,s]=this.rule_coords,[a,l]=this.plot_view.map_to_screen(i,s,this.model.x_range_name,this.model.y_range_name),[n,o]=this.normals,[r,_]=this.offsets;this.visuals.axis_line.set_value(e),e.beginPath(),e.moveTo(Math.round(a[0]+n*r),Math.round(l[0]+o*_));for(let t=1;t{const t=n.isPlainObject(this.cols)?this.cols[i]||this.cols[\"*\"]:this.cols;return null==t?{policy:\"auto\"}:n.isNumber(t)?{policy:\"fixed\",width:t}:n.isString(t)?{policy:t}:t})(),e=s.align||\"auto\";if(\"fixed\"==s.policy)o[i]={policy:\"fixed\",width:s.width,align:e};else if(\"min\"==s.policy)o[i]={policy:\"min\",align:e};else if(\"fit\"==s.policy||\"max\"==s.policy)o[i]={policy:s.policy,flex:s.flex||1,align:e};else{if(\"auto\"!=s.policy)throw new Error(\"unrechable\");h.some(t.col(i),t=>t.is_width_expanding())?o[i]={policy:\"max\",flex:1,align:e}:o[i]={policy:\"min\",align:e}}}const[r,l]=n.isNumber(this.spacing)?[this.spacing,this.spacing]:this.spacing;this._state={items:t,nrows:i,ncols:s,rows:e,cols:o,rspacing:r,cspacing:l}}_measure_totals(t,i){const{nrows:s,ncols:e,rspacing:o,cspacing:n}=this._state;return{height:h.sum(t)+(s-1)*o,width:h.sum(i)+(e-1)*n}}_measure_cells(t){const{items:i,nrows:s,ncols:o,rows:n,cols:r,rspacing:h,cspacing:a}=this._state,p=new Array(s);for(let t=0;t{const{r0:o,c0:g,r1:d,c1:w}=i,u=(d-o)*h,m=(w-g)*a;let y=0;for(let i=o;i<=d;i++)y+=t(i,g).height;y+=u;let x=0;for(let i=g;i<=w;i++)x+=t(o,i).width;x+=m;const b=s.measure({width:x,height:y});f.add(i,{layout:s,size_hint:b});const z=new e.Sizeable(b).grow_by(s.sizing.margin);z.height-=u,z.width-=m;const j=[];for(let t=o;t<=d;t++){const i=n[t];\"fixed\"==i.policy?z.height-=i.height:j.push(t)}if(z.height>0){const t=c(z.height/j.length);for(const i of j)p[i]=l(p[i],t)}const O=[];for(let t=g;t<=w;t++){const i=r[t];\"fixed\"==i.policy?z.width-=i.width:O.push(t)}if(z.width>0){const t=c(z.width/O.length);for(const i of O)_[i]=l(_[i],t)}}),{size:this._measure_totals(p,_),row_heights:p,col_widths:_,size_hints:f}}_measure_grid(t){const{nrows:i,ncols:s,rows:e,cols:o,rspacing:n,cspacing:r}=this._state,h=this._measure_cells((t,i)=>{const s=e[t],n=o[i];return{width:\"fixed\"==n.policy?n.width:1/0,height:\"fixed\"==s.policy?s.height:1/0}});let a;a=\"fixed\"==this.sizing.height_policy&&null!=this.sizing.height?this.sizing.height:t.height!=1/0&&this.is_height_expanding()?t.height:h.size.height;let g,p=0;for(let t=0;t0)for(let t=0;ti?i:e,t--}}}g=\"fixed\"==this.sizing.width_policy&&null!=this.sizing.width?this.sizing.width:t.width!=1/0&&this.is_width_expanding()?t.width:h.size.width;let _=0;for(let t=0;t0)for(let t=0;ts?s:o,t--}}}const{row_heights:f,col_widths:d,size_hints:w}=this._measure_cells((t,i)=>({width:h.col_widths[i],height:h.row_heights[t]}));return{size:this._measure_totals(f,d),row_heights:f,col_widths:d,size_hints:w}}_measure(t){const{size:i}=this._measure_grid(t);return i}_set_geometry(t,i){super._set_geometry(t,i);const{nrows:s,ncols:e,rspacing:o,cspacing:n}=this._state,{row_heights:h,col_widths:g,size_hints:p}=this._measure_grid(t),_=this._state.rows.map((t,i)=>Object.assign(Object.assign({},t),{top:0,height:h[i],get bottom(){return this.top+this.height}})),f=this._state.cols.map((t,i)=>Object.assign(Object.assign({},t),{left:0,width:g[i],get right(){return this.left+this.width}})),d=p.map((t,i)=>Object.assign(Object.assign({},i),{outer:new r.BBox,inner:new r.BBox}));for(let i=0,e=this.absolute?t.top:0;i{const{layout:l,size_hint:a}=h,{sizing:g}=l,{width:p,height:d}=a,w=function(t,i){let s=(i-t)*n;for(let e=t;e<=i;e++)s+=f[e].width;return s}(i,e),u=function(t,i){let s=(i-t)*o;for(let e=t;e<=i;e++)s+=_[e].height;return s}(t,s),m=i==e&&\"auto\"!=f[i].align?f[i].align:g.halign,y=t==s&&\"auto\"!=_[t].align?_[t].align:g.valign;let x=f[i].left;\"start\"==m?x+=g.margin.left:\"center\"==m?x+=c((w-p)/2):\"end\"==m&&(x+=w-g.margin.right-p);let b=_[t].top;\"start\"==y?b+=g.margin.top:\"center\"==y?b+=c((u-d)/2):\"end\"==y&&(b+=u-g.margin.bottom-d),h.outer=new r.BBox({left:x,top:b,width:p,height:d})});const w=_.map(()=>({start:new a(()=>0),end:new a(()=>0)})),u=f.map(()=>({start:new a(()=>0),end:new a(()=>0)}));d.foreach(({r0:t,c0:i,r1:s,c1:e},{size_hint:o,outer:n})=>{const{inner:r}=o;null!=r&&(w[t].start.apply(n.top,t=>l(t,r.top)),w[s].end.apply(_[s].bottom-n.bottom,t=>l(t,r.bottom)),u[i].start.apply(n.left,t=>l(t,r.left)),u[e].end.apply(f[e].right-n.right,t=>l(t,r.right)))}),d.foreach(({r0:t,c0:i,r1:s,c1:e},o)=>{const{size_hint:n,outer:h}=o;function l({left:t,right:i,top:s,bottom:e}){const o=h.width-t-i,n=h.height-s-e;return new r.BBox({left:t,top:s,width:o,height:n})}if(null!=n.inner){let r=l(n.inner);if(!1!==n.align){const o=w[t].start.get(h.top),n=w[s].end.get(_[s].bottom-h.bottom),c=u[i].start.get(h.left),a=u[e].end.get(f[e].right-h.right);try{r=l({top:o,bottom:n,left:c,right:a})}catch(t){}}o.inner=r}else o.inner=h}),d.foreach((t,{layout:i,outer:s,inner:e})=>{i.set_geometry(s,e)})}}s.Grid=p,p.__name__=\"Grid\";class _ extends p{constructor(t){super(),this.items=t.map((t,i)=>({layout:t,row:0,col:i})),this.rows=\"fit\"}}s.Row=_,_.__name__=\"Row\";class f extends p{constructor(t){super(),this.items=t.map((t,i)=>({layout:t,row:i,col:0})),this.cols=\"fit\"}}s.Column=f,f.__name__=\"Column\"},\n",
+ " function _(e,t,s){Object.defineProperty(s,\"__esModule\",{value:!0});const n=e(190),i=e(189),a=e(68);class c extends n.ContentLayoutable{constructor(e){super(),this.content_size=a.unsized(e,()=>new i.Sizeable(a.size(e)))}_content_size(){return this.content_size}}s.ContentBox=c,c.__name__=\"ContentBox\";class o extends n.Layoutable{constructor(e){super(),this.el=e}_measure(e){const t=new i.Sizeable(e).bounded_to(this.sizing.size);return a.sized(this.el,t,()=>{const e=new i.Sizeable(a.content_size(this.el)),{border:t,padding:s}=a.extents(this.el);return e.grow_by(t).grow_by(s).map(Math.ceil)})}}s.VariadicBox=o,o.__name__=\"VariadicBox\";class r extends o{constructor(e){super(e),this._cache=new Map}_measure(e){const{width:t,height:s}=e,n=`${t},${s}`;let i=this._cache.get(n);return null==i&&(i=super._measure(e),this._cache.set(n,i)),i}invalidate_cache(){this._cache.clear()}}s.CachedVariadicBox=r,r.__name__=\"CachedVariadicBox\"},\n",
+ " function _(e,r,u){Object.defineProperty(u,\"__esModule\",{value:!0});var a=e(195);u.Expression=a.Expression;var n=e(196);u.Stack=n.Stack;var o=e(197);u.CumSum=o.CumSum},\n",
+ " function _(e,t,s){Object.defineProperty(s,\"__esModule\",{value:!0});const n=e(71);class i extends n.Model{constructor(e){super(e)}initialize(){super.initialize(),this._connected=new Set,this._result=new Map}v_compute(e){this._connected.has(e)||(this.connect(e.change,()=>this._result.delete(e)),this.connect(e.patching,()=>this._result.delete(e)),this.connect(e.streaming,()=>this._result.delete(e)),this._connected.add(e));let t=this._result.get(e);return null==t&&(t=this._v_compute(e),this._result.set(e,t)),t}}s.Expression=i,i.__name__=\"Expression\"},\n",
+ " function _(t,e,n){Object.defineProperty(n,\"__esModule\",{value:!0});const i=t(1),o=t(195),r=i.__importStar(t(18));class s extends o.Expression{constructor(t){super(t)}static init_Stack(){this.define({fields:[r.Array,[]]})}_v_compute(t){var e;const n=null!==(e=t.get_length())&&void 0!==e?e:0,i=new Float64Array(n);for(const e of this.fields){const o=t.data[e];if(null!=o)for(let t=0,e=Math.min(n,o.length);t