S&P 500の過去データにレバレッジをかけて観察する
>現在の算出方式は、1941年から1943年における平均指数を10として、1957年3月4日からスタートしています。
>S&P 500®は1957年3月4日に指数の算出を開始
> 1957年以前のデーターは、現在のS&P500の前身の指標となります。
>現在の算出方式は、1941年から1943年における平均指数を10として、1957年3月4日からスタートしています。
素直に書くとこうなる
基本的なGBMモデルでは、期待リターンやボラティリティは全体での平均値を使用することが一般的です
正規化したS&P500と近似直線
切片 −0.211
傾き 約 0.000278
1997年からの実際のS&P 500データに基づいて計算した結果
μ(期待リターンの平均):0.0343%
σ(日次リターンの標準偏差):1.24%
始点をどこに取るかで結果が大きく変わる
2001年(ITバブル崩壊直前)からやっていたら3xよりもレバなしの方が高い
1990年からやっていれば3倍が一番高い
この場合にレバの商品に手数料が年利1%取られると
対数グラフ.py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from numpy.polynomial.polynomial import Polynomial
# Read the S&P 500 data
df = pd.read_csv('/path/to/your/csv/file.csv')
# Filter the data to start from March 4, 1957
df_1957 = df[df['Date'] >= '1957-03-04'].reset_index(drop=True)
# Convert the dates to numerical values (number of days since March 4, 1957)
x_data = np.arange(len(df_1957))
# Normalize the S&P 500 data to start from 1
normalized_s_1957 = df_1957['Close'] / df_1957['Close'].iloc[0]
# Fit a first-degree polynomial (a line) to the logarithmic data
p = Polynomial.fit(x_data, np.log(normalized_s_1957), 1)
# Generate y-values based on the fit
y_fit_log = p(x_data)
# Plotting the logarithmic graph and the fitted line
plt.figure(figsize=(15, 6))
plt.semilogy(x_data, normalized_s_1957, label='Normalized Actual S&P 500 (Log scale)', color='b')
plt.semilogy(x_data, np.exp(y_fit_log), label=f'Fitted Line', color='r')
plt.title('Logarithmic Plot of the Normalized Actual S&P 500 and Fitted Line (Starting from March 4, 1957)')
plt.xlabel('Number of Days')
plt.ylabel('Close Price (Log Scale, Normalized)')
plt.legend()
plt.grid(True)
plt.show()
# Show the coefficients of the fitted line
print("Coefficients of the fitted line:", p.convert().coef)
手数料あり.pyimport numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# Read the S&P 500 data
df = pd.read_csv('/path/to/your/csv/file.csv')
# Filtering the dataset to only include data from January 1, 1990, onwards
df_1990 = df[df['Date'] >= '1990-01-01'].reset_index(drop=True)
# Number of data points in the dataset starting from 1990
n_1990 = len(df_1990)
# Calculate the daily returns for the actual S&P 500 data starting from 1990
s_actual_1990 = df_1990['Close'].values
daily_returns_1990 = (s_actual_1990[1:] / s_actual_1990[:-1]) - 1
# Define the annual fee rate for 2x, 3x, and 4x leveraged products (1% annual fee)
annual_fee_rate = 0.01
daily_fee_multiplier = 1 - (annual_fee_rate / 252) # Assuming 252 trading days in a year
# Initialize arrays for 2x, 3x, and 4x leveraged products with daily rebalancing and fees starting from 1990
s_2x_leverage_daily_rebalance_fee_1990 = np.zeros(n_1990)
s_3x_leverage_daily_rebalance_fee_1990 = np.zeros(n_1990)
s_4x_leverage_daily_rebalance_fee_1990 = np.zeros(n_1990)
s_2x_leverage_daily_rebalance_fee_1990[0] = s_actual_1990[0]
s_3x_leverage_daily_rebalance_fee_1990[0] = s_actual_1990[0]
s_4x_leverage_daily_rebalance_fee_1990[0] = s_actual_1990[0]
# Perform the simulation with daily rebalancing and fees
for t in range(1, n_1990):
daily_return = (s_actual_1990[t] / s_actual_1990[t-1]) - 1
s_2x_leverage_daily_rebalance_fee_1990[t] = s_2x_leverage_daily_rebalance_fee_1990[t-1] * (1 + 2 * daily_return) * daily_fee_multiplier
s_3x_leverage_daily_rebalance_fee_1990[t] = s_3x_leverage_daily_rebalance_fee_1990[t-1] * (1 + 3 * daily_return) * daily_fee_multiplier
s_4x_leverage_daily_rebalance_fee_1990[t] = s_4x_leverage_daily_rebalance_fee_1990[t-1] * (1 + 4 * daily_return) * daily_fee_multiplier
# Normalize the leveraged products and actual S&P 500 to start from 100
normalized_s_actual_1990 = s_actual_1990 / s_actual_1990[0] * 100
normalized_s_2x_leverage_daily_rebalance_fee_1990 = s_2x_leverage_daily_rebalance_fee_1990 / s_2x_leverage_daily_rebalance_fee_1990[0] * 100
normalized_s_3x_leverage_daily_rebalance_fee_1990 = s_3x_leverage_daily_rebalance_fee_1990 / s_3x_leverage_daily_rebalance_fee_1990[0] * 100
normalized_s_4x_leverage_daily_rebalance_fee_1990 = s_4x_leverage_daily_rebalance_fee_1990 / s_4x_leverage_daily_rebalance_fee_1990[0] * 100
# Plotting the graph
plt.figure(figsize=(15, 6))
plt.plot(df_1990['Date'], normalized_s_actual_1990, label='Normalized Actual S&P 500', color='r')
plt.plot(df_1990['Date'], normalized_s_2x_leverage_daily_rebalance_fee_1990, label='Normalized 2x Leveraged with Fee (Daily Rebalance)', color='g')
plt.plot(df_1990['Date'], normalized_s_3x_leverage_daily_rebalance_fee_1990, label='Normalized 3x Leveraged with Fee (Daily Rebalance)', color='b')
plt.plot(df_1990['Date'], normalized_s_4x_leverage_daily_rebalance_fee_1990, label='Normalized 4x Leveraged with Fee (Daily Rebalance)', color='m')
plt.title('Normalized Actual S&P 500, 2x, 3x, and 4x Leveraged with Daily Rebalancing and Fees (Base Value = 100, Starting from 1990)')
plt.xlabel('Date')
plt.ylabel('Normalized Value')
plt.legend()
plt.grid(True)
plt.show()
1997年からの実際のS&P 500データに基づいて計算した結果
μ(期待リターンの平均):0.0343%
σ(日次リターンの標準偏差):1.24%
pyimport pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Load the data
df = pd.read_csv('/path/to/data.csv')
df['Date'] = pd.to_datetime(df['Date'])
# Filter data starting from 1997
df_1997 = df[df['Date'] >= '1997-01-01'].reset_index(drop=True)
# Initialize arrays and variables
n_1997 = len(df_1997)
s_actual_1997 = df_1997['Close'].values
# Normalize the actual S&P 500
normalized_s_actual_1997 = s_actual_1997 / s_actual_1997[0] * 100
# Initialize arrays for 2x, 3x, and 4x leveraged products
s_2x_leverage_daily_rebalance_1997 = np.zeros(n_1997)
s_3x_leverage_daily_rebalance_1997 = np.zeros(n_1997)
s_4x_leverage_daily_rebalance_1997 = np.zeros(n_1997)
s_2x_leverage_daily_rebalance_1997[0] = s_actual_1997[0]
s_3x_leverage_daily_rebalance_1997[0] = s_actual_1997[0]
s_4x_leverage_daily_rebalance_1997[0] = s_actual_1997[0]
# Perform daily rebalancing for 2x, 3x, and 4x leveraged products
for t in range(1, n_1997):
daily_return = (s_actual_1997[t] / s_actual_1997[t-1]) - 1
s_2x_leverage_daily_rebalance_1997[t] = s_2x_leverage_daily_rebalance_1997[t-1] * (1 + 2 * daily_return)
s_3x_leverage_daily_rebalance_1997[t] = s_3x_leverage_daily_rebalance_1997[t-1] * (1 + 3 * daily_return)
s_4x_leverage_daily_rebalance_1997[t] = s_4x_leverage_daily_rebalance_1997[t-1] * (1 + 4 * daily_return)
# Normalize the leveraged products
normalized_s_2x_leverage_daily_rebalance_1997 = s_2x_leverage_daily_rebalance_1997 / s_2x_leverage_daily_rebalance_1997[0] * 100
normalized_s_3x_leverage_daily_rebalance_1997 = s_3x_leverage_daily_rebalance_1997 / s_3x_leverage_daily_rebalance_1997[0] * 100
normalized_s_4x_leverage_daily_rebalance_1997 = s_4x_leverage_daily_rebalance_1997 / s_4x_leverage_daily_rebalance_1997[0] * 100
# Plotting
plt.figure(figsize=(15, 6))
plt.plot(df_1997['Date'], normalized_s_actual_1997, label='Normalized Actual S&P 500', color='r')
plt.plot(df_1997['Date'], normalized_s_2x_leverage_daily_rebalance_1997, label='Normalized 2x Leveraged (Daily Rebalance)', color='g')
plt.plot(df_1997['Date'], normalized_s_3x_leverage_daily_rebalance_1997, label='Normalized 3x Leveraged (Daily Rebalance)', color='b')
plt.plot(df_1997['Date'], normalized_s_4x_leverage_daily_rebalance_1997, label='Normalized 4x Leveraged (Daily Rebalance)', color='m')
plt.title('Normalized Actual S&P 500, 2x, 3x, and 4x Leveraged with Daily Rebalancing (Base Value = 100, Starting from 1997)')
plt.xlabel('Date')
plt.ylabel('Normalized Value')
plt.legend()
plt.grid(True)
plt.show()