From 2bca78eb916d5c4d958f0da25ef2a86c77c84c16 Mon Sep 17 00:00:00 2001 From: Derek Melchin <38889814+DerekMelchin@users.noreply.github.com> Date: Tue, 16 Apr 2024 11:16:03 -0600 Subject: [PATCH 1/2] Update strategy library tutorial #01 --- .../03 Method.html | 54 +++++++++---------- .../05 Algorithm.html | 2 +- .../05 \347\256\227\346\263\225.cn.html" | 2 +- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/03 Method.html b/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/03 Method.html index ffff064..26848dc 100755 --- a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/03 Method.html +++ b/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/03 Method.html @@ -15,10 +15,10 @@
def Initialize(self): - self.Schedule.On(self.DateRules.MonthStart(self.symbols[0]), - self.TimeRules.AfterMarketOpen(self.symbols[0]), - self.Rebalance)+
def initialize(self): + self.schedule.on(self.date_rules.month_start(self._symbols[0]), + self.time_rules.after_market_open(self._symbols[0]), + self._rebalance)
@@ -26,33 +26,33 @@
# Fetch the historical data to perform the linear regression -history = self.History( - self.symbols + [self.benchmark], - self.lookback, - Resolution.Daily).close.unstack(level=0)+history = self.history( + self._symbols + [self._benchmark], + self._lookback, + Resolution.DAILY).close.unstack(level=0)
We aim to trade the two assets with the highest alpha to the benchmark. In order to conduct linear regression to find the alpha (linear regression intercept), we need to compute returns (percentage change of closing price) benchmark and the asset then conduct a linear regression.
def SelectSymbols(self, history): +def _select_symbols(self, history): '''Select symbols with the highest intercept/alpha to the benchmark ''' alphas = dict() # Get the benchmark returns - benchmark = history[self.benchmark].pct_change().dropna() + benchmark = history[self._benchmark].pct_change().dropna() # Conducts linear regression for each symbol and save the intercept/alpha - for symbol in self.symbols: - + for symbol in self._symbols: + # Get the security returns returns = history[symbol].pct_change().dropna() - returns = np.vstack([returns, np.ones(len(returns))]).T + bla = np.vstack([benchmark, np.ones(len(returns))]).T # Simple linear regression function in Numpy - result = np.linalg.lstsq(returns, benchmark) + result = np.linalg.lstsq(bla , returns) alphas[symbol] = result[0][1] # Select symbols with the highest intercept/alpha to the benchmark @@ -64,23 +64,23 @@Step 4: Rebalance Function:
This function is where all the action happens, it will be executed on the first trading day of each month as a scheduled event. The algorithm closes all positions of securities that were not selected using Liquidate and go 100% long for both of the selected symbols using SetHoldings.-\ No newline at end of file diff --git a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/05 Algorithm.html b/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/05 Algorithm.html index 645e3da..44979ab 100755 --- a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/05 Algorithm.html +++ b/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/05 Algorithm.html @@ -1,6 +1,6 @@ \ No newline at end of file diff --git "a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/05 \347\256\227\346\263\225.cn.html" "b/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/05 \347\256\227\346\263\225.cn.html" index 4a79e84..815b9a5 100644 --- "a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/05 \347\256\227\346\263\225.cn.html" +++ "b/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/05 \347\256\227\346\263\225.cn.html" @@ -4,6 +4,6 @@ From db1f4cb41a547b58f1da9649508ce52ae94f10ac Mon Sep 17 00:00:00 2001 From: Derek Melchin <38889814+DerekMelchin@users.noreply.github.com> Date: Tue, 16 Apr 2024 11:17:55 -0600 Subject: [PATCH 2/2] Remove chinese version --- .../01 \347\256\200\344\273\213.cn.html" | 14 --- ...7\274\211\347\220\206\350\256\272.cn.html" | 44 --------- .../03 \346\226\271\346\263\225.cn.html" | 95 ------------------- .../04 \346\200\273\347\273\223.cn.html" | 14 --- .../05 \347\256\227\346\263\225.cn.html" | 9 -- ...0\200\203\346\226\207\347\214\256.cn.html" | 8 -- 6 files changed, 184 deletions(-) delete mode 100644 "04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/01 \347\256\200\344\273\213.cn.html" delete mode 100644 "04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/02 \350\265\204\346\234\254\350\265\204\344\272\247\345\256\232\344\273\267\346\250\241\345\236\213\357\274\210CAPM\357\274\211\347\220\206\350\256\272.cn.html" delete mode 100644 "04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/03 \346\226\271\346\263\225.cn.html" delete mode 100644 "04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/04 \346\200\273\347\273\223.cn.html" delete mode 100644 "04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/05 \347\256\227\346\263\225.cn.html" delete mode 100644 "04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/06 \345\217\202\350\200\203\346\226\207\347\214\256.cn.html" diff --git "a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/01 \347\256\200\344\273\213.cn.html" "b/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/01 \347\256\200\344\273\213.cn.html" deleted file mode 100644 index 9ccb0d0..0000000 --- "a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/01 \347\256\200\344\273\213.cn.html" +++ /dev/null @@ -1,14 +0,0 @@ -def Rebalance(self): +def _rebalance(self): # Fetch the historical data to perform the linear regression - history = self.History( - self.symbols + [self.benchmark], - self.lookback, - Resolution.Daily).close.unstack(level=0) - - symbols = self.SelectSymbols(history) + history = self.history( + self._symbols + [self._benchmark], + self._lookback, + Resolution.DAILY).close.unstack(level=0) + + symbols = self._select_symbols(history) # Liquidate positions that are not held by selected symbols - for holdings in self.Portfolio.Values: - symbol = holdings.Symbol - if symbol not in symbols and holdings.Invested: - self.Liquidate(symbol) + for holdings in self.portfolio.values(): + symbol = holdings.symbol + if symbol not in symbols and holdings.invested: + self.liquidate(symbol) - # Invest 100% in the each of the selected symbols + # Invest 100% in the selected symbols for symbol in symbols: - self.SetHoldings(symbol, 1)+ self.set_holdings(symbol, 1)- 本教程执行一个简单的线性回归来构建资本资产定价模型(CAPM),这是由William F. Sharpe和Harry Markowitz开发的一个经典模型。该模型对各资产都会产生alpha和beta值,并通过做多alpha值最高的股票进行交易。本教程将演示以下内容: -
- -
- 该策略的实施表明,在上个月跑赢大盘的股票很可能在接下来的一个月里再次跑赢大盘。该算法在市场平稳时性能良好。然而,当市场波动性增加时,模型未能捕捉到alpha值,且表现不佳。我们从中了解到,市场波动降低了线性回归系数的显著性水平,特别是当我们使用日收益率来拟合模型时。 -
diff --git "a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/02 \350\265\204\346\234\254\350\265\204\344\272\247\345\256\232\344\273\267\346\250\241\345\236\213\357\274\210CAPM\357\274\211\347\220\206\350\256\272.cn.html" "b/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/02 \350\265\204\346\234\254\350\265\204\344\272\247\345\256\232\344\273\267\346\250\241\345\236\213\357\274\210CAPM\357\274\211\347\220\206\350\256\272.cn.html" deleted file mode 100644 index 7add139..0000000 --- "a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/02 \350\265\204\346\234\254\350\265\204\344\272\247\345\256\232\344\273\267\346\250\241\345\236\213\357\274\210CAPM\357\274\211\347\220\206\350\256\272.cn.html" +++ /dev/null @@ -1,44 +0,0 @@ -- 资本资产定价模型(CAPM)描述了系统性风险与资产(通常是股票)预期收益之间的关系。给定风险的资产预期收益计算公式如下: -
- -\[r_a = r_f + \beta_a*(r_m - r_f) + \epsilon \] - -- 其中: -
- -\[r_f = Risk Free Rate\] -\[\beta = Beta of the security\] - -\[r_m = Expected market return\] - -\[\epsilon = Tracking error\] - -- 将公式重构如下,可以更好地理解这个公式: -
- -\[(r_a - r_f ) = \beta_a*(r_m - r_f) + \epsilon \] - -- 方程的左边给出了资产收益和无风险利率之间的差额,即"超额收益"。如果我们将市场超额收益与资产超额收益进行对比,斜率代表资产的"beta"。因此,beta也可以通过公式计算: -
- -\[\beta = \frac{Cov(r_a,r_b)}{var(r_b)}\] - -- 因此beta可以描述为: -
- -\[\beta = \rho _a,_b*\frac{\sigma _a}{\sigma_b}\] - -- 由上式可知,beta可以解释为“关联相对波动”。为了更加简化,可以通过简单的线性回归来计算beta,线性回归可以看作是解释收僧的一个因素,跟踪误差可以表示alpha。为了使这个理论对我们的算法更加便利,我们将上面的公式改为如下形式: -
- -\[r_a = \beta*r_m + r_f*(1-\beta) + \epsilon\] - -- 等式右边的r*(1-β) 是一个非常小的项目,在道琼斯前30强企业的背景下可以忽略不计。如果我们使用基准收益对股票收益进行回归,斜率和截距将分别为beta和alpha。 -
diff --git "a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/03 \346\226\271\346\263\225.cn.html" "b/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/03 \346\226\271\346\263\225.cn.html" deleted file mode 100644 index b64df7a..0000000 --- "a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/03 \346\226\271\346\263\225.cn.html" +++ /dev/null @@ -1,95 +0,0 @@ -- 我们的投资逻辑简单明了。我们认为上个月跑赢大盘的股票将继续跑赢大盘。我们根据alpha值对股票进行排名,每个月我们都会对排名前两支的股票“做多”。要使这一战略发挥作用,我们需要在每月月初做下列工作: -
- -- 道琼斯指数成份股很少变动,最近一次变动发生在2015年3月19日。为了使实施更加容易,我们在这个算法中简单地列出了当前的道琼期成份股。这意味着该算法最早的开始日期是2015年3月19日。 -
- -- 在初始化方法中,我们定义了日程事件来触发投资组合的每月重新平衡。有关如何使用日程事件的更多细节,可以阅读Documentation或查看示例ScheduledEventsAlgorithm。 -
-def Initialize(self): - self.Schedule.On(self.DateRules.MonthStart(self.benchmark), self.TimeRules.AfterMarketOpen(self.benchmark), Action(self.rebalance)) --
- 为了进行线性回归,我们需要编写一个函数来获取价格数据并输出回归结果。函数获得“资产价格”列表(x)和一个“基准价格”列表(y),然后计算变化百分比并进行线性回归。输出是一个包含截距和斜率的元组。 -
- -def regression(self,x,y): - x = np.array(x) - x = np.diff(x)/x[:-1] - y = np.array(y) - y = np.diff(y)/y[:-1] - A = np.vstack([x, np.ones(len(x))]).T - result = np.linalg.lstsq(A, y)[0] - beta = result[0] - alpha = result[1] - return(alpha,beta) --
- 每个月我们都会使用History API获得道琼斯30强成份股的历史价格。数据作为复杂的Slice对象从API返回。为了使其在算法中可以使用,我们将资产价格和基准价格提取到一个列表中。 -
-def get_regression_data(self,symbol,history): - symbol_price = [] - benchmark_price = [] - for i in history: - bar = i[symbol] - benchmark = i[self.benchmark] - symbol_price.append(bar.Close) - benchmark_price.append(benchmark.Close) - - result = self.regression(symbol_price,benchmark_price) - return result --
- 此功能是所有动作发生的地方,将作为预定事件在每个月的第一个交易日执行。SetHoldings的第二个参数是小数,将其设置为“1”表示算法将投资组合设置为“100%多头”而不使用杠杆。有关这一功能的更多信息可以在链接SetHoldings上阅读。 -
- -def rebalance(self): - # 获得历史股票代码和价格,然后放入元组中 - history = self.History(self.regression_dates, Resolution.Daily) - filter = [] - for i in self.symbols: - filter.append((i,self.get_regression_data(i, history)[0])) - # 根据alpha排序筛选 - filter.sort(key = lambda x : x[1],reverse = True) - sorted_symbols = [] - for i in range(2): - sorted_symbols.append(filter[i][0]) - # 获得所持有股票的代码 - holding_list = [] - for i in self.Portfolio: - if i.Value.Invested: - holding_list.append(i.Value.Symbol) - # 如果我们不打算继续持有现有的股份,则将其出售 - if holding_list: - for i in holding_list: - if i not in sorted_symbols: - self.Liquidate(i) - # 做多列表中的两支股票 - for i in sorted_symbols: - self.SetHoldings(i,1) -diff --git "a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/04 \346\200\273\347\273\223.cn.html" "b/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/04 \346\200\273\347\273\223.cn.html" deleted file mode 100644 index c68387d..0000000 --- "a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/04 \346\200\273\347\273\223.cn.html" +++ /dev/null @@ -1,14 +0,0 @@ -
- 我们已经证明,在一个平稳的市场中,上个月跑赢大盘的股票很可能在接下来的一个月里再次跑赢大盘。当市场波动时,线性回归的显著性水平降低,模型性能下降。我们可以通过观察资产(x)和基准(y)的协方差来理解这一点。当协方差减小到零时,beta将会减小。 -
- -\[\hat{\beta} = \frac{Cov[x,y]}{\sum (x_i - \beta{x})^2}\] - -- 作为实验,我们根据2015年的市场数据对算法进行了测试。对市场来说,这是一个极不稳定的时期,波动回到了接近于零的平均值,并在当年8月18日至8月25日期间下跌了近10%。该算法在今年的表现很差,收益率为-11.58%。与这一策略相关的风险包括大幅削减、缺乏对冲和止损。由于我们使用杠杆,风险增加了,因此在1月份有追加保证金的通知。我们可以通过应用以下技术来提高性能: -
- -- 使用OptionChainProvider进行回溯测试。 -
- diff --git "a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/06 \345\217\202\350\200\203\346\226\207\347\214\256.cn.html" "b/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/06 \345\217\202\350\200\203\346\226\207\347\214\256.cn.html" deleted file mode 100644 index f6f75d0..0000000 --- "a/04 Strategy Library/01 CAPM Alpha Ranking Strategy on Dow 30 Companies/06 \345\217\202\350\200\203\346\226\207\347\214\256.cn.html" +++ /dev/null @@ -1,8 +0,0 @@ -