金融老法师 发表于 2019-7-17 22:24:20

量化交易策略——BIAS策略简单小试and加强版

乖离率(BIAS)简称Y值,是移动平均(moving average)原理派生的一项技术指标,测试原理是建立在:如果股价偏离移动平均线太远,不管股价在移动平均线之上或之下,都有可能趋向平均线的这一条原理上。而乖离率则表示股价偏离趋向指标所占到的百分比值。
   
    计算方法:N期BIAS=(当日收盘价-N期平均收盘价)/N期平均收盘价*100%

    回测:

    资金:100000
    频率:日
    交易资产:平安银行
    手续费滑点采用平台默认
    采用13日bias值,买入卖出临界值为0.065,即bias<-0.065满仓买入,bias>0.065全仓卖出
   
    分析:

    信号设置较为简单,可以考虑和别的指标结合下。
    交易次数较少,每次都是全买全卖,买完了等好久都卖不出去的情况很容易出现,导致错过很多更好的买点。
    参数没有计算机优化。
    后期大趋势下,表现不好。
    由bias值与股价的图看出,bias值并没有明显领先股价做出变化。

收益与风险
http://s1.sinaimg.cn/bmiddle/001uapR3zy74WjkcdjO00&690

http://s11.sinaimg.cn/bmiddle/001uapR3zy74Wjke96i9a&690

http://s5.sinaimg.cn/bmiddle/001uapR3zy74WjkkcwAd4&690

http://s6.sinaimg.cn/bmiddle/001uapR3zy74WjkaNwha5&690

http://s13.sinaimg.cn/bmiddle/001uapR3zy74Wjk8GRKcc&690

源码:


# 定义一个全局变量, 保存要操作的证券
# 000001(股票:平安银行)
security = '000001.XSHE'
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
set_universe()

# 每个单位时间(如果按天回测,则每天调用一次,如果按分钟,则每分钟调用一次)调用一次
def handle_data(context, data):
    # 取得过去十三天的平均价格
    average_price = data.mavg(13)
    # 取得当前价格
    current_price = data.price
    # 取得当前的现金
    cash = context.portfolio.cash
    # 计算BIAS值
    bias=(current_price-average_price)/average_price
    # 设置BIAS操作临界值
    bias_operationvalue=0.065;
    # 如果BIAS值小于-BIAS操作临界值,买入
    if bias < -1*bias_operationvalue:
      # 计算可以买多少只股票
      number_of_shares = int(cash/current_price)
      # 购买量大于0时,下单
      if number_of_shares > 0:
            # 买入股票
            order(security, +number_of_shares)
            # 记录这次买入
            log.info("Buying %s" % (security))
    # 如果BIAS大于BIAS操作临界值,卖出
    elif bias > bias_operationvalue and context.portfolio.positions.amount > 0:
      # 卖出所有股票,使这只股票的最终持有量为0
      order_target(security, 0)
      # 记录这次卖出
      log.info("Selling %s" % (security))
    # 画出当前的价格
    record(stock_price=data.price)
    record(bias=bias*20+7)
bias策略加强版

    主要变化

    1.加入了多股票方法,每隔一个周期开始前,结算上一周期未卖出的股票,从股票池(此次选的沪深300)里挑选一些股票(挑选标准此次选的是价格超过5日均线2%),在一个周期内每个单位时间循环访问每个挑选出来的股票,进行判断是否买入(判断标准是13日bias值<-0.06)或卖出(判断标准是13日bias值>0.06).

    2.加入了止损,每只股票亏损超过20%,则止损。

    3.加入了仓位管理,将资金平均分配给每个股票,每个股票依然只能是进行满仓空仓操作。

    4.加入了胜率统计,在卖的时候判断,盈利则成功,亏损则失败,胜率算法为,成功次数除以成功与失败之和。在日志里输出,此次的胜率是64%。

    核心代码

#初始化
def initialize(context):
    ......
#每个单位时间执行一次handle_data内的指令
def handle_data(context, data):
    #如果是一个新的周期
    if g.i%g.period==0:
      #清算所有未卖出的股票
      clear(context, data)
      #从股票池中挑选股票
      findstock(context, data)
    # 循环股票池
    for security in g.buystocks:
         #进行股票交易


收益与风险
http://s4.sinaimg.cn/mw690/001uapR3zy74WjubUPN13&690

