commit
d4a70b8a9b
189
tests/backtesting/genetic_algorithm.ipynb
Normal file
189
tests/backtesting/genetic_algorithm.ipynb
Normal file
@ -0,0 +1,189 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import random\n",
|
||||
"import multiprocessing\n",
|
||||
"import numpy as np\n",
|
||||
"from deap import creator, base, tools, algorithms\n",
|
||||
"from vnpy.app.cta_strategy.backtesting import BacktestingEngine\n",
|
||||
"from boll_channel_strategy import BollChannelStrategy\n",
|
||||
"from datetime import datetime\n",
|
||||
"import multiprocessing #多进程\n",
|
||||
"from scoop import futures #多进程"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def parameter_generate():\n",
|
||||
" '''\n",
|
||||
" 根据设置的起始值,终止值和步进,随机生成待优化的策略参数\n",
|
||||
" '''\n",
|
||||
" parameter_list = []\n",
|
||||
" p1 = random.randrange(4,50,2) #布林带窗口\n",
|
||||
" p2 = random.randrange(4,50,2) #布林带通道阈值\n",
|
||||
" p3 = random.randrange(4,50,2) #CCI窗口\n",
|
||||
" p4 = random.randrange(18,40,2) #ATR窗口 \n",
|
||||
"\n",
|
||||
" parameter_list.append(p1)\n",
|
||||
" parameter_list.append(p2)\n",
|
||||
" parameter_list.append(p3)\n",
|
||||
" parameter_list.append(p4)\n",
|
||||
"\n",
|
||||
" return parameter_list"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def object_func(strategy_avg):\n",
|
||||
" \"\"\"\n",
|
||||
" 本函数为优化目标函数,根据随机生成的策略参数,运行回测后自动返回2个结果指标:收益回撤比和夏普比率\n",
|
||||
" \"\"\"\n",
|
||||
" # 创建回测引擎对象\n",
|
||||
" engine = BacktestingEngine()\n",
|
||||
" engine.set_parameters(\n",
|
||||
" vt_symbol=\"IF88.CFFEX\",\n",
|
||||
" interval=\"1m\",\n",
|
||||
" start=datetime(2018, 9, 1),\n",
|
||||
" end=datetime(2019, 1,1),\n",
|
||||
" rate=0,\n",
|
||||
" slippage=0,\n",
|
||||
" size=300,\n",
|
||||
" pricetick=0.2,\n",
|
||||
" capital=1_000_000,\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" setting = {'boll_window': strategy_avg[0], #布林带窗口\n",
|
||||
" 'boll_dev': strategy_avg[1], #布林带通道阈值\n",
|
||||
" 'cci_window': strategy_avg[2], #CCI窗口\n",
|
||||
" 'atr_window': strategy_avg[3],} #ATR窗口 \n",
|
||||
"\n",
|
||||
" #加载策略 \n",
|
||||
" #engine.initStrategy(TurtleTradingStrategy, setting)\n",
|
||||
" engine.add_strategy(BollChannelStrategy, setting)\n",
|
||||
" engine.load_data()\n",
|
||||
" engine.run_backtesting()\n",
|
||||
" engine.calculate_result()\n",
|
||||
" result = engine.calculate_statistics(Output=False)\n",
|
||||
"\n",
|
||||
" return_drawdown_ratio = round(result['return_drawdown_ratio'],2) #收益回撤比\n",
|
||||
" sharpe_ratio= round(result['sharpe_ratio'],2) #夏普比率\n",
|
||||
" return return_drawdown_ratio , sharpe_ratio"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"#设置优化方向:最大化收益回撤比,最大化夏普比率\n",
|
||||
"creator.create(\"FitnessMulti\", base.Fitness, weights=(1.0, 1.0)) # 1.0 求最大值;-1.0 求最小值\n",
|
||||
"creator.create(\"Individual\", list, fitness=creator.FitnessMulti)\n",
|
||||
"\n",
|
||||
"def optimize():\n",
|
||||
" \"\"\"\"\"\" \n",
|
||||
" toolbox = base.Toolbox() #Toolbox是deap库内置的工具箱,里面包含遗传算法中所用到的各种函数\n",
|
||||
"\n",
|
||||
" # 初始化 \n",
|
||||
" toolbox.register(\"individual\", tools.initIterate, creator.Individual,parameter_generate) # 注册个体:随机生成的策略参数parameter_generate() \n",
|
||||
" toolbox.register(\"population\", tools.initRepeat, list, toolbox.individual) #注册种群:个体形成种群 \n",
|
||||
" toolbox.register(\"mate\", tools.cxTwoPoint) #注册交叉:两点交叉 \n",
|
||||
" toolbox.register(\"mutate\", tools.mutUniformInt,low = 4,up = 40,indpb=0.6) #注册变异:随机生成一定区间内的整数\n",
|
||||
" toolbox.register(\"evaluate\", object_func) #注册评估:优化目标函数object_func() \n",
|
||||
" toolbox.register(\"select\", tools.selNSGA2) #注册选择:NSGA-II(带精英策略的非支配排序的遗传算法)\n",
|
||||
" #pool = multiprocessing.Pool()\n",
|
||||
" #toolbox.register(\"map\", pool.map)\n",
|
||||
" #toolbox.register(\"map\", futures.map)\n",
|
||||
"\n",
|
||||
" #遗传算法参数设置\n",
|
||||
" MU = 40 #设置每一代选择的个体数\n",
|
||||
" LAMBDA = 160 #设置每一代产生的子女数\n",
|
||||
" pop = toolbox.population(400) #设置族群里面的个体数量\n",
|
||||
" CXPB, MUTPB, NGEN = 0.5, 0.35,40 #分别为种群内部个体的交叉概率、变异概率、产生种群代数\n",
|
||||
" hof = tools.ParetoFront() #解的集合:帕累托前沿(非占优最优集)\n",
|
||||
"\n",
|
||||
" #解的集合的描述统计信息\n",
|
||||
" #集合内平均值,标准差,最小值,最大值可以体现集合的收敛程度\n",
|
||||
" #收敛程度低可以增加算法的迭代次数\n",
|
||||
" stats = tools.Statistics(lambda ind: ind.fitness.values)\n",
|
||||
" np.set_printoptions(suppress=True) #对numpy默认输出的科学计数法转换\n",
|
||||
" stats.register(\"mean\", np.mean, axis=0) #统计目标优化函数结果的平均值\n",
|
||||
" stats.register(\"std\", np.std, axis=0) #统计目标优化函数结果的标准差\n",
|
||||
" stats.register(\"min\", np.min, axis=0) #统计目标优化函数结果的最小值\n",
|
||||
" stats.register(\"max\", np.max, axis=0) #统计目标优化函数结果的最大值\n",
|
||||
"\n",
|
||||
" #运行算法\n",
|
||||
" algorithms.eaMuPlusLambda(pop, toolbox, MU, LAMBDA, CXPB, MUTPB, NGEN, stats,\n",
|
||||
" halloffame=hof) #esMuPlusLambda是一种基于(μ+λ)选择策略的多目标优化分段遗传算法\n",
|
||||
"\n",
|
||||
" return pop"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"optimize()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.7.1"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": true,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": false,
|
||||
"title_cell": "Table of Contents",
|
||||
"title_sidebar": "Contents",
|
||||
"toc_cell": false,
|
||||
"toc_position": {},
|
||||
"toc_section_display": true,
|
||||
"toc_window_display": false
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
@ -293,7 +293,7 @@ class BacktestingEngine:
|
||||
self.output("逐日盯市盈亏计算完成")
|
||||
return self.daily_df
|
||||
|
||||
def calculate_statistics(self, df: DataFrame = None):
|
||||
def calculate_statistics(self, df: DataFrame = None, Output=True):
|
||||
""""""
|
||||
self.output("开始计算策略统计指标")
|
||||
|
||||
@ -325,6 +325,7 @@ class BacktestingEngine:
|
||||
daily_return = 0
|
||||
return_std = 0
|
||||
sharpe_ratio = 0
|
||||
return_drawdown_ratio = 0
|
||||
else:
|
||||
# Calculate balance related time series data
|
||||
df["balance"] = df["net_pnl"].cumsum() + self.capital
|
||||
@ -373,38 +374,42 @@ class BacktestingEngine:
|
||||
else:
|
||||
sharpe_ratio = 0
|
||||
|
||||
return_drawdown_ratio = -total_return / max_ddpercent
|
||||
|
||||
# Output
|
||||
self.output("-" * 30)
|
||||
self.output(f"首个交易日:\t{start_date}")
|
||||
self.output(f"最后交易日:\t{end_date}")
|
||||
if Output:
|
||||
self.output("-" * 30)
|
||||
self.output(f"首个交易日:\t{start_date}")
|
||||
self.output(f"最后交易日:\t{end_date}")
|
||||
|
||||
self.output(f"总交易日:\t{total_days}")
|
||||
self.output(f"盈利交易日:\t{profit_days}")
|
||||
self.output(f"亏损交易日:\t{loss_days}")
|
||||
self.output(f"总交易日:\t{total_days}")
|
||||
self.output(f"盈利交易日:\t{profit_days}")
|
||||
self.output(f"亏损交易日:\t{loss_days}")
|
||||
|
||||
self.output(f"起始资金:\t{self.capital:,.2f}")
|
||||
self.output(f"结束资金:\t{end_balance:,.2f}")
|
||||
self.output(f"起始资金:\t{self.capital:,.2f}")
|
||||
self.output(f"结束资金:\t{end_balance:,.2f}")
|
||||
|
||||
self.output(f"总收益率:\t{total_return:,.2f}%")
|
||||
self.output(f"年化收益:\t{annual_return:,.2f}%")
|
||||
self.output(f"最大回撤: \t{max_drawdown:,.2f}")
|
||||
self.output(f"百分比最大回撤: {max_ddpercent:,.2f}%")
|
||||
self.output(f"总收益率:\t{total_return:,.2f}%")
|
||||
self.output(f"年化收益:\t{annual_return:,.2f}%")
|
||||
self.output(f"最大回撤: \t{max_drawdown:,.2f}")
|
||||
self.output(f"百分比最大回撤: {max_ddpercent:,.2f}%")
|
||||
|
||||
self.output(f"总盈亏:\t{total_net_pnl:,.2f}")
|
||||
self.output(f"总手续费:\t{total_commission:,.2f}")
|
||||
self.output(f"总滑点:\t{total_slippage:,.2f}")
|
||||
self.output(f"总成交金额:\t{total_turnover:,.2f}")
|
||||
self.output(f"总成交笔数:\t{total_trade_count}")
|
||||
self.output(f"总盈亏:\t{total_net_pnl:,.2f}")
|
||||
self.output(f"总手续费:\t{total_commission:,.2f}")
|
||||
self.output(f"总滑点:\t{total_slippage:,.2f}")
|
||||
self.output(f"总成交金额:\t{total_turnover:,.2f}")
|
||||
self.output(f"总成交笔数:\t{total_trade_count}")
|
||||
|
||||
self.output(f"日均盈亏:\t{daily_net_pnl:,.2f}")
|
||||
self.output(f"日均手续费:\t{daily_commission:,.2f}")
|
||||
self.output(f"日均滑点:\t{daily_slippage:,.2f}")
|
||||
self.output(f"日均成交金额:\t{daily_turnover:,.2f}")
|
||||
self.output(f"日均成交笔数:\t{daily_trade_count}")
|
||||
self.output(f"日均盈亏:\t{daily_net_pnl:,.2f}")
|
||||
self.output(f"日均手续费:\t{daily_commission:,.2f}")
|
||||
self.output(f"日均滑点:\t{daily_slippage:,.2f}")
|
||||
self.output(f"日均成交金额:\t{daily_turnover:,.2f}")
|
||||
self.output(f"日均成交笔数:\t{daily_trade_count}")
|
||||
|
||||
self.output(f"日均收益率:\t{daily_return:,.2f}%")
|
||||
self.output(f"收益标准差:\t{return_std:,.2f}%")
|
||||
self.output(f"Sharpe Ratio:\t{sharpe_ratio:,.2f}")
|
||||
self.output(f"日均收益率:\t{daily_return:,.2f}%")
|
||||
self.output(f"收益标准差:\t{return_std:,.2f}%")
|
||||
self.output(f"Sharpe Ratio:\t{sharpe_ratio:,.2f}")
|
||||
self.output(f"收益回撤比:\t{return_drawdown_ratio:,.2f}")
|
||||
|
||||
statistics = {
|
||||
"start_date": start_date,
|
||||
@ -430,6 +435,7 @@ class BacktestingEngine:
|
||||
"daily_return": daily_return,
|
||||
"return_std": return_std,
|
||||
"sharpe_ratio": sharpe_ratio,
|
||||
"return_drawdown_ratio": return_drawdown_ratio,
|
||||
}
|
||||
|
||||
return statistics
|
||||
|
@ -1,5 +1,6 @@
|
||||
# encoding: UTF-8
|
||||
"""
|
||||
Author: KeKe
|
||||
Please install tiger-api before use.
|
||||
pip install tigeropen
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user