参数优化
参数优化模块主要由3部分构成:
参数设置
- 设置参数优化区间:如boll_window设置起始值为18,终止值为24,步进为2,这样就得到了[18, 20, 22, 24] 这4个待优化的参数了。
- 设置优化目标字段:如夏普比率、盈亏比、总收益率等。
- 随机生成参数对组合:使用迭代工具产生参数对组合,然后把参数对组合打包到一个个字典组成的列表中
- class OptimizationSetting:
- """
- Setting for runnning optimization.
- """
- def __init__(self):
- """"""
- self.params = {}
- self.target_name = ""
- def add_parameter(
- self, name: str, start: float, end: float = None, step: float = None
- ):
- """"""
- if not end and not step:
- self.params[name] = [start]
- return
- if start >= end:
- print("参数优化起始点必须小于终止点")
- return
- if step <= 0:
- print("参数优化步进必须大于0")
- return
- value = start
- value_list = []
- while value <= end:
- value_list.append(value)
- value += step
- self.params[name] = value_list
- def set_target(self, target_name: str):
- """"""
- self.target_name = target_name
- def generate_setting(self):
- """"""
- keys = self.params.keys()
- values = self.params.values()
- products = list(product(*values))
- settings = []
- for p in products:
- setting = dict(zip(keys, p))
- settings.append(setting)
- return settings
参数对组合回测
多进程优化时,每个进程都会运行optimize函数,输出参数对组合以及目标优化字段的结果。其步骤如下:
- 调用回测引擎
- 输入回测相关设置
- 输入参数对组合到策略中
- 运行回测
- 返回回测结果,包括:参数对组合、目标优化字段数值、策略统计指标
- def optimize(
- target_name: str,
- strategy_class: CtaTemplate,
- setting: dict,
- vt_symbol: str,
- interval: Interval,
- start: datetime,
- rate: float,
- slippage: float,
- size: float,
- pricetick: float,
- capital: int,
- end: datetime,
- mode: BacktestingMode,
- ):
- """
- Function for running in multiprocessing.pool
- """
- engine = BacktestingEngine()
- engine.set_parameters(
- vt_symbol=vt_symbol,
- interval=interval,
- start=start,
- rate=rate,
- slippage=slippage,
- size=size,
- pricetick=pricetick,
- capital=capital,
- end=end,
- mode=mode
- )
- engine.add_strategy(strategy_class, setting)
- engine.load_data()
- engine.run_backtesting()
- engine.calculate_result()
- statistics = engine.calculate_statistics()
- target_value = statistics[target_name]
- return (str(setting), target_value, statistics)
多进程优化
- 根据CPU的核数来创建进程:若CPU为4核,则创建4个进程
- 在每个进程都调用apply_async( )的方法运行参数对组合回测,其回测结果添加到results中 (apply_async是异步非阻塞的,即不用等待当前进程执行完毕,随时根据系统调度来进行进程切换。)
- pool.close()与pool.join()用于进程跑完任务后,去关闭进程。
- 对results的内容通过目标优化字段标准进行排序,输出结果。
- pool = multiprocessing.Pool(multiprocessing.cpu_count())
- results = []
- for setting in settings:
- result = (pool.apply_async(optimize, (
- target_name,
- self.strategy_class,
- setting,
- self.vt_symbol,
- self.interval,
- self.start,
- self.rate,
- self.slippage,
- self.size,
- self.pricetick,
- self.capital,
- self.end,
- self.mode
- )))
- results.append(result)
- pool.close()
- pool.join()
- # Sort results and output
- result_values = [result.get() for result in results]
- result_values.sort(reverse=True, key=lambda result: result[1])
- for value in result_values:
- msg = f"参数:{value[0]}, 目标:{value[1]}"
- self.output(msg)
- return result_values