海龟策略的信号来源于唐奇安通道突破。简单的说就是若突破上轨则做多,突破下轨则做空。我们可以对信号进行改良,如换成布林带通道,金肯特纳通道等等,并且增加过滤条件和离场条件。

但是呢?新的问题又来了:若用了新的指标,需要通过不断调试来得到“最优”参数,这样会耗费大量的时间。

那么,有没有办法在尽量少得时间内,尽可能得到全局最优解或者次优解呢?

答案就是遗传算法啦!

 
 
 

遗传算法原理


具体原理详见:
遗传算法原理简介

一文读懂遗传算法工作原理(附Python实现)

 

遗传算法要做的事情并不复杂:

  1. 随机生成一大推策略参数(称之为族群,族群内的个体对应某一组策略参数)
  2. 族群内个体间进行3类活动:个体间两两交叉互换;个体某个参数发生变异;个体繁殖(即直接复制参数)
  3. 形成子代
  4. 通过目标函数(如最大化夏普比率,最大化总盈亏等)对母代族群和子代族群进行评分
  5. 通过特点筛选标准(如NSGA-Ⅱ)从母代和子代中筛选个体,形成第二代族群。(类似进化论中的“自然选择”)
  6. 新的族群在特定的评分标准和筛选标准中不断迭代(即重复1-5步骤),得到最优解/次优解。

 
 
 

遗传算法代码示例


1.随机生成待优化的策略参数

def parameter_generate():
    '''
    根据设置的起始值,终止值和步进,随机生成待优化的策略参数
    '''
    parameter_list = []
    p1 = random.randrange(4,50,2)      #入场窗口
    p2 = random.randrange(4,50,2)      #出场窗口
    p3 = random.randrange(4,50,2)      #基于ATR窗口止损窗
    p4 = random.randrange(18,40,2)     #基于ATR的动态调仓 

    parameter_list.append(p1)
    parameter_list.append(p2)
    parameter_list.append(p3)
    parameter_list.append(p4)

    return parameter_list

 

  1. 设置目标优化函数(收益回撤比和夏普比率)
def object_func(strategy_avg):
    """
    本函数为优化目标函数,根据随机生成的策略参数,运行回测后自动返回2个结果指标:收益回撤比和夏普比率
    """
    # 创建回测引擎对象
    engine = BacktestingEngine()
    # 设置回测使用的数据                       
    engine.setBacktestingMode(engine.BAR_MODE)      # 设置引擎的回测模式为K线
    engine.setDatabase("VnTrader_Daily_Db", 'XBTHOUR')  # 设置使用的历史数据库
    engine.setStartDate('20170401')                 # 设置回测用的数据起始日期
    engine.setEndDate('20181230')                   # 设置回测用的数据起始日期

    # 配置回测引擎参数
    engine.setSlippage(0.5)                        
    engine.setRate(0.2/100)                     
    engine.setSize(10)                            
    engine.setPriceTick(0.5)                      
    engine.setCapital(1000000) 

    setting = {'entryWindow': strategy_avg[0],       #布林带窗口
               'exitWindow': strategy_avg[1],        #布林带通道阈值
               'atrWindow': strategy_avg[2],         #CCI窗口
               'artWindowUnit': strategy_avg[3],}    #ATR窗口               

    #加载策略          
    engine.initStrategy(TurtleTradingStrategy, setting)    
    # 运行回测,返回指定的结果指标   
    engine.runBacktesting()          # 运行回测
    #逐日回测   
    engine.calculateDailyResult()
    backresult = engine.calculateDailyStatistics()[1] 

    returnDrawdownRatio = round(backresult['returnDrawdownRatio'],2)  #收益回撤比
    sharpeRatio= round(backresult['sharpeRatio'],2)                   #夏普比率
    return returnDrawdownRatio , sharpeRatio

 

3.运行基于Deap库的遗传算法(具体步骤看代码中文注释)

#设置优化方向:最大化收益回撤比,最大化夏普比率
creator.create("FitnessMulti", base.Fitness, weights=(1.0, 1.0)) # 1.0 求最大值;-1.0 求最小值
creator.create("Individual", list, fitness=creator.FitnessMulti)

def optimize():
    """"""   
    toolbox = base.Toolbox()  #Toolbox是deap库内置的工具箱,里面包含遗传算法中所用到的各种函数

    # 初始化     
    toolbox.register("individual", tools.initIterate, creator.Individual,parameter_generate) # 注册个体:随机生成的策略参数parameter_generate()                                          
    toolbox.register("population", tools.initRepeat, list, toolbox.individual)               #注册种群:个体形成种群                                    
    toolbox.register("mate", tools.cxTwoPoint)                                               #注册交叉:两点交叉  
    toolbox.register("mutate", tools.mutUniformInt,low = 4,up = 40,indpb=0.6)                #注册变异:随机生成一定区间内的整数
    toolbox.register("evaluate", object_func)                                                #注册评估:优化目标函数object_func()    
    toolbox.register("select", tools.selNSGA2)                                               #注册选择:NSGA-II(带精英策略的非支配排序的遗传算法)


    #遗传算法参数设置
    MU = 40                                  #设置每一代选择的个体数
    LAMBDA = 160                             #设置每一代产生的子女数
    pop = toolbox.population(400)            #设置族群里面的个体数量
    CXPB, MUTPB, NGEN = 0.5, 0.35, 40        #分别为种群内部个体的交叉概率、变异概率、产生种群代数
    hof = tools.ParetoFront