<jupyter_start><jupyter_text>Maximum daily fluctuation in this stock is 15 %<jupyter_code># Average daily returns
sns.distplot(df['Daily_return'], bins = 1000, color = 'b')
df['Daily_return'].hist(bins = 100, figsize = (10,5))<jupyter_output><empty_output><jupyter_text>Daily fluctuation of stock normal distribution is between +-2 %<jupyter_code>ser = np.array(range(len(df)))
ind_series = pd.Series(ser)
len(ind_series)
df.set_index = ind_series
df.head()
df2 = df.drop(['Date','Close_10','Close_50'],axis = 1, errors = 'ignore')
df2.head()
df2_pct = df2.pct_change()
df2_pct = pd.DataFrame(df2_pct)
df2_pct['Date'] = df['Date']
df2_pct.head()
df2_pct['Close'].quantile(0.05)
# -0.042 means that 95% of the times the worst daily Loss will not exceed 4.25%
# Value at risk using Monte Carlo simulation
days = 365
dt = 1/365
mu = df2_pct.mean()['Close']
sigma = df2_pct.std()['Close']
def monte_price(start,days,mu,sigma):
    price = np.zeros(days)
    price[0] = start
    shock = np.zeros(days)
    drift = np.zeros(days)
    
    for x in range(1,days):
        shock[x] = np.random.normal(loc = mu*dt, scale = sigma*np.sqrt(dt))
        drift[x] = mu*dt
        price[x] = price[x-1] + (price[x-1] * (drift[x] + shock[x]))
    return price
df.head()
start = 29.959999
for i in range(100):
    plt.plot(monte_price(start,days,mu,sigma))

plt.xlabel('Days')
plt.ylabel('Close Price')
plt.title('Monte carlo simulation for Tesla')
plt.ioff()
runs = 10000
simulations = np.zeros(runs)

for run in range(runs):
    simulations[run] = monte_price(start,days, mu, sigma)[days - 1]
q = np.percentile(simulations,1)
sns.histplot(simulations)

# starting price
plt.figtext(0.6,0.8, s="Start price: $%.2f" %start)

# Mean close price
plt.axvline(x = simulations.mean(), linewidth = 2, color = 'g')
plt.figtext(0.6,0.7, s="Mean close price: $%.2f" %simulations.mean())

# Variance of price within 99% confidence level
plt.figtext(0.6,0.6, s="Var(0.99): $%.2f" %(start - q,))

# 1% quantile result
plt.figtext(0.15, 0.6, "q(0.99): $%.2f" % q)
plt.axvline(x = q, linewidth = 4, color = 'r')

plt.title('Tesla Closing price distribution after 365 days', weight = 'bold')
import statsmodels.api as sm
import statsmodels.tsa.api as smt
def tsplot(y, lags=None, figsize=(12, 7), style='bmh'):
    """
        Plot time series, its ACF and PACF, calculate Dickey–Fuller test
        
        y - timeseries
        lags - how many lags to include in ACF, PACF calculation
    """
    if not isinstance(y, pd.Series):
        y = pd.Series(y)
        
    with plt.style.context(style):    
        fig = plt.figure(figsize=figsize)
        layout = (2, 2)
        ts_ax = plt.subplot2grid(layout, (0, 0), colspan=2)
        acf_ax = plt.subplot2grid(layout, (1, 0))
        pacf_ax = plt.subplot2grid(layout, (1, 1))
        
        y.plot(ax=ts_ax)
        p_value = sm.tsa.stattools.adfuller(y)[1]
        ts_ax.set_title('Time Series Analysis Plots\n Dickey-Fuller: p={0:.5f}'.format(p_value))
        smt.graphics.plot_acf(y, lags=lags, ax=acf_ax)
        smt.graphics.plot_pacf(y, lags=lags, ax=pacf_ax)
        plt.tight_layout()
tsplot(df.Close, lags=60)
close_diff = df.Close - df.Close.shift(24)
tsplot(close_diff[24:], lags=60)
close_diff = close_diff - close_diff.shift(1)
tsplot(close_diff[24+1:], lags=60)
from tqdm import tqdm_notebook
from itertools import product 
import warnings
warnings.filterwarnings("ignore")
ps = range(4, 8)
d=1 
qs = range(5, 8)
Ps = range(0, 2)
D=1 
Qs = range(0, 2)
s = 24 #season length is still 24

