Random Forests - Predicting Daily Cryptocurrencies Returns¶
Table of Contents¶
In [ ]:
%matplotlib inline
%load_ext autoreload
%autoreload 2
from datetime import timedelta
from time import time
import warnings
warnings.filterwarnings('ignore')
import numpy as np
import pandas as pd
import pandas_datareader.data as web
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.ensemble import RandomForestRegressor
import scipy.stats as stats
from util import SqlServerConnector
sns.set_style('whitegrid')
1. Loading Data¶
1.1. Connect to sql server¶
In [ ]:
conn = SqlServerConnector(server_name='',
database_name='',
user_name='',
password='')
1.2. Load assets (coins) historical daily returns¶
In [ ]:
assets_historical_returns = conn.get_rets(daily=True, portfolios=False, start='2010-01-01', end='2023-12-31')
assets_historical_returns.columns = assets_historical_returns.columns.str.strip()
assets_historical_returns
1.3. Loading factor portfolios daily returns¶
In [ ]:
factors_historical_returns = conn.get_factors(daily=True).shift().dropna()
factors_historical_returns
1.4. Loading historical daily risk free rate¶
In [ ]:
rf = web.DataReader('F-F_Research_Data_5_Factors_2x3', 'famafrench', start='2010', end='2022')[0]
rf.index = rf.index.to_timestamp()
rf = rf.RF.reindex(pd.date_range(start='2010', end='2023', freq='d')).ffill()/30
rf
1.5. Alligning data¶
In [ ]:
rf = rf.loc[factors_historical_returns.index]
assets_historical_returns = assets_historical_returns.loc[factors_historical_returns.index]
# Subtract risk free rate from assets returns to find asset exess returns
# assets_historical_returns = assets_historical_returns.sub(rf, axis=0)
1.6. Splitting data¶
In [ ]:
in_sample_pct = 0.8
## Assets
assets_historical_returns_in_sample = assets_historical_returns.iloc[:int(in_sample_pct*len(assets_historical_returns))]
assets_historical_returns_out_of_sample = assets_historical_returns.iloc[int(in_sample_pct*len(assets_historical_returns)):]
## Factors
factors_historical_returns_in_sample = factors_historical_returns.iloc[:int(in_sample_pct*len(factors_historical_returns))]
factors_historical_returns_out_of_sample = factors_historical_returns.iloc[int(in_sample_pct*len(factors_historical_returns)):]
2. In-Sample analysis¶
2.1. Run random forest regression¶
In [ ]:
mod = RandomForestRegressor(n_estimators=100)
res = mod.fit(factors_historical_returns_in_sample, assets_historical_returns_in_sample)
predicted_returns_in_sample = pd.DataFrame(res.predict(factors_historical_returns_in_sample),
index=assets_historical_returns_in_sample.index,
columns=assets_historical_returns_in_sample.columns
)
predicted_returns_in_sample
2.2. Average results for all coins¶
In [ ]:
stop_loss_factors = [0, 0.1, 0.2, 0.3, 0.4, 0.5]
winnings_discount = 0.5 ## percentage of the stop loss factor that is applied to the winiing trades
trading_fees_factor = 0.01
significance_level = 0.1
results=[]
for stop_loss_factor in stop_loss_factors:
t_stats = []
p_values = []
win_rates = []
avg_daily_rets = []
cols=[]
for coin in assets_historical_returns_in_sample.columns:
predicted_returns = predicted_returns_in_sample[coin]
ground_truth = (assets_historical_returns_in_sample.loc[:, coin]>=0).astype(int).replace(0,-1)
predictions = (predicted_returns>=0).astype(int).replace(0,-1)
signals = predictions - ground_truth
win_rate = (signals==0).sum()/len(signals)
strategy_returns_coin = (assets_historical_returns_in_sample.loc[:,coin] * predictions).fillna(0)
strategy_returns_coin.loc[strategy_returns_coin>=0] = strategy_returns_coin.loc[strategy_returns_coin>=0]*(1-(stop_loss_factor*winnings_discount))*(1-trading_fees_factor)
strategy_returns_coin.loc[strategy_returns_coin<0] = strategy_returns_coin.loc[strategy_returns_coin<0]*(1-stop_loss_factor)*(1+trading_fees_factor)
# Perform the one-sample t-test
t_test = stats.ttest_1samp(a=strategy_returns_coin, popmean=0, alternative='greater')
win_rates.append(win_rate)
t_stats.append(t_test.statistic)
p_values.append(t_test.pvalue)
avg_daily_rets.append(strategy_returns_coin.mean())
cols.append(coin)
first_results = pd.DataFrame({'win_rate':win_rates, 't_stats':t_stats, 'p_value':p_values, 'avg_daily_returns':avg_daily_rets}, index=cols)
results.append(first_results.mean().values)
average_results_all_coins_in_sample = pd.DataFrame(results, index=stop_loss_factors, columns=first_results.columns)
average_results_all_coins_in_sample
2.3. Results for Ethereum¶
In [ ]:
stop_loss_factors = [0, 0.1, 0.2, 0.3, 0.4, 0.5]
winnings_discount = 0.5 ## percentage of the stop loss factor that is applied to the winiing trades
trading_fees_factor = 0.01
significance_level = 0.1
coin_results_in_sample = pd.DataFrame()
rets = pd.DataFrame()
coin = 'ethereum'
for stop_loss_factor in stop_loss_factors:
predicted_returns = predicted_returns_in_sample[coin]
ground_truth = (assets_historical_returns_in_sample.loc[:, coin]>=0).astype(int).replace(0,-1)
predictions = (predicted_returns>=0).astype(int).replace(0,-1)
signals = predictions - ground_truth
win_rate = (signals==0).sum()/len(signals)
strategy_returns = (assets_historical_returns_in_sample.loc[:,coin] * predictions).fillna(0)
strategy_returns.loc[strategy_returns>=0] = strategy_returns.loc[strategy_returns>=0]*(1-(stop_loss_factor*winnings_discount))*(1-trading_fees_factor)
strategy_returns.loc[strategy_returns<0] = strategy_returns.loc[strategy_returns<0]*(1-stop_loss_factor)*(1+trading_fees_factor)
# Perform the one-sample t-test
t_test = stats.ttest_1samp(a=strategy_returns, popmean=0, alternative='greater')
t_stat = t_test.statistic
p_value = t_test.pvalue
avg_daily_rets = strategy_returns.mean()
first_results = pd.DataFrame({'win_rate':win_rate, 't_stats':t_stat, 'p_value':p_value, 'avg_daily_return':avg_daily_rets}, index=[stop_loss_factor])
coin_results_in_sample = pd.concat([coin_results_in_sample, first_results])
rets = pd.concat([rets, strategy_returns.to_frame()], axis=1)
rets.columns = stop_loss_factors
coin_results_in_sample
In [ ]:
strategy_compounded_returns = rets.cumsum().apply(np.exp)
btc_bh = assets_historical_returns_in_sample.bitcoin.cumsum().apply(np.exp)
btc_bh = btc_bh.append(pd.Series([1], index=[rets.index.min()-timedelta(days=1)])).sort_index()
btc_bh.name = 'Bitcoin'
portfolios_compared = pd.concat([strategy_compounded_returns,btc_bh], axis=1).fillna(1)
portfolios_compared.plot(figsize=(20,12), legend=True, logy=True)
3. Out-Of-Sample analysis¶
In [ ]:
predicted_returns_out_of_sample = pd.DataFrame(res.predict(factors_historical_returns_out_of_sample),
index=assets_historical_returns_out_of_sample.index,
columns=assets_historical_returns_out_of_sample.columns
)
3.1. Average results for all coins¶
In [ ]:
stop_loss_factors = [0, 0.1, 0.2, 0.3, 0.4, 0.5]
winnings_discount = 0.5 ## percentage of the stop loss factor that is applied to the winiing trades
trading_fees_factor = 0.01
significance_level = 0.1
results=[]
for stop_loss_factor in stop_loss_factors:
t_stats = []
p_values = []
win_rates = []
avg_daily_rets = []
cols=[]
for coin in assets_historical_returns_out_of_sample.columns:
predicted_returns = predicted_returns_out_of_sample[coin]
ground_truth = (assets_historical_returns_out_of_sample.loc[:, coin]>=0).astype(int).replace(0,-1)
predictions = (predicted_returns>=0).astype(int).replace(0,-1)
signals = predictions - ground_truth
win_rate = (signals==0).sum()/len(signals)
strategy_returns_coin = (assets_historical_returns_out_of_sample.loc[:,coin] * predictions).fillna(0)
strategy_returns_coin.loc[strategy_returns_coin>=0] = strategy_returns_coin.loc[strategy_returns_coin>=0]*(1-(stop_loss_factor*winnings_discount))*(1-trading_fees_factor)
strategy_returns_coin.loc[strategy_returns_coin<0] = strategy_returns_coin.loc[strategy_returns_coin<0]*(1-stop_loss_factor)*(1+trading_fees_factor)
# Perform the one-sample t-test
t_test = stats.ttest_1samp(a=strategy_returns_coin, popmean=0, alternative='greater')
win_rates.append(win_rate)
t_stats.append(t_test.statistic)
p_values.append(t_test.pvalue)
avg_daily_rets.append(strategy_returns_coin.mean())
cols.append(coin)
first_results = pd.DataFrame({'win_rate':win_rates, 't_stats':t_stats, 'p_value':p_values, 'avg_daily_returns':avg_daily_rets}, index=cols)
results.append(first_results.mean().values)
average_results_all_coins_out_of_sample = pd.DataFrame(results, index=stop_loss_factors, columns=first_results.columns)
average_results_all_coins_out_of_sample
3.2. Results for ethereum¶
In [ ]:
stop_loss_factors = [0, 0.1, 0.2, 0.3, 0.4, 0.5]
winnings_discount = 0.5 ## percentage of the stop loss factor that is applied to the winiing trades
trading_fees_factor = 0.01
significance_level = 0.1
coin_results_out_of_sample = pd.DataFrame()
rets = pd.DataFrame()
coin = 'ethereum'
for stop_loss_factor in stop_loss_factors:
predicted_returns = predicted_returns_out_of_sample[coin]
ground_truth = (assets_historical_returns_out_of_sample.loc[:, coin]>=0).astype(int).replace(0,-1)
predictions = (predicted_returns>=0).astype(int).replace(0,-1)
signals = predictions - ground_truth
win_rate = (signals==0).sum()/len(signals)
strategy_returns = (assets_historical_returns_out_of_sample.loc[:,coin] * predictions).fillna(0)
strategy_returns.loc[strategy_returns>=0] = strategy_returns.loc[strategy_returns>=0]*(1-(stop_loss_factor*winnings_discount))*(1-trading_fees_factor)
strategy_returns.loc[strategy_returns<0] = strategy_returns.loc[strategy_returns<0]*(1-stop_loss_factor)*(1+trading_fees_factor)
# Perform the one-sample t-test
t_test = stats.ttest_1samp(a=strategy_returns, popmean=0, alternative='greater')
t_stat = t_test.statistic
p_value = t_test.pvalue
avg_daily_rets = strategy_returns.mean()
first_results = pd.DataFrame({'win_rate':win_rate, 't_stats':t_stat, 'p_value':p_value, 'avg_daily_return':avg_daily_rets}, index=[stop_loss_factor])
coin_results_out_of_sample = pd.concat([coin_results_out_of_sample, first_results])
rets = pd.concat([rets, strategy_returns.to_frame()], axis=1)
rets.columns = stop_loss_factors
coin_results_out_of_sample
In [ ]:
strategy_compounded_returns = rets.cumsum().apply(np.exp)
btc_bh = assets_historical_returns_out_of_sample.bitcoin.cumsum().apply(np.exp)
btc_bh = btc_bh.append(pd.Series([1], index=[rets.index.min()-timedelta(days=1)])).sort_index()
btc_bh.name = 'Bitcoin'
portfolios_compared = pd.concat([strategy_compounded_returns,btc_bh], axis=1).fillna(1)
portfolios_compared.plot(figsize=(20,12), legend=True, logy=True)
4. Out-Of-Sample analysis (rolling)¶
In [ ]:
window = 365
conn2 = SqlServerConnector(server_name='DESKTOP-O0P86FB',
database_name='CryplogModels',
user_name='AbdullahBahi',
password='277776')
4.1. Average results for all coins¶
In [ ]:
stop_loss_factors = [0, 0.1, 0.2, 0.3, 0.4, 0.5]
winnings_discount = 0.5 ## percentage of the stop loss factor that is applied to the winiing trades
trading_fees_factor = 0.01
results=[]
for stop_loss_factor in stop_loss_factors:
t_stats = []
p_values = []
win_rates = []
avg_daily_rets = []
for coin in assets_historical_returns_out_of_sample.columns:
predicted_returns = conn2.sql_to_df(f'select * from RF_3Factor where asset = \'{coin}\' and window = {window} order by date')
predicted_returns['Date'] = pd.to_datetime(predicted_returns.Date)
predicted_returns.set_index(['Date'], inplace=True)
predicted_returns = predicted_returns.predicted_return
ground_truth = (assets_historical_returns.loc[predicted_returns.index, coin]>=0).astype(int).replace(0,-1)
predictions = (predicted_returns>=0).astype(int).replace(0,-1)
signals = predictions - ground_truth
win_rate = (signals==0).sum()/len(signals)
strategy_returns_coin = (assets_historical_returns.loc[predicted_returns.index,coin] * predictions).fillna(0)
strategy_returns_coin.loc[strategy_returns_coin>=0] = strategy_returns_coin.loc[strategy_returns_coin>=0]*(1-(stop_loss_factor*winnings_discount))*(1-trading_fees_factor)
strategy_returns_coin.loc[strategy_returns_coin<0] = strategy_returns_coin.loc[strategy_returns_coin<0]*(1-stop_loss_factor)*(1+trading_fees_factor)
# Perform the one-sample t-test
t_test = stats.ttest_1samp(a=strategy_returns_coin, popmean=0, alternative='greater')
win_rates.append(win_rate)
t_stats.append(t_test.statistic)
p_values.append(t_test.pvalue)
avg_daily_rets.append(strategy_returns_coin.mean())
first_results = pd.DataFrame({'win_rate':win_rates, 't_stats':t_stats, 'p_value':p_values, 'avg_daily_returns':avg_daily_rets}, index=assets_historical_returns.columns)
results.append(first_results.mean().values)
average_results_all_coins_out_of_sample_rolling = pd.DataFrame(results, index=stop_loss_factors, columns=first_results.columns)
average_results_all_coins_out_of_sample_rolling
4.2. Results for ethereum¶
In [ ]:
stop_loss_factors = [0, 0.1, 0.2, 0.3, 0.4, 0.5]
winnings_discount = 0.5 ## percentage of the stop loss factor that is applied to the winiing trades
trading_fees_factor = 0.01
coin_results_out_of_sample_rolling = pd.DataFrame()
rets = pd.DataFrame()
coin = 'ethereum'
for stop_loss_factor in stop_loss_factors:
predicted_returns = conn2.sql_to_df(f'select * from RF_3Factor where asset = \'{coin}\' and window = {window} order by date')
predicted_returns['Date'] = pd.to_datetime(predicted_returns.Date)
predicted_returns.set_index(['Date'], inplace=True)
predicted_returns = predicted_returns.predicted_return
ground_truth = (assets_historical_returns.loc[predicted_returns.index, coin]>=0).astype(int).replace(0,-1)
predictions = (predicted_returns>=0).astype(int).replace(0,-1)
signals = predictions - ground_truth
win_rate = (signals==0).sum()/len(signals)
strategy_returns = (assets_historical_returns.loc[predicted_returns.index,coin] * predictions).fillna(0)
strategy_returns.loc[strategy_returns>=0] = strategy_returns.loc[strategy_returns>=0]*(1-(stop_loss_factor*winnings_discount))*(1-trading_fees_factor)
strategy_returns.loc[strategy_returns<0] = strategy_returns.loc[strategy_returns<0]*(1-stop_loss_factor)*(1+trading_fees_factor)
# Perform the one-sample t-test
t_test = stats.ttest_1samp(a=strategy_returns, popmean=0, alternative='greater')
t_stat = t_test.statistic
p_value = t_test.pvalue
avg_daily_rets = strategy_returns.mean()
first_results = pd.DataFrame({'win_rate':win_rate, 't_stats':t_stat, 'p_value':p_value, 'avg_daily_return':avg_daily_rets}, index=[stop_loss_factor])
coin_results_out_of_sample_rolling = pd.concat([coin_results_out_of_sample_rolling, first_results])
rets = pd.concat([rets, strategy_returns.to_frame()], axis=1)
rets.columns = stop_loss_factors
coin_results_out_of_sample_rolling
In [ ]:
strategy_compounded_returns = rets.cumsum().apply(np.exp)
btc_bh = assets_historical_returns.loc[predicted_returns.index].bitcoin.cumsum().apply(np.exp)
btc_bh = btc_bh.append(pd.Series([1], index=[rets.index.min()-timedelta(days=1)])).sort_index()
btc_bh.name = 'Bitcoin'
portfolios_compared = pd.concat([strategy_compounded_returns,btc_bh], axis=1).fillna(1)
portfolios_compared.plot(figsize=(20,12), legend=True, logy=True)
5. Out-Of-Sample analysis (rolling - all windows)¶
5.1. Average results for all coins¶
In [ ]:
stop_loss_factors = [0, 0.1, 0.2, 0.3, 0.4, 0.5]
winnings_discount = 0.5 ## percentage of the stop loss factor that is applied to the winiing trades
trading_fees_factor = 0.01
average_results_all_coins_out_of_sample_rolling_all_windows_concatinated = pd.DataFrame()
for window in np.linspace(30,16*30,16).astype(int):
results=[]
for stop_loss_factor in stop_loss_factors:
t_stats = []
p_values = []
win_rates = []
avg_daily_rets = []
for coin in assets_historical_returns_out_of_sample.columns:
predicted_returns = conn2.sql_to_df(f'select * from RF_3Factor where asset = \'{coin}\' and window = {window} order by date')
predicted_returns['Date'] = pd.to_datetime(predicted_returns.Date)
predicted_returns.set_index(['Date'], inplace=True)
predicted_returns = predicted_returns.predicted_return
ground_truth = (assets_historical_returns.loc[predicted_returns.index, coin]>=0).astype(int).replace(0,-1)
predictions = (predicted_returns>=0).astype(int).replace(0,-1)
signals = predictions - ground_truth
win_rate = (signals==0).sum()/len(signals)
strategy_returns_coin = (assets_historical_returns.loc[predicted_returns.index,coin] * predictions).fillna(0)
strategy_returns_coin.loc[strategy_returns_coin>=0] = strategy_returns_coin.loc[strategy_returns_coin>=0]*(1-(stop_loss_factor*winnings_discount))*(1-trading_fees_factor)
strategy_returns_coin.loc[strategy_returns_coin<0] = strategy_returns_coin.loc[strategy_returns_coin<0]*(1-stop_loss_factor)*(1+trading_fees_factor)
# Perform the one-sample t-test
t_test = stats.ttest_1samp(a=strategy_returns_coin, popmean=0, alternative='greater')
win_rates.append(win_rate)
t_stats.append(t_test.statistic)
p_values.append(t_test.pvalue)
avg_daily_rets.append(strategy_returns_coin.mean())
first_results = pd.DataFrame({'win_rate':win_rates, 't_stats':t_stats, 'p_value':p_values, 'avg_daily_returns':avg_daily_rets}, index=assets_historical_returns.columns)
results.append(first_results.mean().values)
average_results_all_coins_out_of_sample_rolling_all_windows = pd.DataFrame(results, index=stop_loss_factors, columns=first_results.columns)
average_results_all_coins_out_of_sample_rolling_all_windows = average_results_all_coins_out_of_sample_rolling_all_windows.transpose()
average_results_all_coins_out_of_sample_rolling_all_windows['window'] = window
average_results_all_coins_out_of_sample_rolling_all_windows_concatinated = pd.concat([average_results_all_coins_out_of_sample_rolling_all_windows_concatinated,
average_results_all_coins_out_of_sample_rolling_all_windows
])
print(f'Window {window} is finished!')
average_results_all_coins_out_of_sample_rolling_all_windows_concatinated
In [ ]:
average_results_all_coins_out_of_sample_rolling_all_windows_concatinated.to_excel('average_results_all_coins_out_of_sample_rolling_all_windows.xlsx')
5.2. Results for ethereum¶
In [ ]:
stop_loss_factors = [0, 0.1, 0.2, 0.3, 0.4, 0.5]
winnings_discount = 0.5 ## percentage of the stop loss factor that is applied to the winiing trades
trading_fees_factor = 0.01
coin_results_out_of_sample_rolling_all_windows_concatinated = pd.DataFrame()
rets_concatinated = pd.DataFrame()
for window in np.linspace(30,16*30,16).astype(int):
coin_results_out_of_sample_rolling_all_windows = pd.DataFrame()
rets = pd.DataFrame()
coin = 'ethereum'
for stop_loss_factor in stop_loss_factors:
predicted_returns = conn2.sql_to_df(f'select * from RF_3Factor where asset = \'{coin}\' and window = {window} order by date')
predicted_returns['Date'] = pd.to_datetime(predicted_returns.Date)
predicted_returns.set_index(['Date'], inplace=True)
predicted_returns = predicted_returns.predicted_return
ground_truth = (assets_historical_returns.loc[predicted_returns.index, coin]>=0).astype(int).replace(0,-1)
predictions = (predicted_returns>=0).astype(int).replace(0,-1)
signals = predictions - ground_truth
win_rate = (signals==0).sum()/len(signals)
strategy_returns = (assets_historical_returns.loc[predicted_returns.index,coin] * predictions).fillna(0)
strategy_returns.loc[strategy_returns>=0] = strategy_returns.loc[strategy_returns>=0]*(1-(stop_loss_factor*winnings_discount))*(1-trading_fees_factor)
strategy_returns.loc[strategy_returns<0] = strategy_returns.loc[strategy_returns<0]*(1-stop_loss_factor)*(1+trading_fees_factor)
# Perform the one-sample t-test
t_test = stats.ttest_1samp(a=strategy_returns, popmean=0, alternative='greater')
t_stat = t_test.statistic
p_value = t_test.pvalue
avg_daily_rets = strategy_returns.mean()
first_results = pd.DataFrame({'win_rate':win_rate, 't_stats':t_stat, 'p_value':p_value, 'avg_daily_return':avg_daily_rets}, index=[stop_loss_factor])
coin_results_out_of_sample_rolling_all_windows = pd.concat([coin_results_out_of_sample_rolling_all_windows, first_results])
rets = pd.concat([rets, strategy_returns.to_frame()], axis=1)
rets.columns = stop_loss_factors
rets['window'] = window
rets_concatinated = pd.concat([rets_concatinated, rets])
coin_results_out_of_sample_rolling_all_windows
coin_results_out_of_sample_rolling_all_windows = coin_results_out_of_sample_rolling_all_windows.transpose()
coin_results_out_of_sample_rolling_all_windows['window'] = window
coin_results_out_of_sample_rolling_all_windows_concatinated = pd.concat([coin_results_out_of_sample_rolling_all_windows_concatinated,
coin_results_out_of_sample_rolling_all_windows
])
print(f'Window {window} is finished!')
coin_results_out_of_sample_rolling_all_windows_concatinated
In [ ]:
coin_results_out_of_sample_rolling_all_windows_concatinated.to_excel('coin_results_out_of_sample_rolling_all_windows.xlsx')
In [ ]:
# rets_concatinated.drop(['2022-01-10'], inplace=True)
rets_to_plot0 = rets_concatinated.reset_index().pivot(index='Date', columns='window', values=0.0).dropna()
rets_to_plot1 = rets_concatinated.reset_index().pivot(index='Date', columns='window', values=0.1).dropna()
rets_to_plot2 = rets_concatinated.reset_index().pivot(index='Date', columns='window', values=0.2).dropna()
rets_to_plot3 = rets_concatinated.reset_index().pivot(index='Date', columns='window', values=0.3).dropna()
rets_to_plot4 = rets_concatinated.reset_index().pivot(index='Date', columns='window', values=0.4).dropna()
rets_to_plot5 = rets_concatinated.reset_index().pivot(index='Date', columns='window', values=0.5).dropna()
strategy_compounded_returns0 = rets_to_plot0.cumsum().apply(np.exp)
strategy_compounded_returns1 = rets_to_plot1.cumsum().apply(np.exp)
strategy_compounded_returns2 = rets_to_plot2.cumsum().apply(np.exp)
strategy_compounded_returns3 = rets_to_plot3.cumsum().apply(np.exp)
strategy_compounded_returns4 = rets_to_plot4.cumsum().apply(np.exp)
strategy_compounded_returns5 = rets_to_plot5.cumsum().apply(np.exp)
btc_bh = assets_historical_returns.loc[predicted_returns.index].bitcoin.cumsum().apply(np.exp)
btc_bh = btc_bh.append(pd.Series([1], index=[rets.index.min()-timedelta(days=1)])).sort_index()
btc_bh.name = 'Bitcoin'
portfolios_compared0 = pd.concat([strategy_compounded_returns0,btc_bh], axis=1).ffill()
portfolios_compared1 = pd.concat([strategy_compounded_returns1,btc_bh], axis=1).ffill()
portfolios_compared2 = pd.concat([strategy_compounded_returns2,btc_bh], axis=1).ffill()
portfolios_compared3 = pd.concat([strategy_compounded_returns3,btc_bh], axis=1).ffill()
portfolios_compared4 = pd.concat([strategy_compounded_returns4,btc_bh], axis=1).ffill()
portfolios_compared5 = pd.concat([strategy_compounded_returns5,btc_bh], axis=1).ffill()
In [ ]:
plt.subplots(3, 2, figsize=(30,20))
ax1 = plt.subplot(3, 2, 1)
portfolios_compared0.plot(ax=ax1, legend=False, logy=True, title='Risk Mitigation Factor = 0.0')
ax2 = plt.subplot(3, 2, 2)
portfolios_compared1.plot(ax=ax2, legend=False, logy=True, title='Risk Mitigation Factor = 0.1')
ax3 = plt.subplot(3, 2, 3)
portfolios_compared2.plot(ax=ax3, legend=False, logy=True, title='Risk Mitigation Factor = 0.2')
ax4 = plt.subplot(3, 2, 4)
portfolios_compared3.plot(ax=ax4, legend=False, logy=True, title='Risk Mitigation Factor = 0.3')
ax5 = plt.subplot(3, 2, 5)
portfolios_compared4.plot(ax=ax5, legend=False, logy=True, title='Risk Mitigation Factor = 0.4')
ax6 = plt.subplot(3, 2, 6)
portfolios_compared5.plot(ax=ax6, legend=False, logy=True, title='Risk Mitigation Factor = 0.5')
for i, lines in enumerate(zip(ax1.lines, ax2.lines, ax3.lines, ax4.lines, ax5.lines, ax6.lines)):
if i == 16:
for line in lines:
line.set_color('black')
line.set_marker('*')
plt.show()
6. Comparing results of Fama-Macbeth model¶
6.1. Across all coins¶
6.1.1. In-sample¶
In [ ]:
average_results_all_coins_in_sample
6.1.2. Out-of-sample (static)¶
In [ ]:
average_results_all_coins_out_of_sample
6.1.3. Out-of-sample (rolling - 1Y window)¶
In [ ]:
average_results_all_coins_out_of_sample_rolling
6.1.4. Out-of-sample (rolling - all windows)¶
In [ ]:
average_results_all_coins_out_of_sample_rolling_all_windows_concatinated
6.2. for Ethereum¶
6.2.1. In-sample¶
In [ ]:
coin_results_in_sample
6.2.2. Out-of-sample (static)¶
In [ ]:
coin_results_out_of_sample
6.2.3. Out-of-sample (rolling - 1Y window)¶
In [ ]:
coin_results_out_of_sample_rolling
6.2.4. Out-of-sample (rolling - all windows)¶
In [ ]:
coin_results_out_of_sample_rolling_all_windows_concatinated
In [ ]: