-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtrendfollowing.py
78 lines (60 loc) · 2.84 KB
/
trendfollowing.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from utils import Performance
df = pd.read_excel(io=r"/Users/gamarante/Downloads/Book1.xlsx",
index_col=0)
name = 'SMAL11 BZ Equity'
df = df[name].dropna()
ret = df.pct_change(1)
k_fast = 21 * 6
k_slow = 21 * 12
df_fast = ret.rolling(k_fast).mean().shift(1) # 1-day lag on the signal
df_slow = ret.rolling(k_slow).mean().shift(1) # 1-day lag on the signal
is_bull = (df_fast >= 0) & (df_slow >= 0)
is_bear = (df_fast < 0) & (df_slow < 0)
is_corr = (df_fast < 0) & (df_slow >= 0)
is_rebo = (df_fast >= 0) & (df_slow < 0)
is_else = ~(is_bull | is_bear | is_corr | is_rebo)
ret_fast = ret * (df_fast >= 0) + (-ret) * (df_fast < 0)
ret_slow = ret * (df_slow >= 0) + (-ret) * (df_slow < 0)
mean_bull = ret[is_bull].expanding().mean().reindex(ret.index).fillna(method='ffill')
mean_bear = ret[is_bear].expanding().mean().reindex(ret.index).fillna(method='ffill')
mean_corr = ret[is_corr].expanding().mean().reindex(ret.index).fillna(method='ffill')
mean_rebo = ret[is_rebo].expanding().mean().reindex(ret.index).fillna(method='ffill')
std_bull = ret[is_bull].expanding().var().reindex(ret.index).fillna(method='ffill')
std_bear = ret[is_bear].expanding().var().reindex(ret.index).fillna(method='ffill')
std_corr = ret[is_corr].expanding().var().reindex(ret.index).fillna(method='ffill')
std_rebo = ret[is_rebo].expanding().var().reindex(ret.index).fillna(method='ffill')
std_bube = ret[is_bull | is_bear].expanding().var().reindex(ret.index).fillna(method='ffill')
sharpe_bull = ((1 + mean_bull)**252 - 1) / (std_bull * np.sqrt(252))
sharpe_bear = ((1 + mean_bear)**252 - 1) / (std_bear * np.sqrt(252))
sharpe_corr = ((1 + mean_corr)**252 - 1) / (std_corr * np.sqrt(252))
sharpe_rebo = ((1 + mean_rebo)**252 - 1) / (std_rebo * np.sqrt(252))
freq_bull = is_bull.expanding().sum()
freq_bear = is_bear.expanding().sum()
freq_corr = is_corr.expanding().sum()
freq_rebo = is_rebo.expanding().sum()
freq_bube = (is_bull | is_bear).expanding().sum()
c = (freq_bull / freq_bube) * (mean_bull / std_bube) - (freq_bear / freq_bube) * (mean_bear / std_bube)
aco = 0.5 * (1 - (1 / c) * mean_corr / std_corr)
aco = np.minimum(aco, 1)
aco = np.maximum(aco, 0)
are = 0.5 * (1 - (1 / c) * mean_rebo / std_rebo)
are = np.minimum(are, 1)
are = np.maximum(are, 0)
ret_dyn = is_bull * ret + is_bear * (-ret) + is_corr * ((1 - aco) * ret_slow + aco * ret_fast) + is_rebo * ((1 - are) * ret_slow + are * ret_fast)
ret_dyn = ret_dyn.fillna(0)
dyn = (1 + ret_dyn).cumprod()
ret_fast = ret_fast.fillna(0)
fast = (1 + ret_fast).cumprod()
ret_slow = ret_slow.fillna(0)
slow = (1 + ret_slow).cumprod()
df = pd.concat([df, fast.rename("Fast"), slow.rename("Slow"), dyn.rename('DynTrend')], axis=1)
df = df[df.index >= '2017-01-01']
df = 100 * df / df.iloc[0]
df.plot()
plt.show()
ratio = df['DynTrend'] / df[name]
ratio.plot()
plt.show()