# creating list with all the possible combinations of parameters
parameters = product(ps, qs, Ps, Qs)
parameters_list = list(parameters)
len(parameters_list)
def optimize_sarima(parameters_list,d,D,s):
    results = []
    best_aic = float('inf')
    
    for param in tqdm_notebook(parameters_list):
        try:
            model = sm.tsa.statespace.SARIMAX(df.Close, order=(param[0],d,param[1]),
                                              seasonal_order=(param[2], D, param[3], s)).fit(disp=-1)
        except:
            continue
        aic = model.aic
        if aic < best_aic:
            best_model = model
            best_aic = aic
            best_params = param
        results.append([param, model.aic])
    
    result_table = pd.DataFrame(results)
    result_table.columns = ['Parameters','aic']
    result_table = result_table.sort_values(by='aic',ascending = True).reset_index(drop=True)
    return result_table
%%time
result_table = optimize_sarima(parameters_list, d, D, s)
result_table.head()
p, q, P, Q = result_table.Parameters[0]

best_model=sm.tsa.statespace.SARIMAX(df.Close, order=(p, d, q), 
                                        seasonal_order=(P, D, Q, s)).fit(disp=-1)
print(best_model.summary())
tsplot(best_model.resid[24+1:], lags=60)
from sklearn.metrics import r2_score, median_absolute_error, mean_absolute_error
from sklearn.metrics import median_absolute_error, mean_squared_error, mean_squared_log_error
def mean_absolute_percentage_error(y_true, y_pred): 
    return np.mean(np.abs((y_true - y_pred) / y_true)) * 100
def plotSARIMA(series, model, n_steps):
    # adding model values
    data = pd.Series(series.copy())
    dataframe = pd.DataFrame(data)
    dataframe.columns = ['actual']
    dataframe['arima_model'] = model.fittedvalues
    # making a shift on s+d steps, because these values were unobserved by the model
    # due to the differentiating
    dataframe['arima_model'][:s+d] = np.NaN
    
    # forecasting on n_steps forward 
    forecast = model.predict(start = dataframe.shape[0], end = dataframe.shape[0]+n_steps)
    forecast = dataframe.arima_model.append(forecast)
    # calculate error, again having shifted on s+d steps from the beginning
    error = mean_absolute_percentage_error(dataframe.actual[s+d:], dataframe.arima_model[s+d:])

    plt.figure(figsize=(15, 7))
    plt.title("Mean Absolute Percentage Error: {0:.2f}%".format(error))
    plt.plot(forecast, color='r', label="model")
    plt.axvspan(dataframe.index[-1], forecast.index[-1], alpha=0.5, color='lightgrey')
    plt.plot(dataframe.actual, label="actual")
    plt.legend()
    plt.grid(True);
# Forecasting of next 100 days
plotSARIMA(df.Close, best_model, 100)
new_df = pd.DataFrame(df.Close.copy())
new_df.columns = ['y']
for i in range(6,25):
    new_df['lag_{}'.format(i)] = new_df.y.shift(i)
new_df.tail()
# Prediction using linear model
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=5)
def time_series_train_test_split(X,y,test_size):
    test_index = int(len(X)*(1-test_size))
    
    X_train = X.iloc[:test_index]
    X_test = X.iloc[test_index:]
    y_train = y.iloc[:test_index]
    y_test = y.iloc[test_index:]
    
    return X_train, y_train, X_test, y_test
X = new_df.dropna().drop(['y'],axis = 1)
y = new_df.dropna().y
X_train, y_train, X_test, y_test = time_series_train_test_split(X,y,0.3)
lr = LinearRegression()
lr.fit(X_train,y_train)
lr.score(X_test,y_test)
from sklearn.ensemble import  RandomForestRegressor
model_rf = RandomForestRegressor()
model_rf.fit(X_train,y_train)
model_rf.score(X_test,y_test)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1411861841199945, 'fraction_numerical': 0.02642080638502821, 'mean_word_length': 3.920785375761679, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '586911', 'license': 'Apache-2.0', 'n_tokens_mistral': 2821, 'n_tokens_neox': 2669, 'n_words': 576, 'path': 'Tesla Price Prediction- Time Series Analysis.ipynb', 'repo_name': 'Code-SameerKhan/Jupyter_Notebooks', 'size': '7267'}