量化投资笔记(二)

编写一个简单的策略

基本策略:

  • 设定好要交易的股票数量stocksnum
  • 每天找出市值排名最小的前stocksnum只股票作为要买入的股票
  • 若已持有的股票的市值已经不够小而不在要买入的股票中,则卖出这些股票
  • 买入要买入的股票,买入金额为当前可用资金的stocksnum分之一。

加强策略:

  • 希望能实现通过一个变量period控制操作的周期,即每period天进行一次选股并交易。
def initialize(context):
  run_daily(period,time='every_bar')
  # 设定好要交易的股票数量stocksnum
  g.stocksnum = 7
  # 设定交易周期
  g.p = 13
  # 记录策略进行天数
  g.days = 0

def period(context):
    if g.days % g.p == 0:#设置13天买一次股票
        # 找出市值排名最小的前stocksnum只股票作为要买入的股票
        scu= get_index_stocks('000001.XSHG')+get_index_stocks('399106.XSHE')
        df=get_fundamentals(query(valuation.code).filter(valuation.code.\
        in_(scu)).order_by(valuation.market_cap.asc()).limit(g.stocksnum))
        buylist=list(df['code'])
        # 若已持有的股票的市值已经不够小而不在要买入的股票中,则卖出这些股票。
        for stock in context.portfolio.positions:
          if stock not in buylist:
              order_target(stock, 0) 
        # 买入要买入的股票,买入金额为可用资金的stocksnum分之一
        for s in buylist:
            order_value(s,(context.portfolio.available_cash)/g.stocksnum)
    g.days+=g.days

代码中有一个选出所有股票的小技巧:使用获取指数成分股方法可以获取上证指数和深证综指的成分股,两者加起来就是当前全市场股票的股票列表,用加号可以连接两个list。以下是该策略在2016年的回测结果:

在这里插入图片描述
继续优化:

  • 排除停牌股票、ST股票和涨停股票
  • 加入止损条件
def initialize(context):
  run_daily(period,time='every_bar')
  g.stocksnum = 7
  g.p = 13
  g.days = 0

def period(context):
    if g.days % g.p == 0:
        # 找出市值排名最小的前stocksnum只股票作为要买入的股票
        scu= get_index_stocks('000001.XSHG')+get_index_stocks('399106.XSHE')
        # 排除停牌股票、ST股票和涨停股票
        stock_list = []
        current_data = get_current_data()#获得universe中股票的信息
        for stock in scu:
	        if not current_data[stock].is_st:
	            if not current_data[stock].paused:
	                if current_data[stock].last_price !=current_data[stock].high_limit:
	                    stock_list.append(stock)
        df=get_fundamentals(query(valuation.code).filter(valuation.code.\
        in_(stock_list)).order_by(valuation.market_cap.asc()).limit(g.stocksnum))
        buylist=list(df['code'])
        
        # 若已持有的股票的市值已经不够小而不在要买入的股票中,则卖出,并且止损。
        for stock in context.portfolio.positions:
	        cost = context.portfolio.positions[stock].avg_cost
	        price = context.portfolio.positions[stock].price
	        ret = price/cost - 1
	        if stock not in buylist: 
	            order_target(stock, 0) 
	        else:
	            if ret < -0.05:    #止损
	                order_target(stock,0)
	                buylist.remove(stock)
	                print("触发止损")
	            if ret > 0.05:     #止盈
	                order_target(stock,0)
	                buylist.remove(stock)
	                print("触发止盈")
        # 买入要买入的股票,买入金额为可用资金的stocksnum分之一
        for s in buylist:
            order_value(s,(context.portfolio.available_cash)/g.stocksnum)
    g.days+=g.days

get_current_data(security_list=None)函数可以获得数据在一个单位时间(天/分钟)的涨跌停价、是否停牌、当天的开盘价等。如果security_list 是 None,代表使用 universe 中的股票。该函数返回一个 dict 对象,key 是股票代码,value 数据具体如下:

  • high_limit : 涨停价
  • low_limit : 跌停价
  • paused : 是否停止或者暂停交易,当停牌、未上市或退市后返回 True
  • is_st : 是否包含 ST,*ST
  • day_open : 当天开盘价,分钟回测时可用
  • name : 股票现在的名称
  • industry_code : 股票现在所属的行业代码

在这里插入图片描述
可以看到虽然该策略不如上一个策略表现好,但是更贴近市场真实情况。

参考文献

https://www.joinquant.com/view/community/detail/8ec7aaaa899cf928550f89a104637f22?type=1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值