{ "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 }