diff --git a/tests/backtesting/GA_Pre_Final.ipynb b/tests/backtesting/GA_Pre_Final.ipynb new file mode 100644 index 00000000..8519ad3a --- /dev/null +++ b/tests/backtesting/GA_Pre_Final.ipynb @@ -0,0 +1,376 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "import multiprocessing\n", + "import numpy as np\n", + "from deap import creator, base, tools, algorithms\n", + "from backtesting import BacktestingEngine,OptimizationSetting\n", + "from boll_channel_strategy import BollChannelStrategy\n", + "from atr_rsi_strategy import AtrRsiStrategy\n", + "from datetime import datetime\n", + "import multiprocessing #多进程\n", + "from scoop import futures #多进程\n", + "from functools import lru_cache" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "数据总体: 13824\n" + ] + } + ], + "source": [ + "setting = OptimizationSetting()\n", + "#setting.add_parameter('atr_length', 10, 50, 2)\n", + "#setting.add_parameter('atr_ma_length', 10, 50, 2)\n", + "#setting.add_parameter('rsi_length', 4, 50, 2)\n", + "#setting.add_parameter('rsi_entry', 4, 30, 1)\n", + "setting.add_parameter('boll_window', 4, 50, 2)\n", + "#setting.add_parameter('boll_dev', 4, 50, 2)\n", + "setting.add_parameter('cci_window', 4, 50, 2)\n", + "setting.add_parameter('atr_window', 4, 50, 2)\n", + "\n", + "\n", + "local_setting = setting.generate_setting()\n", + "total_sample = len(local_setting)\n", + "print(\"数据总体:\",total_sample)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dict_keys(['boll_window', 'cci_window', 'atr_window'])" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "setting_names = random.choice(local_setting).keys()\n", + "setting_names" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def parameter_generate():\n", + " setting_param = list(random.choice(local_setting).values())\n", + " return setting_param" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[22, 28, 22]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "parameter_generate()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'boll_window': 24, 'cci_window': 14, 'atr_window': 28}" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "setting=dict(zip(setting_names,parameter_generate()))\n", + "setting" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def object_func(strategy_avg):\n", + " \"\"\"\"\"\"\n", + " return run_backtesting(tuple(strategy_avg))\n", + " #return run_backtesting(strategy_avg)\n", + " \n", + "\n", + "@lru_cache(maxsize=1000000)\n", + "def run_backtesting(strategy_avg):\n", + " # 创建回测引擎对象\n", + " engine = BacktestingEngine()\n", + " engine.set_parameters(\n", + " vt_symbol=\"IF88.CFFEX\",\n", + " interval=\"1m\",\n", + " start=datetime(2016, 1, 1),\n", + " end=datetime(2019, 1,1),\n", + " rate=0.3/10000,\n", + " slippage=0.2,\n", + " size=300,\n", + " pricetick=0.2,\n", + " capital=1_000_000,\n", + " )\n", + " \n", + " setting=dict(zip(setting_names,strategy_avg))\n", + " \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": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(-0.51, -0.28)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "object_func(parameter_generate())" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "target_names = [\"return_drawdown_ratio\" , \"sharpe_ratio\"]\n", + "def show_result(hof):\n", + " for i in range(len(hof)):\n", + " solution = hof[i] \n", + " parameter=dict(zip(setting_names,solution))\n", + " result=dict(zip(target_names,list(object_func(solution))))\n", + " print({**parameter, **result})" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "from time import time\n", + "#设置优化方向:最大化收益回撤比,最大化夏普比率\n", + "creator.create(\"FitnessMax\", base.Fitness, weights=(1.0, 1.0)) # 1.0 求最大值;-1.0 求最小值\n", + "creator.create(\"Individual\", list, fitness=creator.FitnessMax)\n", + "\n", + "def optimize(population=None):\n", + " \"\"\"\"\"\" \n", + " start = time() \n", + " toolbox = base.Toolbox() \n", + "\n", + " # 初始化 \n", + " toolbox.register(\"individual\", tools.initIterate, creator.Individual,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=1) \n", + " toolbox.register(\"evaluate\", object_func) \n", + " toolbox.register(\"select\", tools.selNSGA2) \n", + " #pool = multiprocessing.Pool()\n", + " #toolbox.register(\"map\", pool.map)\n", + " #toolbox.register(\"map\", futures.map)\n", + " \n", + " \n", + " #遗传算法参数设置\n", + " MU = 80 #设置每一代选择的个体数\n", + " LAMBDA = 100 #设置每一代产生的子女数\n", + " POP=100\n", + " CXPB, MUTPB, NGEN = 0.95, 0.05,30 #分别为种群内部个体的交叉概率、变异概率、产生种群代数\n", + " \n", + " if population==None:\n", + " LAMBDA = POP = int(pow(total_sample, 1/2.7))\n", + " MU = int(0.8*POP) \n", + " \n", + " pop = toolbox.population(POP) #设置族群里面的个体数量\n", + " hof = tools.ParetoFront() #解的集合:帕累托前沿(非占优最优集)\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", + " print(\"开始运行遗传算法,每代族群总数:%s, 优良品种筛选个数:%s,迭代次数:%s,交叉概率:%s,突变概率:%s\" %(POP,MU,NGEN,CXPB,MUTPB))\n", + " \n", + "\n", + " #运行算法\n", + " algorithms.eaMuPlusLambda(pop, toolbox, MU, LAMBDA, CXPB, MUTPB, NGEN, stats,\n", + " halloffame=hof) #esMuPlusLambda是一种基于(μ+λ)选择策略的多目标优化分段遗传算法\n", + "\n", + " end = time()\n", + " cost = int((end - start))\n", + "\n", + " print(\"遗传算法优化完成,耗时%s秒\"% (cost))\n", + " print(\"输出帕累托前沿解集:\")\n", + " show_result(hof)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "开始运行遗传算法,每代族群总数:34, 优良品种筛选个数:27,迭代次数:30,交叉概率:0.95,突变概率:0.05\n", + "gen\tnevals\tmean \tstd \tmin \tmax \n", + "0 \t34 \t[0.08852941 0.00352941]\t[0.5373362 0.29107188]\t[-0.7 -0.63]\t[1.51 0.5 ]\n", + "1 \t34 \t[0.60148148 0.27518519]\t[0.31013383 0.08573734]\t[0.32 0.18] \t[1.51 0.5 ]\n", + "2 \t34 \t[0.79333333 0.33851852]\t[0.27758215 0.06742369]\t[0.47 0.25] \t[1.54 0.5 ]\n", + "3 \t34 \t[1.00888889 0.39777778]\t[0.3147525 0.06214281]\t[0.7 0.33] \t[1.54 0.5 ]\n", + "4 \t34 \t[1.41074074 0.47444444]\t[0.22881217 0.04661373]\t[0.96 0.36] \t[1.92 0.57]\n", + "5 \t34 \t[1.59666667 0.51222222]\t[0.14714568 0.0255797 ]\t[1.51 0.49] \t[1.92 0.57]\n", + "6 \t34 \t[1.66259259 0.52185185]\t[0.16585564 0.02981884]\t[1.52 0.49] \t[1.92 0.57]\n", + "7 \t34 \t[1.8737037 0.55666667]\t[0.07713135 0.01763834]\t[1.75 0.53] \t[1.95 0.57]\n", + "8 \t34 \t[1.93666667 0.57 ]\t[0.01490712 0. ]\t[1.92 0.57] \t[1.95 0.57]\n", + "9 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "10 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "11 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "12 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "13 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "14 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "15 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "16 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "17 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "18 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "19 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "20 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "21 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "22 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "23 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "24 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "25 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "26 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "27 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "28 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "29 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "30 \t34 \t[1.95 0.57] \t[0. 0.] \t[1.95 0.57] \t[1.95 0.57]\n", + "遗传算法优化完成,耗时309秒\n", + "输出帕累托前沿解集:\n", + "{'boll_window': 48, 'cci_window': 40, 'atr_window': 22, 'return_drawdown_ratio': 1.95, 'sharpe_ratio': 0.57}\n", + "{'boll_window': 48, 'cci_window': 50, 'atr_window': 22, 'return_drawdown_ratio': 1.95, 'sharpe_ratio': 0.57}\n" + ] + } + ], + "source": [ + "optimize()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + " MU = 80 #设置每一代选择的个体数\n", + " POP = 100 #设置每一代产生的子女数\n", + " CXPB, MUTPB, NGEN = 0.95, 0.05,20 \n", + " print(\"开始运行遗传算法,每代族群总数:%s, 优良品种筛选个数:%s,迭代次数:%s,交叉概率:%s,突变概率:%s\" %(POP,MU,NGEN,CXPB,MUTPB))" + ] + }, + { + "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 +}