巴菲特的alpha--部分代码

巴菲特的alpha–部分代码

#!/usr/bin/env python3
#  -*- coding: utf-8 -*-
"""
作者:qiujier
分享者:vx 1985159637
在《巴菲特的alpha》文章里,后人把巴菲特的收益分成六个维度,分别是市场,估值,规模,动量,质量和波动率六个维度。我们今天就开始复现其中的原理,
除去市场维度,我们从其他五个维度分别挑选因子,总共6个,组成6因子模型。
对于因子的处理,由于因子来自不同维度,所以无需进行降维或者因子正交处理来解决它的相关性问题,所以简单进行了去极值和标准化处理
对于股票列表,已经进行剔除ST,上市未满60天的新股,停牌股和开盘涨停股
对于打分方式:针对升序因子乘以-1;针对降序因子乘以1,最后进行叠加
在择时方面,采用RSRS的方式对指数进行择时信号。
资金规模在10000000,20日调仓,回测时间从2010-01-01到2018-11-08
"""import pandas as pd
import numpy as np
import datetime as dt
import talib as ta
from datetime import date, timedelta
import statsmodels.api as sm# 初始化账户
def init(context):set_params(context)set_variables(context)set_backtest()run_daily(stop_loss)# 设置策参数
def set_params(context):g.tc = 20  # 调仓频率g.t = 0g.big_small = 'big'  # big是降序,small为升序context.stock = '000300.SH'g.long_pct = 0.05g.stock = '000300.SH'  # 择时选取的指数g.total_positionprevious = 0  # 仓位g.N = 18  # RSRS选取的回归长度g.M = 1100  # RSRS均值窗口def set_variables(context):context.X_length = 11context.flag = Trueg.buy = 0.7  # 买入阀门g.sell = -0.7  # 卖出阀门g.ans = []g.ans_rightdev = []def set_backtest():set_benchmark('000300.SH')  # 设置基准set_slippage(PriceSlippage(0.002))  # 设置可变滑点def before_trading(context):# 需要先建立过去的数据集合,否则后面新数据没有历史数据作为窗口if context.flag:initlast_date = context.now - timedelta(days=1)prices = get_price(g.stock, '2006-06-05', initlast_date, '1d', ['high', 'low'])# 获取最高价和最低价highs = prices.highlows = prices.low# 建立一个初始的装有beta从过去到初始阶段的历史数据的列表g.ansg.ans = []for i in range(len(highs))[g.N:]:data_high = highs.iloc[i - g.N + 1:i + 1]data_low = lows.iloc[i - g.N + 1:i + 1]X = sm.add_constant(data_low)model = sm.OLS(data_high, X)results = model.fit()g.ans.append(results.params[1])# 装有rsquare从过去到初始阶段历史数据的列表g.ans_rightdev.append(results.rsquared)context.flag = False# 个股止损
def stop_loss(context, bar_dict):for stock in list(context.portfolio.positions):cumulative_return = bar_dict[stock].close / context.portfolio.positions[stock].cost_basisif cumulative_return < 0.9:order_target_value(stock, 0)def handle_bar(context, bar_dict):stock = g.stockbeta = 0r2 = 0prices = history(stock, ['high', 'low'], g.N, '1d', False, 'pre', is_panel=1)highs = prices.highlows = prices.lowX = sm.add_constant(lows)model = sm.OLS(highs, X)# 得到betabeta = model.fit().params[1]# 将新的beta添加到装有历史数据列表g.ans.append(beta)# 得到rsquare数据r2 = model.fit().rsquared# 将新的rsquare添加到装有历史数据列表g.ans_rightdev.append(r2)# 为了标准化当下的beta数值,拿过去1100天的数据作为均值的窗口section = g.ans[-g.M:]# 计算均值序列mu = np.mean(section)# 计算标准化RSRS指标序列sigma = np.std(section)zscore = (section[-1] - mu) / sigma# 计算右偏RSRS标准分,就是将标准化后的beta数据乘以原始beta再乘以拟合度zscore_rightdev = zscore * beta * r2# 根据交易信号买入卖出if zscore_rightdev > g.buy:total_position = 1elif zscore_rightdev < g.sell:total_position = 0else:total_position = g.total_positionpreviousif (g.total_positionprevious != total_position) or (g.t % g.tc == 0):g.total_positionprevious = total_positionlast_date = get_last_datetime().strftime('%Y%m%d')stock_list = list(get_all_securities('stock', date=last_date).index)# 对stock_list进行去除st,停牌等处理stock_list = fun_unpaused(bar_dict, stock_list)stock_list = fun_st(bar_dict, stock_list)stock_list = fun_highlimit(bar_dict, stock_list)stock_list = fun_remove_new(stock_list, 60)# 以下是各单因子# 规模因子cap_df = market_cap(stock_list, 'valuation_market_cap', last_date)cap_df = cap_df * -1# 估值因子PB_df = PB(stock_list, 'valuation_pb', last_date)PB_df = PB_df * -1# 动量因子MTM20_df = MTM20(stock_list, 'MTM20')MTM20_df = MTM20_df * -1# 质量因子# 1.ROE(高利润)roe_df = roe(stock_list, 'profit_roe_ths', last_date)# 2.净利润同比增长率(高成长)net_profit_growth_ratio_df = net_profit_growth_ratio(stock_list, 'growth_net_profit_growth_ratio', last_date)# 波动率因子ATR20_df = ATR20(stock_list, 'ATR20')ATR20_df = ATR20_df * -1# 合并多因子concat_obj = [cap_df, PB_df, MTM20_df, roe_df, net_profit_growth_ratio_df, ATR20_df]df = pd.concat(concat_obj, axis=1)df = df.dropna()#       log.info(type(df))sum = df.sum(axis=1)# log.info(sum)# 进行排序if g.big_small == 'big':# 按照大排序sum.sort_values(ascending=False, inplace=True)if g.big_small == 'small':# 按照小排序sum.sort_values(ascending=True, inplace=True)# 根据比例取出排序后靠前部分stock_list1 = sum[0:int(len(stock_list) * g.long_pct)].index# log.info(stock_list1)buy_list = []for stock in stock_list1:buy_list.append(stock)# 买卖操作for stock in list(context.portfolio.positions):if stock not in buy_list:order_target(stock, 0)cash = context.portfolio.portfolio_valueposition = cash * g.total_positionprevious#       position=cash*g.SAR_signalnum = int(len(stock_list) * g.long_pct)## 买入for stock in buy_list:order_target_value(stock, position / num)g.t = g.t + 1"""
以下是单因子
"""


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部