!pip install yfinance

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.statespace.sarimax import SARIMAX
from sklearn.metrics import mean_squared_error
import yfinance as yf

# Download historical data
symbol = "CADJPY=X"
start_date = "2023-03-01"
end_date = "2023-06-01"
data = yf.download(symbol, start=start_date, end=end_date, interval='1d')
data = data.dropna()

# Calculate daily returns
data['Return'] = data['Close'].pct_change()
data = data.dropna()

# SARIMA model with exogenous variables
sarima_model = SARIMAX(data['Close'],
                       exog=data[['Open', 'High', 'Low', 'Volume']],
                       order=(1, 0, 1),
                       seasonal_order=(1, 1, 1, 5))
sarima_fit = sarima_model.fit(disp=False)

# Forecast using SARIMA
forecast_steps_final = 30
forecast_final = sarima_fit.get_forecast(steps=forecast_steps_final, exog=data[['Open', 'High', 'Low', 'Volume']].tail(30))
forecast_index_final = pd.date_range(data.index[-1] + pd.Timedelta(days=1), periods=forecast_steps_final, freq='B')
forecast_values_final = forecast_final.predicted_mean

# Function for Heston model simulation
def heston_model_simulation(initial_price, kappa, theta, sigma, rho, v0, r, T, time_steps):
    dt = T / time_steps
    prices = [initial_price]
    volatilities = [v0]

    for _ in range(time_steps):
        z1 = np.random.normal(0, 1)
        z2 = rho * z1 + np.sqrt(1 - rho**2) * np.random.normal(0, 1)

        # Update volatility using Heston model
        vol_t = volatilities[-1] + kappa * (theta - volatilities[-1]) * dt + sigma * np.sqrt(volatilities[-1]) * np.sqrt(dt) * z2
        vol_t = np.maximum(vol_t, 0.0001)  # Ensure volatility is non-negative

        # Update price using geometric Brownian motion with stochastic volatility
        price_t = prices[-1] * np.exp((r - 0.5 * vol_t) * dt + np.sqrt(vol_t) * np.sqrt(dt) * z1)

        prices.append(price_t)
        volatilities.append(vol_t)

    return np.array(prices), np.array(volatilities)

    # Function for Monte Carlo simulation with geometric Brownian motion
def monte_carlo_simulation(initial_price, mean_return, std_return, forecast_steps, n_simulations):
    simulated_trajectories = []

    for _ in range(n_simulations):
        simulated_returns = np.random.normal(mean_return, std_return, forecast_steps)
        simulated_prices = [initial_price]

        for return_in in simulated_returns:
            simulated_price = simulated_prices[-1] * (1 + return_in)
            simulated_prices.append(simulated_price)

        simulated_trajectories.append(simulated_prices)

    return np.array(simulated_trajectories)

# Simulate Heston model
heston_simulated_prices, _ = heston_model_simulation(data['Close'].iloc[-1], kappa=1.5, theta=0.04, sigma=0.3, rho=-0.7, v0=0.04, r=0.01, T=1, time_steps=forecast_steps_final)
# Simulate Monte Carlo with geometric Brownian motion
monte_carlo_simulated_trajectories = monte_carlo_simulation(data['Close'].iloc[-1], mean_return=data['Return'].mean(), std_return=data['Return'].std(), forecast_steps=forecast_steps_final, n_simulations=10000)
# Ensure that heston_simulated_prices and monte_carlo_simulated_trajectories have the same length
common_length = min(len(heston_simulated_prices[1:]), len(monte_carlo_simulated_trajectories[0]))
# Combine Heston and Monte Carlo results
combined_simulation_results = (heston_simulated_prices[1:common_length + 1] + np.mean(monte_carlo_simulated_trajectories[:, :common_length], axis=0)) / 2
# Combine SARIMA and simulation results
final_combined_forecast = (forecast_values_final + combined_simulation_results) / 2
# Calculate additional metrics
mse_combined_forecast = mean_squared_error(data['Close'].tail(forecast_steps_final), final_combined_forecast)
percentage_error_final_combined = np.abs((data['Close'].tail(forecast_steps_final).values - final_combined_forecast) / data['Close'].tail(forecast_steps_final).values)

 عندما اقوم بتشغيل هذا الكود تظهر هذه الرساله الخطا    ValueError                                Traceback (most recent call last)
<ipython-input-4-2369f59bf864> in <cell line: 81>()
     79 combined_simulation_results = (heston_simulated_prices[1:common_length + 1] + np.mean(monte_carlo_simulated_trajectories[:, :common_length], axis=0)) / 2
     80 # Combine SARIMA and simulation results
---> 81 final_combined_forecast = (forecast_values_final + combined_simulation_results) / 2
     82 # Calculate additional metrics
     83 mse_combined_forecast = mean_squared_error(data['Close'].tail(forecast_steps_final), final_combined_forecast)

7 frames
/usr/local/lib/python3.10/dist-packages/pandas/core/ops/common.py in new_method(self, other)
     74         other = item_from_zerodim(other)
     75 
---> 76         return method(self, other)
     77 
     78     return new_method

/usr/local/lib/python3.10/dist-packages/pandas/core/arraylike.py in __add__(self, other)
    184         moose     3.0     NaN
    185         """
--> 186         return self._arith_method(other, operator.add)
    187 
    188     @unpack_zerodim_and_defer("__radd__")

/usr/local/lib/python3.10/dist-packages/pandas/core/series.py in _arith_method(self, other, op)
   6133     def _arith_method(self, other, op):
   6134         self, other = self._align_for_op(other)
-> 6135         return base.IndexOpsMixin._arith_method(self, other, op)
   6136 
   6137     def _align_for_op(self, right, align_asobject: bool = False):

/usr/local/lib/python3.10/dist-packages/pandas/core/base.py in _arith_method(self, other, op)
   1382             result = ops.arithmetic_op(lvalues, rvalues, op)
   1383 
-> 1384         return self._construct_result(result, name=res_name)
   1385 
   1386     def _construct_result(self, result, name):

/usr/local/lib/python3.10/dist-packages/pandas/core/series.py in _construct_result(self, result, name)
   6229         #  JSONArray tests
   6230         dtype = getattr(result, "dtype", None)
-> 6231         out = self._constructor(result, index=self.index, dtype=dtype, copy=False)
   6232         out = out.__finalize__(self)
   6233 

/usr/local/lib/python3.10/dist-packages/pandas/core/series.py in __init__(self, data, index, dtype, name, copy, fastpath)
    582                 data = data.copy()
    583         else:
--> 584             data = sanitize_array(data, index, dtype, copy)
    585 
    586             manager = _get_option("mode.data_manager", silent=True)

/usr/local/lib/python3.10/dist-packages/pandas/core/construction.py in sanitize_array(data, index, dtype, copy, allow_2d)
    657                 subarr = maybe_infer_to_datetimelike(subarr)
    658 
--> 659     subarr = _sanitize_ndim(subarr, data, dtype, index, allow_2d=allow_2d)
    660 
    661     if isinstance(subarr, np.ndarray):

/usr/local/lib/python3.10/dist-packages/pandas/core/construction.py in _sanitize_ndim(result, data, dtype, index, allow_2d)
    716             if allow_2d:
    717                 return result
--> 718             raise ValueError(
    719                 f"Data must be 1-dimensional, got ndarray of shape {data.shape} instead"
    720             )

ValueError: Data must be 1-dimensional, got ndarray of shape (30, 30) instead