• 参数优化
    • 参数设置
    • 参数对组合回测
    • 多进程优化

    参数优化

    参数优化模块主要由3部分构成:

    参数设置

    • 设置参数优化区间:如boll_window设置起始值为18,终止值为24,步进为2,这样就得到了[18, 20, 22, 24] 这4个待优化的参数了。
    • 设置优化目标字段:如夏普比率、盈亏比、总收益率等。
    • 随机生成参数对组合:使用迭代工具产生参数对组合,然后把参数对组合打包到一个个字典组成的列表中
    1. class OptimizationSetting:
    2. """
    3. Setting for runnning optimization.
    4. """
    5.  
    6. def __init__(self):
    7. """"""
    8. self.params = {}
    9. self.target_name = ""
    10.  
    11. def add_parameter(
    12. self, name: str, start: float, end: float = None, step: float = None
    13. ):
    14. """"""
    15. if not end and not step:
    16. self.params[name] = [start]
    17. return
    18.  
    19. if start >= end:
    20. print("参数优化起始点必须小于终止点")
    21. return
    22.  
    23. if step <= 0:
    24. print("参数优化步进必须大于0")
    25. return
    26.  
    27. value = start
    28. value_list = []
    29.  
    30. while value <= end:
    31. value_list.append(value)
    32. value += step
    33.  
    34. self.params[name] = value_list
    35.  
    36. def set_target(self, target_name: str):
    37. """"""
    38. self.target_name = target_name
    39.  
    40. def generate_setting(self):
    41. """"""
    42. keys = self.params.keys()
    43. values = self.params.values()
    44. products = list(product(*values))
    45.  
    46. settings = []
    47. for p in products:
    48. setting = dict(zip(keys, p))
    49. settings.append(setting)
    50.  
    51. return settings

    参数对组合回测

    多进程优化时,每个进程都会运行optimize函数,输出参数对组合以及目标优化字段的结果。其步骤如下:

    • 调用回测引擎
    • 输入回测相关设置
    • 输入参数对组合到策略中
    • 运行回测
    • 返回回测结果,包括:参数对组合、目标优化字段数值、策略统计指标
    1. def optimize(
    2. target_name: str,
    3. strategy_class: CtaTemplate,
    4. setting: dict,
    5. vt_symbol: str,
    6. interval: Interval,
    7. start: datetime,
    8. rate: float,
    9. slippage: float,
    10. size: float,
    11. pricetick: float,
    12. capital: int,
    13. end: datetime,
    14. mode: BacktestingMode,
    15. ):
    16. """
    17. Function for running in multiprocessing.pool
    18. """
    19. engine = BacktestingEngine()
    20. engine.set_parameters(
    21. vt_symbol=vt_symbol,
    22. interval=interval,
    23. start=start,
    24. rate=rate,
    25. slippage=slippage,
    26. size=size,
    27. pricetick=pricetick,
    28. capital=capital,
    29. end=end,
    30. mode=mode
    31. )
    32.  
    33. engine.add_strategy(strategy_class, setting)
    34. engine.load_data()
    35. engine.run_backtesting()
    36. engine.calculate_result()
    37. statistics = engine.calculate_statistics()
    38.  
    39. target_value = statistics[target_name]
    40. return (str(setting), target_value, statistics)

    多进程优化

    • 根据CPU的核数来创建进程:若CPU为4核,则创建4个进程
    • 在每个进程都调用apply_async( )的方法运行参数对组合回测,其回测结果添加到results中 (apply_async是异步非阻塞的,即不用等待当前进程执行完毕,随时根据系统调度来进行进程切换。)
    • pool.close()与pool.join()用于进程跑完任务后,去关闭进程。
    • 对results的内容通过目标优化字段标准进行排序,输出结果。
    1. pool = multiprocessing.Pool(multiprocessing.cpu_count())
    2.  
    3. results = []
    4. for setting in settings:
    5. result = (pool.apply_async(optimize, (
    6. target_name,
    7. self.strategy_class,
    8. setting,
    9. self.vt_symbol,
    10. self.interval,
    11. self.start,
    12. self.rate,
    13. self.slippage,
    14. self.size,
    15. self.pricetick,
    16. self.capital,
    17. self.end,
    18. self.mode
    19. )))
    20. results.append(result)
    21.  
    22. pool.close()
    23. pool.join()
    24.  
    25. # Sort results and output
    26. result_values = [result.get() for result in results]
    27. result_values.sort(reverse=True, key=lambda result: result[1])
    28.  
    29. for value in result_values:
    30. msg = f"参数:{value[0]}, 目标:{value[1]}"
    31. self.output(msg)
    32.  
    33. return result_values