1、量化投资 量化投资【网格交易】,号称全解析到社区搜了一下,有同学转贴,但还没实现。冰柠檬同学在钟摆策略中交易方法有用到网格的思想,但没有系统的介绍。好啦,干货来啦1.熊市不用跑,15年6月至今回测收益20%(同期大盘下跌35%)。2.10年至今6年,年化23%。3.震荡期的大红包,12年-13年年化30%。网格交易是啥子这是一种仓位策略,用于动态调仓。该大法秉持的原则是仓位策略比选股策略更重要。当然,我们做策略的,选出好的股票池是我们孜孜不倦的追求几个基本概念1.底仓价:价格的标准线,建仓和调仓的重要依据。2.低吸高抛:仓位控制贯彻低吸高抛,绝不追涨杀跌。根据网格设置买卖价位。下面举个例子o在
2、底仓价的附近,我们根据网格的大小,比如每跌3%按仓位买入(第一档:买40%,第二档:买30%,第三档:买20%,第四档:买10%)。要注意的是,这里买卖不是绝对的定量,而是调仓到对应仓位。如果第一次跌破3%,而后上涨到5%时,是不操作的,因为下跌时只建了40%的仓,而上涨5%的仓位是60%,不够抛出。3.网格大小:上图给出了3种网格大小。特点是买入网格小于卖出网格。这种不对称编织网格的道理在于网格的目的是网获利润,将利润建立在趋势的必然性中,而不仅仅是靠震荡的偶然性。先讲特点和局限吧首先,定理&公理:没有万能的策略。1.趋势决定策略的成败。在长期的上涨趋势中策略才能获得满意回报。2.选股集中在
3、波动大、成长性好的中小市值股票。不断盘整的周期股、大盘股和业绩不佳的垃圾股踩中就麻烦了。3.底仓价格设定在安全边际内。在估值顶部设立底仓价格风险极大,会造成很大的损失。4.牛市表现不佳。分散的仓位策略,没有依据价格形态来修改网格,都可能在牛市中跑输大盘。降低贝塔的代价就是阿尔法也较低。5.买卖规则不灵活,可能使一些重要的突破支持或阻力位置的买卖点被忽略在网格之外。来看看策略步骤1.选股重点行业:I64 互联网和相关服务,I65 软件和信息技术服务业低估值PE小:PE50小市值:分行业按市值排列选市值小的30只高波动:分行业在市值最小的30只中选出过去一年波动率最大的5只股票So,我们的股票池有
4、10只股。每3个月按上述条件更新一次股票池,更新时不在新股票池的股票全部清仓。2.网格:-3%买,5%卖、-5%买,10%卖、-8%买,15%卖、-12%买,20%卖四种大小的网格都会相应尝试一下看看效果。3.资金安排:在仓位控制时,满仓的概念是(总资金/股票池总数*2.5)后面的乘数是为了提高资金利用率,因为3个月的周期内可能不是每只股票都能达到满仓。好啦,收韭菜的时候到了回测做了很多组,大致是分市场行情(牛、震荡和熊)各做了一次。然后在震荡期调整网格大小分别做了4次。结论1.记住啦:熊市大网格、震荡小网格、长周期中间网格。这个比较好理解,网格小意味着操作频繁,震荡周期就是勤能补拙了,多多的
5、交易,熊市的话大网格容忍度高一些。2.【熊市】:选取2015-6-1至2016-1-26日,大网格-12%买,20%卖。最好的结果是半年多盈利20%(大盘同期大跌35%),年化40%+【长周期】:选取2010-1-1至2015-12-31日,中网格-8%买,15%卖。最好的结果是6年241%(大盘同期4%),年化23%。【震荡期】:选取2012-1-1至2013-12-31日,小网格-3%买,5%卖。最好的结果2年68%(大盘同期-0.5%),年化29.6%。3.下面上一个熊市大网格的回测结果,剩下的大家可以自己克隆代码改参数试咯补充1.小市值选股对策略的影响。这是个讲交易方法的策略,那么高收
6、益是否因为按小市值筛选股票得来的呢?仔细看代码会发现,这个策略选股的要点是波动率,而非小市值。下面加一下去掉小市值条件的长周期回测效果(加小市值:240%,不加小市值232%,并没太大的影响)2.行业选取对策略的影响高成长性行业的股票本来就收益可观,那我们看看控制单一变量,去掉网格交易方法,长期持有股票池的股票效果如何。注意:这里每3个月股票池轮换还是在做的,大盘止损的条件也不变。(长期持有:157%,运用网格交易:240%,采用网格交易收益更高,回撤也小一些)最后:这不是教科书,这不是教科书,这不是教科书。精要的是思想,细节的东西大家到搬砖贴里自行学习,有问题欢迎交流讨论,欢迎拍砖impor
7、t numpyimport pandas as pdfrom pandas import Seriesdef initialize(context): g.count = 30 g.cash = 1000000 g.buy_stock = g.initial_price = g.month = context.current_dt.month run_monthly(select_stock_by_industry,1,open)# 选股# 重点行业,低估值PE小,优质蓝筹市值大,高波动def select_stock_by_industry(context): #每3个月更新month =
8、context.current_dt.monthif month%3 != g.month%3: return industry_list = #C27,C39,I63, I64,I65 #K70, #M73,M74 #,N77,R86,R87 stocks = for industry_code in industry_list: stock_set = get_industry_stocks(industry_code) #选fundamental比较好的前15只,pe_ration30,market_cap,按market_cap取后20只股票。q = query( valuation.
9、code, valuation.market_cap, valuation.pe_ratio ).filter( valuation.code.in_(stock_set), valuation.pe_ratio 50 ).order_by( valuation.market_cap.desc() ).limit( g.count ) df = get_fundamentals(q) stock_set = list(dfcode) #取波动率最高的2只variance_list = for stock in stock_set: variance_list.append(variance(s
10、tock) s1 =Series(variance_list,index = stock_set).rank() stocks = list(s1s1 6.index) for stock in stocks: g.buy_stock.append(stock) g.initial_pricestock=0 set_universe(g.buy_stock) reset_position(context) return None# 轮换选股后清除新股票池外的持仓reset_position(context): if context.portfolio.positions.keys() !=:
11、for stock in context.portfolio.positions.keys(): if stock not in g.buy_stock: order_target_value(stock, 0) return None# 计算波动率def variance(security_code): hist1 = attribute_history(security_code, 180, 1d, close,df=False) narray=numpy.array(hist1close) sum1=narray.sum() narray2=narray*narraysum2=narra
12、y2.sum() N = len(hist1close) mean=sum1/N var=sum2/N-mean*2 return var# 计算股票前n日收益率def security_return(days,security_code): hist1 = attribute_history(security_code, days + 1, 1d, close,df=False) security_returns = (hist1close-1-hist1close0)/hist1close0 return security_returns# 止损,根据前n日收益率def conduct_n
13、day_stoploss(context,security_code,days,bench): if security_return(days,security_code)= bench: for stock in g.buy_stock: order_target_value(stock,0) log.info(Sell %s for stoploss %stock) return True else: return False# 计算股票累计收益率(从建仓至今)def security_accumulate_return(context,data,stock): current_price
14、 = datastock.pricecost = context.portfolio.positionsstock.avg_cost if cost != 0: return (current_price-cost)/cost else: return None# 个股止损,根据累计收益def conduct_accumulate_stoploss(context,data,stock,bench): if security_accumulate_return(context,data,stock) != None and security_accumulate_return(context,
15、data,stock) bench: order_target_value(stock,0) log.info(Sell %s for stoploss %stock)return True else: return False# 选股:连续N日下跌def is_fall_nday(days,stock): his = history(days+1,1d,close,stock,df =False) cnt = 0 for i in range(days): daily_returns = (hisstocki+1 - hisstocki)/hisstocki if daily_returns
16、 multi * moveavg: return True else:return False# 初始底仓选择,判断没有initial_price,则建立基准价def initial_price(context,data,stock): if g.initial_pricestock=0: g.initial_pricestock=datastock.price return None# 补仓、空仓:分n买入/卖出def setup_position(context,data,stock,bench,status): bottom_price= g.initial_pricestock if
17、bottom_price = 0:return cash = context.portfolio.cash current_price = datastock.price amount = context.portfolio.positionsstock.amount current_value = current_price*amount unit_value = g.cash/40 returns = (current_price-bottom_price)/bottom_price #卖出 if (status = short): if returns bench and current
18、_value 6*unit_value: order_target_value(stock,6*unit_value) if returns 2*bench and current_value 3*unit_value: order_target_value(stock,3*unit_value) if returns 3*bench and current_value 1*unit_value : order_target_value(stock,1*unit_value) if returns 4*bench and current_value 0: order_target_value(
19、stock,0) # 买入 if (status = long) and cash 0: if returns bench and current_value 4*unit_value: order_target_value(stock,4*unit_value) if returns 2*bench and current_value 7*unit_value: order_target_value(stock,7*unit_value) if returns 3*bench and current_value 9*unit_value :order_target_value(stock,9
20、*unit_value) if returns 4*bench and current_value 10*unit_value: order_target_value(stock,10*unit_value) return True # 每个单位时间(如果按天回测,则每天调用一次,如果按分钟,则每分钟调用一次)调用一次def handle_data(context, data): # 指数止损,前一天跌幅大于3% if conduct_nday_stoploss(context, 000001.XSHG, 2,-0.03): return for stock in g.buy_stock: i
21、f conduct_accumulate_stoploss(context,data,stock,-0.2):return #1.连续5日下跌,不操作 if is_fall_nday(5,stock): return #2.大于5日平均或10日平均1.5倍以上,不操作 if compare_current_nmoveavg(data,stock,5,1.5) or compare_current_nmoveavg(data,stock,10,1.5): return #初始设置底仓 initial_price(context,data,stock) #补仓步长:-3%,-5%,-8%,-12% setup_position(context,data,stock,-0.08,long) #空仓步长:5%,10%,15%,20% setup_position(context,data,stock,0.15,short)
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1