http://s4.sinaimg.cn/mw690/001uapR3zy74Wjudgwrb3&690

http://s13.sinaimg.cn/mw690/001uapR3zy74WjueYAQ6c&690

http://s7.sinaimg.cn/mw690/001uapR3zy74WjugQBw66&690

http://s2.sinaimg.cn/mw690/001uapR3zy74Wju9cml51&690


源码:
# 定义一个全局变量, 保存要操作的证券
def initialize(context):
    #设置股票池
    context.stocks = get_index_stocks('000300.XSHG')
    set_universe(context.stocks)
    #设置最多挑选的股票数量
    g.max_stock=10
    #平均分配股票的可用资金
    g.max_use_cash=context.portfolio.cash/g.max_stock
    #设置变量,记录操作成功与失败次数
    g.win=0.0
    g.lose=0.0
    #计时器
    g.i=-1;
    #股票池中选择出的股票列表
    g.buystocks = []
    #更新股票列表周期
    g.period=60

# 每个单位时间(如果按天回测,则每天调用一次,如果按分钟,则每分钟调用一次)调用一次
def handle_data(context, data):
    g.i=g.i+1
    #判断是否为一个新周期
    if g.i%g.period==0:
      #清算所有未卖出的股票
      clear(context, data)
      #从股票池中挑选股票
      findstock(context, data)
    # 循环股票池
    for security in g.buystocks:
      # 得到该股票当前价格
      current_price = data.price
      #得到十三日均价
      avg = data.mavg(13)
      #计算bias值
      bias = (current_price-avg)/avg
      #计算持仓成本
      current_avgcost = context.portfolio.positions.avg_cost
      #计算当前股票的盈利状况
      if context.portfolio.positions.amount > 0:
            r_ratio=(current_price-current_avgcost)/current_avgcost
      else:
            r_ratio=0
   
      # 如果bias值小于-0.06,且仓位为空,则买入
      if bias < -0.06 and context.portfolio.positions.amount == 0:
            # 计算可以买多少只股票
            amount = int(g.max_use_cash / current_price)
            # 下入买入单
            order(security, amount)
      # 如果bias值大于0.06,且仓位非空,则卖出
      elif (r_ratio<-0.2 or bias > 0.06) and context.portfolio.positions.amount > 0:
            # 卖出所有股票,使这只股票的最终持有量为0
            orderfail=order_target(security, 0)
            if orderfail!=None:#防止订单无效,如停牌、没钱买等
                #统计胜率
                winorlose(r_ratio)
    #计算操作次数
    times=g.win+g.lose
    #取得当前时间
    date = context.current_dt.strftime("%Y-%m-%d")
    #在最后一个单位时间,清空仓位,并在日志中输出成功次数,失败次数,与胜率
    if date=='2015-09-30':
      clear(context, data
      if times !=0:
            print(g.win,g.lose,g.win/times)
            
   
def clear(context, data):
    for security in g.buystocks:
      # 得到该股票当前价格
      current_price = data.price
      #计算持仓成本
      current_avgcost = context.portfolio.positions.avg_cost
      
      #计算该股票的盈利状况
      if context.portfolio.positions.amount > 0:
            r_ratio=(current_price-current_avgcost)/current_avgcost
      else:
            r_ratio=0
      #卖出股票
      orderfail=order_target(security, 0)
      #统计胜率
      if orderfail!=None:#防止订单无效,如停牌、没钱买等
            winorlose(r_ratio)
#挑选股票
def findstock(context, data):
    #初始化股票列表
    g.buystocks = []
    #循环股票池
    for security in context.stocks:
      # 得到该股票当前价格
      current_price = data.price
      #得到五日均价
      avg = data.mavg(5)
      #如果当前价格高出五日均线2%则选入
      if current_price>1.02*avg:
            g.buystocks.append(security)
      #如果选出足够的股票则终止挑选
      if len(g.buystocks)==g.max_stock:
            break
#统计胜率,收益为正则判为成功,收益为负则判为失败
def winorlose(r_ratio):
    if r_ratio > 0:
      g.win=g.win+1;
    else:
      g.lose=g.lose+1;





geek168 发表于 2019-7-17 23:29:24

:):):):):):)

gyshssl 发表于 2019-7-17 23:31:04

厉害厉害,这个策略不错
页: [1]
查看完整版本: 量化交易策略——BIAS策略简单小试and加强版