In [1]:
# Basic imports
import os
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import datetime as dt
import scipy.optimize as spo
import sys
from time import time
from sklearn.metrics import r2_score, median_absolute_error
%matplotlib inline
%pylab inline
pylab.rcParams['figure.figsize'] = (20.0, 10.0)
%load_ext autoreload
%autoreload 2
sys.path.append('../../')
In [2]:
def update_mean(mu_prev, x_n, n):
return (mu_prev * (n-1) + x_n) / n
In [62]:
def update_std(std_prev, mu_prev, x_n, n, mu_n):
""" An arbitrary definition for n=1 is necessary for consistency with n>1."""
#if n == 1:
# return (x_n - mu_n)
#if n == 2: # This is necessary because of the n=1 case definition.
# return np.sqrt((std_prev**2 + (x_n - mu_n)**2))
return np.sqrt(( ((n - 1) * std_prev**2) + (x_n - mu_n)*(x_n - mu_prev) ) / (n))
In [4]:
def update_sharpe(mu_prev, std_prev, x_n, n, f_s):
mu_n = update_mean(mu_prev, x_n, n)
std_n = update_std(std_prev, x_n, n, mu_n)
return np.sqrt(f_s) * mu_n / std_n, mu_n, std_n
In [5]:
daily = np.random.rand(30000)
daily_df = pd.DataFrame(daily, columns=['dr'])
daily_df.head()
Out[5]:
In [6]:
def sharpe_ratio(daily_returns, sampling_frequency=252, daily_rfr=0):
return np.sqrt(sampling_frequency)*(daily_returns - daily_rfr).mean()/(daily_returns-daily_rfr).std()
In [7]:
print(daily[23:34])
sharpe_ratio(daily[23:34])
Out[7]:
In [8]:
from functools import partial
In [9]:
SAMPLING_FREQUENCY = 252
"""
def dummy(x):
print(type(x))
print(len(x))
return 0.0
daily_df.expanding(14).apply(dummy)
"""
Out[9]:
In [10]:
expanding_sharpe_df = daily_df.expanding(252).apply(sharpe_ratio)
expanding_sharpe_df.rename(columns={'dr':'expanding_sharpe'})
expanding_sharpe_df.plot()
Out[10]:
In [ ]:
In [11]:
mu = 0
std = 0
sr = []
for i in range(len(daily)):
sr_n, mu, std = update_sharpe(mu_prev=mu, std_prev=std, x_n=daily[i], n=i+1, f_s=252)
sr.append(sr_n)
In [12]:
len(sr)
Out[12]:
In [13]:
expanding_sharpe_df.shape
Out[13]:
In [14]:
expanding_sharpe_df.plot()
plt.plot(sr)
Out[14]:
In [15]:
comp_df = expanding_sharpe_df.copy()
comp_df['sr'] = pd.Series(sr)
comp_df['diff'] = ((comp_df['dr'] - comp_df['sr']) / comp_df['dr']).abs()
comp_df.head()
Out[15]:
In [16]:
comp_df['diff'].plot()
Out[16]:
In [17]:
comp_df['diff'].describe()
Out[17]:
In [18]:
print('Mean relative error %.2f%%' % (comp_df['diff'].mean() * 100))
In [19]:
comp_df.loc[240:270]
Out[19]:
In [20]:
valid_diff = comp_df.loc[251:, 'diff']
In [21]:
valid_diff.describe()
Out[21]:
In [22]:
valid_diff.plot()
Out[22]:
In [42]:
sr_val = []
for i in range(1,10):
sr_n = sharpe_ratio(daily[:i], sampling_frequency=252, daily_rfr=0)
sr_val.append(sr_n)
sr_val
Out[42]:
In [35]:
mu = 0.0
std = 0.0
sr = []
for i in range(10):
sr_n, mu, std = update_sharpe(mu_prev=mu, std_prev=std, x_n=daily[i], n=i+1, f_s=252.0)
sr.append(sr_n)
sr
Out[35]:
In [ ]:
In [46]:
mu_n = 0.0
mu = []
for i in range(10):
mu_n = update_mean(mu_n, daily[i], i+1)
mu.append(mu_n)
mu
Out[46]:
In [50]:
mu_val = []
for i in range(10):
mu_val.append(np.mean(daily[:i+1]))
mu_val
Out[50]:
In [53]:
(np.array(mu_val) - np.array(mu)).nonzero()
Out[53]:
In [63]:
std_n = 0.0
mu_n = 0.0
std = []
for i in range(10):
mu_prev = mu_n
mu_n = update_mean(mu_n, daily[i], i+1)
std_n = update_std(std_n, mu_prev, daily[i], i+1, mu_n)
std.append(std_n)
std
Out[63]:
In [64]:
std_val = []
for i in range(10):
std_val.append(np.std(daily[:i+1], ddof=1))
std_val
Out[64]:
In [65]:
from utils.running_stats import RunningStats
In [66]:
rstats = RunningStats()
In [67]:
std_val2 = []
for i in range(10):
rstats.push(daily[i])
std_val2.append(rstats.standard_deviation())
std_val2
Out[67]:
In [ ]: