import optuna
from multiprocessing import Process, Queue, Manager
import numpy as np
def backtest_func(queue:Queue):
import random
# 回测结果
result = dict()
result['annual_return_rate'] = random.random()
# 可以增加其它策略业绩评价指标
queue.put(result) # 回测结果增加到队列
return result
def run_backtest_parallel(backtest_func, n_jobs):
queue = Manager().Queue()
# 多进程并行回测
job_list = []
for i in range(n_jobs):
job = Process(target=backtest_func, args=(queue,))
job_list.append(job)
job.start()
for job in job_list:
job.join()
# 回测结果接收
post_results = list()
while (not queue.empty()):
post_result = queue.get()
post_results.append(post_result)
return post_results
if __name__ == '__main__':
# 执行多进程并行
post_results = run_backtest_parallel(backtest_func=backtest_func, n_jobs=5)
# 查看结果
for post_result in post_results:
print(post_result)
import optuna
from multiprocessing import Process, Queue, Manager
import numpy as np
def backtest_func(trading_params:dict):
import random
period = trading_params['period']
# 回测结果
result = dict()
result['annual_return_rate'] = random.random()
# 可以增加其它策略业绩评价指标
return result
def objective_func(trial, backtest_func, trading_params:dict, queue:Queue):
# 交易参数更新
trading_params_dict = dict()
for key, value in trading_params.items():
if key == 'period':
low = value[0]
high = value[-1]
step = value[1] - value[0]
trading_params_dict[key] = trial.suggest_int(name=key, low=low, high=high, step=step)
elif key == 'limited_turning_rate':
low = value[0]
high = value[-1]
step = round(value[1] - value[0], 2)
trading_params_dict[key] = trial.suggest_float(name=key, low=low, high=high, step=step)
else:
trading_params_dict[key] = value
result = backtest_func(trading_params_dict)
queue.put(result)
return result.get('annual_return_rate', 0.0) # 优化年化收益率
def optimize(backtest_func, n_trials, trading_parmas:dict, queue:Queue):
study_name = 'optuna_optimize'
storage_name = "sqlite:///{}.db".format(study_name)
study = optuna.load_study(study_name=study_name, storage=storage_name)
study.optimize(lambda trial: objective_func(trial, backtest_func=backtest_func, trading_params=trading_parmas, queue=queue),
n_trials=n_trials, gc_after_trial=True)
def run_backtest_parallel(backtest_func, trading_params, n_trials, n_jobs):
# 创建学习过程
study_name = 'optuna_optimize'
storage_name = "sqlite:///{}.db".format(study_name)
study = optuna.create_study(study_name=study_name, direction='maximize', storage=storage_name, load_if_exists=True)
queue = Manager().Queue()
# 多进程并行回测
job_list = []
for i in range(n_jobs):
job = Process(target=optimize, args=(backtest_func, n_trials, trading_params, queue))
job_list.append(job)
job.start()
for job in job_list:
job.join()
# 回测结果接收
post_results = list()
while (not queue.empty()):
post_result = queue.get()
post_results.append(post_result)
return post_results
if __name__ == '__main__':
# 交易参数设置
trading_params = dict()
PERIOD_LIST = list(range(1, 11, 1)) # 换仓周期
TURNOVER_RATE_LIST = np.arange(0.3, 0.8, 0.01) # 换手率
trading_params['period'] = PERIOD_LIST
trading_params['limited_turning_rate'] = TURNOVER_RATE_LIST
# 执行多进程并行
post_results = run_backtest_parallel(backtest_func=backtest_func, trading_params=trading_params, n_trials=10, n_jobs=5)
# 查看结果
for post_result in post_results:
print(post_result)