记一次有趣的米筐经历~
一开始我是拒绝的!
但是最后还是答应了哈哈哈
说是要用米筐这个量化平台做个股票的回测分析,老师给的策略很简单:
“如果过去 10 年,每个月初进行次判断,如果上个月沪深 300 指数涨了,按均分买入
上个月下跌最大的 100 只股票(就是每只股票买 0.01 乘总财富),然后在当月月底卖出,
这样持续地每个月操作,这样的策略的收益是怎样的?不用考虑手续费。如果上个月沪
深 300 指数跌了,则在本月无操作”
一开始我以为在pycharm上面搞就行了,但是我发现事情没那么简单(因为我怎么搞都无法调用米筐的接口)原来是要验证才行……
附个图片:
然后我就去试了试Tushare,发现也还是不行最后才知道原来是可以直接登录进去在米筐自己基于IPython NoteBook搭建的Ricequant研究平台进行分析:
进去之后点击免费试用(要先登录)就行
然后就是金融知识十分匮乏的我根本看不懂这些专有名词都是些啥………………
终于在折腾了一晚上之后我才搞明白基本回测操作和分析终于做出了这个作业
第一题代码:
1 def query_fundamental(context, bar_dict): 2 # 查询所有公司的股票的收益,查询日期是最近的一个交易日 3 # 按照公司的股票的收益 降序排序 之后 取前100个 4 fundamental_df = get_fundamentals( 5 query( 6 fundamentals.income_statement.revenue 7 ).order_by( 8 fundamentals.income_statement.revenue.desc() 9 ).limit( 10 100 11 ) 12 ) 13 14 # 将查询结果dataframe的fundamental_df存放在context里面: 15 context.fundamental_df = fundamental_df 16 17 # 实时打印日志看下查询结果 18 logger.info(context.fundamental_df) 19 20 # 对于每一个股票按照平均现金买入: 21 context.stocks = context.fundamental_df.columns.values 22 update_universe(context.stocks) 23 24 # 先查一下选出来的股票是否在已有的portfolio里面: 25 # 先清仓然后再买入这一个月新的符合条件的股票 26 logger.info("Clearing all the current positions.") 27 # positions一个包含所有仓位的字典,.keys可以获得 28 for holding_stock in context.portfolio.positions.keys(): 29 if context.portfolio.positions[holding_stock].quantity != 0: # 如果当前的持仓股数不等于0就清空 30 order_percent(holding_stock, 0) 31 # 买入等于现有投资组合1%的价值的股票 32 logger.info("Building new positions for portfolio.") 33 for stock in context.stocks: 34 order_percent(stock, 0.01) 35 logger.info("Buying: 0.01 % of cash for stock: " + str(stock)) 36 37 38 def init(context): 39 scheduler.run_monthly(query_fundamental, monthday=1) 40 41 42 def handle_bar(context, bar_dict): 43 pass
回测结果:
第二题代码:
1 import talib 2 import datetime 3 4 def query_fundamental(context, bar_dict): 5 #选择沪深300里面所有的股票代码 6 stocks_name = index_components('沪深300') 7 8 # 获取一个月前的时间 9 if context.now.month - 1 is 0: 10 a_month_ago = 12 11 month_ago = context.now.replace(month=a_month_ago, year=context.now.year-1) 12 else: 13 a_month_ago = context.now.month - 1 14 month_ago = context.now.replace(month=a_month_ago) 15 16 # 获得上个月的沪深指数300的涨跌情况 17 benchmark_price = get_price('399300.XSHE', start_date=month_ago, fields=['close']) 18 19 # 如果上个月的沪深指数涨了: 20 if benchmark_price[0] < benchmark_price[-1]: 21 22 # 将深沪指数300所有的公司的收益降序排序之后取前100个 23 fundamental_df = get_fundamentals( 24 query( 25 fundamentals.income_statement.revenue 26 ).filter(fundamentals.income_statement.stockcode.in_(stocks_name)).order_by( 27 fundamentals.income_statement.revenue.desc() 28 ).limit( 29 100 30 ) 31 ) 32 33 # 将查询结果dataframe的fundamental_df存放在context里面: 34 context.fundamental_df = fundamental_df 35 36 # 实时打印日志看下查询结果 37 logger.info(context.fundamental_df) 38 39 # 对每一个股票均分买入: 40 context.stocks = context.fundamental_df.columns.values 41 update_universe(context.stocks) 42 43 44 # 先清仓(即将所有股票卖出)再买入这一个月新的股票 45 46 logger.info("清除现在所有的仓位") 47 # 先查一下选出来的股票是否在已有的portfolio里面:positions是一个包含所有仓位的字典,.keys可以获得 48 for holding_stock in context.portfolio.positions.keys(): 49 # 如果当前的持仓股数不等于0就清空 50 if context.portfolio.positions[holding_stock].quantity != 0: 51 order_percent(holding_stock, 0) 52 53 # 买入等于现有投资组合1%的价值的股票 54 logger.info("重新买入") 55 for stock in context.stocks: 56 order_percent(stock, 0.01) 57 logger.info("Buying: 0.01 % of cash for stock: " + str(stock)) 58 59 60 def init(context): 61 # 每个月的月初进行一次买卖操作 62 scheduler.run_monthly(query_fundamental, monthday=1) 63 64 65 def handle_bar(context, bar_dict): 66 # 这里不做任何操作 67 pass
回测结果:
第三第四题的代码类似就是大于小于号需要切换以及
if benchmark_price[0] < benchmark_price[-1]:
fundamentals.income_statement.revenue.asc() 或者是 desc()
第三题回测结果:
第四题回测结果: