第四章:经典量化策略集锦(第三篇:网格交易—动态调仓策略)

导语:市场上股票的价格总是在不断的上下波动,投资者通过低买高卖获利。第三篇将向大 


家介绍网格交易,一个动态的调仓策略,有效解决仓位和价位控制。 






一、策略阐述 






窥探网格交易 






    “追涨杀跌”与“高抛低吸”是两种完全不同的交易方式,也是大家听到较多的两个炒 


股词汇。顾名思义,“追涨杀跌”就是股价上涨买入,股价下跌卖出。“高抛低吸”就是股 


价下跌买入,股价上涨卖出。 






    但是纯粹的“高抛低吸”只是概念,根本无法形成一个交易系统。而且A 股市场,只有 


股价上涨,投资者才能从中获利。如果股价跌跌不休,投资者每一次补仓都亏得更多。 






    网格交易与“高抛低吸”相似,但网格交易更为成熟,主要体现在以下两个方面: 






    1.价位管理:网格交易有明确的分批买入价格和卖出价格,不受任何主观意识影响。 


    2.仓位管理:网格交易有明确的买入仓位和卖出仓位,不受任何主观意识影响。 






    具体参考下图: 






     


    可以明确的是,上述网格交易中每笔交易都是盈利的。只要股价不断的上下波动,那么 


策略就可以不断的盈利。 






     




----------------------- Page 78-----------------------


网格交易的注意点 






    1. 网格交易需要规避长期下跌的个股,由于低买高卖的特征,网格交易盈利需要依赖股 


价波动,进行长期积累,如果个股长期下跌,那么持股市值亏损可能会吞没低买高卖的盈利。 






    2.  网格交易需要尽量寻找波动较高的股票,这样就可以进行更多次的低买高卖操作,提 


高网格交易收益率。 






    3. 因为网格交易没有止损,只有越跌越买,而且不盈利绝不退出。网格交易需要做好股 


价继续下跌的措施,保证在极限底部仍然要有现金使用。 






    4. 网格交易因其上涨卖出的性质,决定了其追求的是绝对收益,以及保证每笔交易是盈 


利的。 






构建网格交易 






    第一步:我们选取互联网游戏行业龙头:三七互娱为投资标的,该股票业绩优异,波动 


率大,且股价靠近安全边际。 






    第二步:建底仓,仓位40% 。 






    第三步:设置网格,每上涨2% ,卖出2000 股,每下跌2% ,买入2000 股。 






    第四步:对三七互娱该股票进行网格交易回测,并打印日志。 






    以下为策略实现的基本信息: 






    策略实现难度:1 


    实现过程中所需要用到的API 函数,ps:通过 MindGo 量化交易平台 API 文档快速掌握: 






需要用到的API 函数         功能 






set_benchmark       设置基准指数 






g.                  全局变量 






account.positions   查询账户信息 






get_price           获取历史行情数据 






get_datetime()      获取当前时间 




----------------------- Page 79-----------------------


二、代码示意图 






三、编写释义 






  本策略使用到了全局变量:g,策略编写上需与大家分享全局变量的概念,并讲述全局 


变量的使用 






  全局变量、局部变量、对象 






  一般量化策略同时含有全局变量、局部变量、对象,全局变量即为函数外部的变量,可 


以在整个程序访问。局部变量即为函数内部的变量,仅仅在某个函数内访问。对象内存储信 


息,比如资金账户对象account 存储账户信息,data 对象用于获取行情数据等等。 






  【示例】 






  全局变量:g 






  局部变量:sh、sz 






  对象:account、data 






  注意:每个量化交易平台的全局变量都是系统定义的,用户无法自定义一个新的全局变 


量,但是局部变量可以自定义。  






    全局变量 g 和 account 是不同的,account 是账户对象。在自定义函数中,用户使用该对 


象的变量时,需在函数中传入 account,也就是 def 函数名(account):,但是全局变量 g 不同, 


即使函数不输入任何信息,还是可以直接使用全局变量 g 中的变量,可以方便策略编写。 




----------------------- Page 80-----------------------


四、最终结果 






策略回测区间:2017.11.01-2018.02.11   


回测资金:1000000 


回测频率:分钟级 


回测结果:红色曲线为策略收益率曲线,蓝色曲线为对应的基准指数收益率曲线 






网格交易日志 (局部): 






2017-11-03 09:31:00 - INFO 执行卖出操作,价位:23.48 ,数量:2000 


2017-11-03 09:49:00 - INFO 执行买入操作,价位:22.9 ,数量:2000 


2017-11-03 14:15:00 – INFO 执行买入操作,价位:22.35 ,数量:2000 






2017-11-06 09:31:00 - INFO 执行买入操作,价位:21.73 ,数量:2000 


2017-11-06 10:56:00 – INFO 执行卖出操作,价位:22.19 ,数量:2000 






2017-11-07 09:31:00 - INFO 执行卖出操作,价位:22.95 ,数量:2000 


2017-11-07 09:35:00 - INFO 执行卖出操作,价位:23.45 ,数量:2000 


2017-11-07 09:43:00 - INFO 执行买入操作,价位:22.86 ,数量:2000 


2017-11-07 14:51:00 – INFO 执行卖出操作,价位:23.34 ,数量:2000 






2017-11-08 09:39:00 - INFO 执行买入操作,价位:22.82 ,数量:2000 


2017-11-08 09:48:00 - INFO 执行卖出操作,价位:23.3 ,数量:2000 


2017-11-08 10:07:00 - INFO 执行卖出操作,价位:23.9 ,数量:2000 


2017-11-08 10:24:00 - INFO 执行卖出操作,价位:24.58 ,数量:2000 




----------------------- Page 81-----------------------


2017-11-08 11:06:00 - INFO 执行买入操作,价位:24.07 ,数量:2000 


2017-11-08 13:05:00 - INFO 执行卖出操作,价位:24.59 ,数量:2000 


2017-11-08 14:16:00 – INFO 执行买入操作,价位:24.07 ,数量:2000 






2017-11-09 09:31:00 – INFO 执行买入操作,价位:23.42 ,数量:2000 






2017-11-10 09:54:00 - INFO 执行买入操作,价位:22.93 ,数量:2000 


2017-11-10 11:00:00 - INFO 执行买入操作,价位:22.45 ,数量:2000 






策略源代码: 






import numpy 


import pandas as pd 


#============================初始化函数================================ 


def initialize(account): 


    g.stock = '002555.SZ'#设置网格交易的股票 


    set_benchmark(g.stock) 


    g.x1 = 0.02   #上涨多少卖出 


    g.x2 = 0.02   #下跌多少买入 


    g.y1 = 2000   #卖出多少 


    g.y2 = 2000   #买入多少 


    g.p = 0 #记录上一次交易的价格 


    g.p1 = 0 #下次买入价 


    g.p2 = 0 #下次卖出价 


    g.day = 1 #记录运行天数 


    g.tall = []#记录做 t 资金变动 


    pass 


def before_trading_start(account,data): 


    if g.day == 1: 


        account.jc = True 


    else: 


        account.jc = False 


    g.t = [] 


#===========================开盘时=============================== 


def handle_data(account,data): 


    date=get_datetime().strftime('%Y%m%d%H%M%S') 


    if account.jc == True: 


        order_target_percent(g.stock,0.4) 


        p=history(g.stock, ['close'], 1, '1m', False, 'pre', is_panel=1)['close'].iloc[0] 


        g.p=p  


        g.p1 = g.p*(1-g.x1) 


        g.p2 = g.p*(1+g.x2) 


    else: 


        p=history(g.stock, ['close'], 1, '1m', False, 'pre', is_panel=1)['close'].iloc[0] 


        if p <g.p1: 


            order(g.stock,g.y2) 


            g.p=p  




----------------------- Page 82-----------------------


            g.p1 = g.p*(1-g.x1) 


            g.p2 = g.p*(1+g.x2) 


            log.info('时间:{},执行买入操作,价位:{},数量:{}'.format(date,p,g.y2)) 


            g.t.append(-1*(p*g.y2)) 


            g.tall.append(-1*(p*g.y2)) 


        elif p>g.p2: 


            order(g.stock,-g.y1) 


            g.p=p  


            g.p1 = g.p*(1-g.x1) 


            g.p2 = g.p*(1+g.x2) 


            log.info('时间:{},执行卖出操作,价位:{},数量:{}'.format(date,p,g.y1)) 


            g.t.append(p*g.y1) 


            g.tall.append(p*g.y1) 


        else: 


            pass 


def after_trading_end(account,data): 


    if g.day==1: 


        log.info('首日建仓') 


        pass 


    else: 


        log.info(' 当日做 T 资金变动:{}'.format(sum(g.t))) 


        log.info('全部做 T 资金变动:{}'.format(sum(g.tall))) 


        pass 


    g.day=g.day+1 


     




----------------------- Page 83-----------------------
阅读更多

更多精彩内容