From 4cd84b45a5aa91b69e0e3cb0a83a6bf3ff0c8ccc Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Fri, 3 May 2019 16:10:11 +0800 Subject: [PATCH] [Mod]add return value of run_ga_optimization --- tests/backtesting/GA_Pre_Final.ipynb | 104 +++-------------- tests/backtesting/run_ga.py | 27 +++++ tests/backtesting/turtle.ipynb | 60 +++++----- vnpy/app/cta_strategy/backtesting.py | 164 ++++++++++++++------------- 4 files changed, 153 insertions(+), 202 deletions(-) create mode 100644 tests/backtesting/run_ga.py diff --git a/tests/backtesting/GA_Pre_Final.ipynb b/tests/backtesting/GA_Pre_Final.ipynb index 0d99a169..de3b6d46 100644 --- a/tests/backtesting/GA_Pre_Final.ipynb +++ b/tests/backtesting/GA_Pre_Final.ipynb @@ -20,17 +20,9 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "数据总体: 13824\n" - ] - } - ], + "outputs": [], "source": [ "setting = OptimizationSetting()\n", "#setting.add_parameter('atr_length', 10, 50, 2)\n", @@ -50,20 +42,9 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "dict_keys(['boll_window', 'cci_window', 'atr_window'])" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "setting_names = random.choice(local_setting).keys()\n", "setting_names" @@ -71,7 +52,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -82,40 +63,18 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[48, 6, 26]" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "parameter_generate()" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'boll_window': 16, 'cci_window': 48, 'atr_window': 6}" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "setting=dict(zip(setting_names,parameter_generate()))\n", "setting" @@ -123,7 +82,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -167,41 +126,16 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2019-05-03 15:02:07.528909\t开始加载历史数据\n", - "2019-05-03 15:02:34.854177\t历史数据加载完成,数据量:175440\n", - "2019-05-03 15:02:34.877616\t策略初始化完成\n", - "2019-05-03 15:02:34.877616\t开始回放历史数据\n", - "2019-05-03 15:02:37.000744\t历史数据回放结束\n", - "2019-05-03 15:02:37.000744\t开始计算逐日盯市盈亏\n", - "2019-05-03 15:02:37.012463\t逐日盯市盈亏计算完成\n", - "2019-05-03 15:02:37.012463\t开始计算策略统计指标\n" - ] - }, - { - "data": { - "text/plain": [ - "(0.96, 0.38)" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "object_func(parameter_generate())" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -216,7 +150,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -283,15 +217,7 @@ "metadata": { "scrolled": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "开始运行遗传算法,每代族群总数:34, 优良品种筛选个数:27,迭代次数:30,交叉概率:0.95,突变概率:0.05\n" - ] - } - ], + "outputs": [], "source": [ "optimize()" ] diff --git a/tests/backtesting/run_ga.py b/tests/backtesting/run_ga.py new file mode 100644 index 00000000..4ce1c6b3 --- /dev/null +++ b/tests/backtesting/run_ga.py @@ -0,0 +1,27 @@ +from vnpy.app.cta_strategy.backtesting import BacktestingEngine, OptimizationSetting +from vnpy.app.cta_strategy.strategies.atr_rsi_strategy import ( + AtrRsiStrategy, +) +from datetime import datetime + +if __name__ == "__main__": + engine = BacktestingEngine() + engine.set_parameters( + vt_symbol="IF88.CFFEX", + interval="1m", + start=datetime(2019, 1, 1), + end=datetime(2019, 4, 30), + rate=0.3 / 10000, + slippage=0.2, + size=300, + pricetick=0.2, + capital=1_000_000, + ) + engine.add_strategy(AtrRsiStrategy, {}) + + setting = OptimizationSetting() + setting.set_target("sharpe_ratio") + setting.add_parameter("atr_length", 3, 39, 1) + setting.add_parameter("atr_ma_length", 10, 30, 1) + + engine.run_ga_optimization(setting) diff --git a/tests/backtesting/turtle.ipynb b/tests/backtesting/turtle.ipynb index fc872235..822614f8 100644 --- a/tests/backtesting/turtle.ipynb +++ b/tests/backtesting/turtle.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -16,7 +16,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -54,44 +54,38 @@ }, { "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2019-05-03 14:58:44.510371\t开始运行遗传算法,每代族群总数:20, 优良品种筛选个数:16,迭代次数:300,交叉概率:0.95,突变概率:0.05\n" - ] - }, - { - "ename": "AttributeError", - "evalue": "Can't pickle local object 'create_ga_optimize..ga_optimize'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0msetting\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0madd_parameter\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"atr_ma_length\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m80\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[0mengine\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrun_ga_optimization\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msetting\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;32mC:\\Github\\vnpy\\vnpy\\app\\cta_strategy\\backtesting.py\u001b[0m in \u001b[0;36mrun_ga_optimization\u001b[1;34m(self, optimization_setting, output)\u001b[0m\n\u001b[0;32m 601\u001b[0m \u001b[0mngen\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 602\u001b[0m \u001b[0mstats\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 603\u001b[1;33m \u001b[0mhalloffame\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mhof\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 604\u001b[0m ) \n\u001b[0;32m 605\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mc:\\miniconda3\\lib\\site-packages\\deap\\algorithms.py\u001b[0m in \u001b[0;36meaMuPlusLambda\u001b[1;34m(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, stats, halloffame, verbose)\u001b[0m\n\u001b[0;32m 301\u001b[0m \u001b[1;31m# Evaluate the individuals with an invalid fitness\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 302\u001b[0m \u001b[0minvalid_ind\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0mind\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mind\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mpopulation\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mind\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfitness\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalid\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 303\u001b[1;33m \u001b[0mfitnesses\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mtoolbox\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtoolbox\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mevaluate\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0minvalid_ind\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 304\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mind\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfit\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mzip\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minvalid_ind\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfitnesses\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 305\u001b[0m \u001b[0mind\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfitness\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalues\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mfit\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mc:\\miniconda3\\lib\\multiprocessing\\pool.py\u001b[0m in \u001b[0;36mmap\u001b[1;34m(self, func, iterable, chunksize)\u001b[0m\n\u001b[0;32m 288\u001b[0m \u001b[1;32min\u001b[0m \u001b[0ma\u001b[0m \u001b[0mlist\u001b[0m \u001b[0mthat\u001b[0m \u001b[1;32mis\u001b[0m \u001b[0mreturned\u001b[0m\u001b[1;33m.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 289\u001b[0m '''\n\u001b[1;32m--> 290\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_map_async\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfunc\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0miterable\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmapstar\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mchunksize\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 291\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 292\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mstarmap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0miterable\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mchunksize\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mc:\\miniconda3\\lib\\multiprocessing\\pool.py\u001b[0m in \u001b[0;36mget\u001b[1;34m(self, timeout)\u001b[0m\n\u001b[0;32m 681\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_value\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 682\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 683\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_value\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 684\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 685\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_set\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mi\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mobj\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mc:\\miniconda3\\lib\\multiprocessing\\pool.py\u001b[0m in \u001b[0;36m_handle_tasks\u001b[1;34m(taskqueue, put, outqueue, pool, cache)\u001b[0m\n\u001b[0;32m 455\u001b[0m \u001b[1;32mbreak\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 456\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 457\u001b[1;33m \u001b[0mput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtask\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 458\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 459\u001b[0m \u001b[0mjob\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0midx\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mtask\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mc:\\miniconda3\\lib\\multiprocessing\\connection.py\u001b[0m in \u001b[0;36msend\u001b[1;34m(self, obj)\u001b[0m\n\u001b[0;32m 204\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_check_closed\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 205\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_check_writable\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 206\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_send_bytes\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0m_ForkingPickler\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdumps\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 207\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 208\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mrecv_bytes\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmaxlength\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mc:\\miniconda3\\lib\\multiprocessing\\reduction.py\u001b[0m in \u001b[0;36mdumps\u001b[1;34m(cls, obj, protocol)\u001b[0m\n\u001b[0;32m 49\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mdumps\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcls\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mobj\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mprotocol\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 50\u001b[0m \u001b[0mbuf\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mio\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mBytesIO\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 51\u001b[1;33m \u001b[0mcls\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mbuf\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mprotocol\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdump\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 52\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mbuf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetbuffer\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 53\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mAttributeError\u001b[0m: Can't pickle local object 'create_ga_optimize..ga_optimize'" - ] - } - ], + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], "source": [ "setting = OptimizationSetting()\n", "setting.set_target(\"sharpe_ratio\")\n", - "setting.add_parameter(\"atr_length\", 3, 105, 1)\n", - "setting.add_parameter(\"atr_ma_length\", 10, 80, 1)\n", + "setting.add_parameter(\"atr_length\", 3, 39, 1)\n", + "setting.add_parameter(\"atr_ma_length\", 10, 30, 1)\n", "\n", "engine.run_ga_optimization(setting)" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "result = _" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(result)" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/vnpy/app/cta_strategy/backtesting.py b/vnpy/app/cta_strategy/backtesting.py index 004bdda5..bb670872 100644 --- a/vnpy/app/cta_strategy/backtesting.py +++ b/vnpy/app/cta_strategy/backtesting.py @@ -6,6 +6,7 @@ from functools import lru_cache from time import time import multiprocessing import random +import math import numpy as np import matplotlib.pyplot as plt @@ -29,6 +30,8 @@ from .base import ( from .template import CtaTemplate sns.set_style("whitegrid") +creator.create("FitnessMax", base.Fitness, weights=(1.0,)) +creator.create("Individual", list, fitness=creator.FitnessMax) class OptimizationSetting: @@ -537,44 +540,52 @@ class BacktestingEngine: return list(random.choice(settings).values()) # Create ga object function - object_func = create_ga_optimize( - target_name, - self.strategy_class, - settings[0], - self.vt_symbol, - self.interval, - self.start, - self.rate, - self.slippage, - self.size, - self.pricetick, - self.capital, - self.end, - self.mode - ) + global ga_target_name + global ga_strategy_class + global ga_setting + global ga_vt_symbol + global ga_interval + global ga_start + global ga_rate + global ga_slippage + global ga_size + global ga_pricetick + global ga_capital + global ga_end + global ga_mode + + ga_target_name = target_name + ga_strategy_class = self.strategy_class + ga_setting = settings[0] + ga_vt_symbol = self.vt_symbol + ga_interval = self.interval + ga_start = self.start + ga_rate = self.rate + ga_slippage = self.slippage + ga_size = self.size + ga_pricetick = self.pricetick + ga_capital = self.capital + ga_end = self.end + ga_mode = self.mode # Set up genetic algorithem - creator.create("FitnessMax", base.Fitness, weights=(1.0,)) - creator.create("Individual", list, fitness=creator.FitnessMax) - toolbox = base.Toolbox() toolbox.register("individual", tools.initIterate, creator.Individual, generate_parameter) toolbox.register("population", tools.initRepeat, list, toolbox.individual) toolbox.register("mate", tools.cxTwoPoint) toolbox.register("mutate", tools.mutUniformInt, low=4, up=40, indpb=1) - toolbox.register("evaluate", object_func) + toolbox.register("evaluate", ga_optimize) toolbox.register("select", tools.selNSGA2) - pool = multiprocessing.Pool(multiprocessing.cpu_count()) - toolbox.register("map", pool.map) - - mu = 16 # number of individuals to select for the next generation - lambda_ = 20 # number of children to produce at each generation - cxpb = 0.95 # probability that an offspring is produced by crossover - mutpb = 0.05 # probability that an offspring is produced by mutation - ngen = 300 # number of generation - - pop_size = 20 # number of individuals in each generation + total_size = len(settings) + pop_size = int(pow(total_size, 1 / math.e)) # number of individuals in each generation + lambda_ = pop_size # number of children to produce at each generation + mu = int(pop_size * 0.8) # number of individuals to select for the next generation + + cxpb = 0.95 # probability that an offspring is produced by crossover + mutpb = 1 - cxpb # probability that an offspring is produced by mutation + ngen = 30 # number of generation + pop = toolbox.population(pop_size) hof = tools.ParetoFront() # end result of pareto front @@ -584,11 +595,15 @@ class BacktestingEngine: stats.register("std", np.std, axis=0) stats.register("min", np.min, axis=0) stats.register("max", np.max, axis=0) - - msg = "开始运行遗传算法,每代族群总数:%s, 优良品种筛选个数:%s,迭代次数:%s,交叉概率:%s,突变概率:%s" %(pop_size, mu, ngen, cxpb, mutpb) - self.output(msg) + + # Multiprocessing is not supported yet. + # pool = multiprocessing.Pool(multiprocessing.cpu_count()) + # toolbox.register("map", pool.map) # Run ga optimization + msg = "开始运行遗传算法,每代族群总数:%s, 优良品种筛选个数:%s,迭代次数:%s,交叉概率:%s,突变概率:%s" % (pop_size, mu, ngen, cxpb, mutpb) + self.output(msg) + start = time() algorithms.eaMuPlusLambda( @@ -607,9 +622,17 @@ class BacktestingEngine: cost = int((end - start)) self.output(f"遗传算法优化完成,耗时{cost}秒") - self.output("输出帕累托前沿解集:") - return hof + # Return result list + results = [] + parameter_keys = list(ga_setting.keys()) + + for parameter_values in hof: + setting = dict(zip(parameter_keys, parameter_values)) + target_value = ga_optimize(parameter_values)[0] + results.append((setting, target_value)) + + return results def update_daily_close(self, price: float): """""" @@ -1065,52 +1088,33 @@ def optimize( return (str(setting), target_value, statistics) -def create_ga_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 - """ - parameter_keys = list(setting.keys()) +@lru_cache(maxsize=1000000) +def _ga_optimizae(parameter_values: tuple): + """""" + parameter_keys = list(ga_setting.keys()) + setting = dict(zip(parameter_keys, parameter_values)) - @lru_cache(maxsize=1000000) - def _optimizae(parameter_values: tuple): - """""" - setting = dict(zip(parameter_keys, parameter_values)) - result = optimize( - target_name, - strategy_class, - setting, - vt_symbol, - interval, - start, - rate, - slippage, - size, - pricetick, - capital, - end, - mode - ) - return (result[1],) + result = optimize( + ga_target_name, + ga_strategy_class, + setting, + ga_vt_symbol, + ga_interval, + ga_start, + ga_rate, + ga_slippage, + ga_size, + ga_pricetick, + ga_capital, + ga_end, + ga_mode + ) + return (result[1],) - def ga_optimize(parameter_values: list): - """""" - return _optimizae(tuple(parameter_values)) - return ga_optimize +def ga_optimize(parameter_values: list): + """""" + return _ga_optimizae(tuple(parameter_values)) @lru_cache(maxsize=10) @@ -1141,6 +1145,8 @@ def load_tick_data( # GA related global value +ga_end = None +ga_mode = None ga_target_name = None ga_strategy_class = None ga_setting = None @@ -1151,6 +1157,4 @@ ga_rate = None ga_slippage = None ga_size = None ga_pricetick = None -ga_capital = None -ga_end = None -ga_mode = None \ No newline at end of file +ga_capital = None \ No newline at end of file