Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sin32775/dae07dc8c588457907f45bf771eb5ca4 to your computer and use it in GitHub Desktop.
Save sin32775/dae07dc8c588457907f45bf771eb5ca4 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 準備"
]
},
{
"cell_type": "code",
"execution_count": 93,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import indicators as ind #indicators.pyのインポート\n",
"from backtest import Backtest,BacktestReport\n",
"dataM1 = pd.read_csv('DAT_ASCII_GBPUSD_M1_201705.csv', sep=';',\n",
" names=('Time','Open','High','Low','Close', ''),\n",
" index_col='Time', parse_dates=True)\n",
"dataM1.index += pd.offsets.Hour(7) #7時間のオフセット\n",
"ohlc = ind.TF_ohlc(dataM1, 'H') #1時間足データの作成"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 最適化するトレードシステム\n",
"今回は最適化するパラメータの値の組み合わせを増やすために、2本の移動平均の交差システムに決済用のシグナルを追加。決済用のシグナルは、以下のように定義。\n",
"\n",
" 買いポジションの決済:終値が決済用移動平均を下抜けたとき\n",
" 売りポジションの決済:終値が決済用移動平均を上抜けたとき\n",
" \n",
" \n",
"このシステムでは、パラメータは3個。今回はそれぞれのパラメータを以下のような範囲で探索することにします。"
]
},
{
"cell_type": "code",
"execution_count": 94,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"SlowMAperiod = np.arange(7, 151) #長期移動平均期間の範囲\n",
"FastMAperiod = np.arange(5, 131) #短期移動平均期間の範囲\n",
"ExitMAperiod = np.arange(3, 111) #決済用移動平均期間の範囲"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# メインルーチン\n",
"遺伝的アルゴリズムのメインルーチンは、前回のランダムサーチとほぼ同じです。\n",
"\n",
"パラメータをランダムに探すところを、後述の遺伝的処理に置き換えるだけです。\n",
"\n",
"また売買シグナルは上記のルールのように決済用のシグナルを追加しています。\n",
"\n",
"もう一つ、前回からの変更点は、SlowMAperiod, FastMAperiod, ExitMAperiodの三つのパラメータの範囲をPrangeというリストにまとめて各関数に渡すようにした点です。\n",
"\n",
"こうすることで、パラメータの数が増えてもそのまま対応することができます。"
]
},
{
"cell_type": "code",
"execution_count": 95,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def Optimize(ohlc, Prange):\n",
" def shift(x, n=1): return np.concatenate((np.zeros(n), x[:-n])) #シフト関数\n",
"\n",
" SlowMA = np.empty([len(Prange[0]), len(ohlc)]) #長期移動平均\n",
" for i in range(len(Prange[0])):\n",
" SlowMA[i] = ind.iMA(ohlc, Prange[0][i])\n",
"\n",
" FastMA = np.empty([len(Prange[1]), len(ohlc)]) #短期移動平均\n",
" for i in range(len(Prange[1])):\n",
" FastMA[i] = ind.iMA(ohlc, Prange[1][i])\n",
"\n",
" ExitMA = np.empty([len(Prange[2]), len(ohlc)]) #決済用移動平均\n",
" for i in range(len(Prange[2])):\n",
" ExitMA[i] = ind.iMA(ohlc, Prange[2][i])\n",
"\n",
" Close = ohlc['Close'].values #終値\n",
"\n",
" M = 20 #個体数\n",
" Eval = np.zeros([M, 6]) #評価項目\n",
" Param = InitParam(Prange, M) #パラメータ初期化\n",
" gens = 0 #世代数\n",
" while gens < 100:\n",
" for k in range(M):\n",
" i0 = Param[k,0]\n",
" i1 = Param[k,1]\n",
" i2 = Param[k,2]\n",
" #買いエントリーシグナル\n",
" BuyEntry = (FastMA[i1] > SlowMA[i0]) & (shift(FastMA[i1]) <= shift(SlowMA[i0]))\n",
" #売りエントリーシグナル\n",
" SellEntry = (FastMA[i1] < SlowMA[i0]) & (shift(FastMA[i1]) >= shift(SlowMA[i0]))\n",
" #買いエグジットシグナル\n",
" BuyExit = (Close < ExitMA[i2]) & (shift(Close) >= shift(ExitMA[i2]))\n",
" #売りエグジットシグナル\n",
" SellExit = (Close > ExitMA[i2]) & (shift(Close) <= shift(ExitMA[i2]))\n",
" #バックテスト\n",
" Trade, PL = Backtest(ohlc, BuyEntry, SellEntry, BuyExit, SellExit) \n",
" Eval[k] = BacktestReport(Trade, PL)\n",
" # 世代の交代\n",
" Param = Evolution(Param, Eval[:,0], Prange)\n",
" gens += 1\n",
" print(gens, Eval[0,0])\n",
" Slow = Prange[0][Param[:,0]]\n",
" Fast = Prange[1][Param[:,1]]\n",
" Exit = Prange[2][Param[:,2]]\n",
" return pd.DataFrame({'Slow':Slow, 'Fast':Fast, 'Exit':Exit, 'Profit': Eval[:,0], 'Trades':Eval[:,1],\n",
" 'Average':Eval[:,2],'PF':Eval[:,3], 'MDD':Eval[:,4], 'RF':Eval[:,5]},\n",
" columns=['Slow','Fast','Exit','Profit','Trades','Average','PF','MDD','RF'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 遺伝的処理\n",
"\n",
"上の関数で、GA用に追加した関数は、InitParam()とEvolution()です。まず、InitParam()は、各個体のパラメータの初期化です。"
]
},
{
"cell_type": "code",
"execution_count": 96,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from numpy.random import randint,choice\n",
"\n",
"#パラメータ初期化\n",
"def InitParam(Prange, M):\n",
" Param = randint(len(Prange[0]), size=M)\n",
" for i in range(1,len(Prange)):\n",
" Param = np.vstack((Param, randint(len(Prange[i]), size=M)))\n",
" return Param.T"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Evolution()は、次のようにいくつかの遺伝的処理を含みます。"
]
},
{
"cell_type": "code",
"execution_count": 97,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"#遺伝的処理\n",
"def Evolution(Param, Eval, Prange):\n",
" #エリート保存付きルーレット選択\n",
" Param = Param[np.argsort(Eval)[::-1]] #ソート\n",
" R = Eval-min(Eval)\n",
" R = R/sum(R)\n",
" idx = choice(len(Eval), size=len(Eval), replace=True, p=R)\n",
" idx[0] = 0 #エリート保存\n",
" Param = Param[idx]\n",
" \n",
" #1点交叉\n",
"def Evolution(Param, Eval, Prange):\n",
" N = 10\n",
" idx = choice(np.arange(1,len(Param)), size=N, replace=False)\n",
" for i in range(0,N,2):\n",
" ix = idx[i:i+2]\n",
" p = randint(1,len(Prange))\n",
" Param[ix] = np.hstack((Param[ix][:,:p], Param[ix][:,p:][::-1]))\n",
" #近傍生成\n",
"def Evolution(Param, Eval, Prange):\n",
" N = 10\n",
" idx = choice(np.arange(1,len(Param)), size=N, replace=False)\n",
" diff = choice([-1,1], size=N).reshape(N,1)\n",
" for i in range(N):\n",
" p = randint(len(Prange))\n",
" Param[idx[i]][p:p+1] = (Param[idx[i]][p]+diff[i]+len(Prange[p]))%len(Prange[p])\n",
" #突然変異 \n",
"def Evolution(Param, Eval, Prange): \n",
" N = 2\n",
" idx = choice(np.arange(1,len(Param)), size=N, replace=False)\n",
" for i in range(N):\n",
" p = randint(len(Prange))\n",
" Param[idx[i]][p:p+1] = randint(len(Prange[p]))\n",
" return Param"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"それぞれの処理について説明します。\n",
"## エリート保存付きルーレット選択\n",
"\n",
"現在の個体の中から次世代に残す個体を選択します。\n",
"\n",
"選択の方法はいくつかあるのですが、Numpyの関数でルーレット選択に便利な関数があったので、それを使ってみます。\n",
"\n",
"ルーレット選択はバックテストの評価値である適応度の大きさに応じて、確率的に次世代に残す個体を選択する方法です。\n",
"\n",
"適応度が高いほど残りやすくなります。\n",
"\n",
"今回使った関数は、numpy.random.choice()という関数で、リストから必要な個数分ランダムに選択するものですが、オプションの引数にpという選択確率のリストを付けると、その確率に合わせて選択してくれます。\n",
"\n",
"これはルーレット選択そのものです。次のようなコードになります。"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def Evolution(Param, Eval, Prange):\n",
" #エリート保存付きルーレット選択\n",
" Param = Param[np.argsort(Eval)[::-1]] #ソート\n",
" R = Eval-min(Eval)\n",
" R = R/sum(R)\n",
" idx = choice(len(Eval), size=len(Eval), replace=True, p=R)\n",
" idx[0] = 0 #エリート保存\n",
" Param = Param[idx]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ただ、確率がマイナスだと都合が悪いので、適応度の最小値が0になるように補正してあります。\n",
"\n",
"またルーレット選択だけだと、適応度が高くても運悪く選ばれないこともあるので、適応度をソートして最も高い個体(エリート)は必ず次世代に残るようにしています。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1点交叉\n",
"次に遺伝子の交叉を行います。これは、二つの個体を選んで、遺伝子情報の一部を互いに交換することです。\n",
"\n",
"交叉の方法もいくつかありますが、ここではパラメータの並びの1か所を選んで、その前後を交換する方法にしました。\n"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
" def Evolution(Param, Eval, Prange):\n",
" N = 10\n",
" idx = choice(np.arange(1,len(Param)), size=N, replace=False)\n",
" for i in range(0,N,2):\n",
" ix = idx[i:i+2]\n",
" p = randint(1,len(Prange))\n",
" Param[ix] = np.hstack((Param[ix][:,:p], Param[ix][:,p:][::-1]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ここでもchoice()を使って交叉する個体の個数分の乱数列を生成します。replace=Falseを付けることで、重複のない乱数列が得られます。\n",
"\n",
"そして、2個ずつの個体をixとして選択して、交叉点pの後半のデータを入れ換えることで交叉を実現しています。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 近傍生成\n",
"\n",
"通常のGAでは、選択、交叉、突然変異で進化のシミュレーションを行うのですが、今回のように交叉点をパラメータの切れ目のところに限定していると、いつの間にか同じ個体だらけになってしまい、進化が止まってしまいます。\n",
"\n",
"かといって、突然変異を多くすると、ランダムサーチに近くなってしまうので、あまり効率がよくありません。\n",
"\n",
"そこで、今回は、パラメータの一部を+1、あるいは-1する変化を施します。\n",
"\n",
"いわゆる近傍解というやつで、局所探索アルゴリズムでよく利用されるものです。"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def Evolution(Param, Eval, Prange):\n",
" N = 10\n",
" idx = choice(np.arange(1,len(Param)), size=N, replace=False)\n",
" diff = choice([-1,1], size=N).reshape(N,1)\n",
" for i in range(N):\n",
" p = randint(len(Prange))\n",
" Param[idx[i]][p:p+1] = (Param[idx[i]][p]+diff[i]+len(Prange[p]))%len(Prange[p])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"交叉と同じく近傍を生成する個体を選択します。\n",
"\n",
"そして、どのパラメータを変化させるかをまた乱数で決めて、そのパラメータを1だけ変化させます。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 突然変異\n",
"\n",
"最後に突然変異を実行します。\n",
"\n",
"これもいくつかの方法がありますが、選択した個体のパラメータの一部を新しく乱数で書き換えます。\n",
"\n",
"GAの場合、局所解から抜け出すには、突然変異が重要なのですが、これを多用するとランダム性が高くなってしまうので、ここでは、2個程度にしておきます。"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
" def Evolution(Param, Eval, Prange): \n",
" N = 2\n",
" idx = choice(np.arange(1,len(Param)), size=N, replace=False)\n",
" for i in range(N):\n",
" p = randint(len(Prange))\n",
" Param[idx[i]][p:p+1] = randint(len(Prange[p]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 実行結果\n",
"\n",
"以上のように定義した関数を使って遺伝的アルゴリズムを実行してみます。"
]
},
{
"cell_type": "code",
"execution_count": 98,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 15.2\n",
"2 15.2\n",
"3 15.2\n",
"4 15.2\n",
"5 15.2\n",
"6 15.2\n",
"7 15.2\n",
"8 15.2\n",
"9 15.2\n",
"10 15.2\n",
"11 15.2\n",
"12 15.2\n",
"13 15.2\n",
"14 15.2\n",
"15 15.2\n",
"16 15.2\n",
"17 15.2\n",
"18 15.2\n",
"19 15.2\n",
"20 15.2\n",
"21 15.2\n",
"22 15.2\n",
"23 15.2\n",
"24 15.2\n",
"25 15.2\n",
"26 15.2\n",
"27 15.2\n",
"28 15.2\n",
"29 15.2\n",
"30 15.2\n",
"31 15.2\n",
"32 15.2\n",
"33 15.2\n",
"34 15.2\n",
"35 15.2\n",
"36 15.2\n",
"37 15.2\n",
"38 15.2\n",
"39 15.2\n",
"40 15.2\n",
"41 15.2\n",
"42 15.2\n",
"43 15.2\n",
"44 15.2\n",
"45 15.2\n",
"46 15.2\n",
"47 15.2\n",
"48 15.2\n",
"49 15.2\n",
"50 15.2\n",
"51 15.2\n",
"52 15.2\n",
"53 15.2\n",
"54 15.2\n",
"55 15.2\n",
"56 15.2\n",
"57 15.2\n",
"58 15.2\n",
"59 15.2\n",
"60 15.2\n",
"61 15.2\n",
"62 15.2\n",
"63 15.2\n",
"64 15.2\n",
"65 15.2\n",
"66 15.2\n",
"67 15.2\n",
"68 15.2\n",
"69 15.2\n",
"70 15.2\n",
"71 15.2\n",
"72 15.2\n",
"73 15.2\n",
"74 15.2\n",
"75 15.2\n",
"76 15.2\n",
"77 15.2\n",
"78 15.2\n",
"79 15.2\n",
"80 15.2\n",
"81 15.2\n",
"82 15.2\n",
"83 15.2\n",
"84 15.2\n",
"85 15.2\n",
"86 15.2\n",
"87 15.2\n",
"88 15.2\n",
"89 15.2\n",
"90 15.2\n",
"91 15.2\n",
"92 15.2\n",
"93 15.2\n",
"94 15.2\n",
"95 15.2\n",
"96 15.2\n",
"97 15.2\n",
"98 15.2\n",
"99 15.2\n",
"100 15.2\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Slow</th>\n",
" <th>Fast</th>\n",
" <th>Exit</th>\n",
" <th>Profit</th>\n",
" <th>Trades</th>\n",
" <th>Average</th>\n",
" <th>PF</th>\n",
" <th>MDD</th>\n",
" <th>RF</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>97</td>\n",
" <td>85</td>\n",
" <td>35</td>\n",
" <td>127.7</td>\n",
" <td>8.0</td>\n",
" <td>15.962500</td>\n",
" <td>2.908819</td>\n",
" <td>36.8</td>\n",
" <td>3.470109</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>135</td>\n",
" <td>18</td>\n",
" <td>24</td>\n",
" <td>56.7</td>\n",
" <td>3.0</td>\n",
" <td>18.900000</td>\n",
" <td>13.600000</td>\n",
" <td>4.5</td>\n",
" <td>12.600000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>10</td>\n",
" <td>70</td>\n",
" <td>74</td>\n",
" <td>35.8</td>\n",
" <td>13.0</td>\n",
" <td>2.753846</td>\n",
" <td>1.140282</td>\n",
" <td>115.7</td>\n",
" <td>0.309421</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>55</td>\n",
" <td>128</td>\n",
" <td>108</td>\n",
" <td>21.6</td>\n",
" <td>3.0</td>\n",
" <td>7.200000</td>\n",
" <td>1.301676</td>\n",
" <td>71.6</td>\n",
" <td>0.301676</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>95</td>\n",
" <td>84</td>\n",
" <td>103</td>\n",
" <td>18.2</td>\n",
" <td>7.0</td>\n",
" <td>2.600000</td>\n",
" <td>1.298851</td>\n",
" <td>48.6</td>\n",
" <td>0.374486</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>56</td>\n",
" <td>130</td>\n",
" <td>6</td>\n",
" <td>15.2</td>\n",
" <td>3.0</td>\n",
" <td>5.066667</td>\n",
" <td>1.340045</td>\n",
" <td>44.7</td>\n",
" <td>0.340045</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>41</td>\n",
" <td>41</td>\n",
" <td>21</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>94</td>\n",
" <td>85</td>\n",
" <td>90</td>\n",
" <td>-38.6</td>\n",
" <td>7.0</td>\n",
" <td>-5.514286</td>\n",
" <td>0.419549</td>\n",
" <td>59.2</td>\n",
" <td>-0.652027</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>27</td>\n",
" <td>91</td>\n",
" <td>67</td>\n",
" <td>-41.2</td>\n",
" <td>7.0</td>\n",
" <td>-5.885714</td>\n",
" <td>0.516999</td>\n",
" <td>55.9</td>\n",
" <td>-0.737030</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>36</td>\n",
" <td>11</td>\n",
" <td>86</td>\n",
" <td>-50.7</td>\n",
" <td>15.0</td>\n",
" <td>-3.380000</td>\n",
" <td>0.812639</td>\n",
" <td>231.0</td>\n",
" <td>-0.219481</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>20</td>\n",
" <td>57</td>\n",
" <td>7</td>\n",
" <td>-59.7</td>\n",
" <td>14.0</td>\n",
" <td>-4.264286</td>\n",
" <td>0.738273</td>\n",
" <td>175.4</td>\n",
" <td>-0.340365</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>13</td>\n",
" <td>91</td>\n",
" <td>93</td>\n",
" <td>-64.1</td>\n",
" <td>8.0</td>\n",
" <td>-8.012500</td>\n",
" <td>0.236905</td>\n",
" <td>75.5</td>\n",
" <td>-0.849007</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>60</td>\n",
" <td>92</td>\n",
" <td>20</td>\n",
" <td>-64.1</td>\n",
" <td>6.0</td>\n",
" <td>-10.683333</td>\n",
" <td>0.461797</td>\n",
" <td>119.1</td>\n",
" <td>-0.538203</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>142</td>\n",
" <td>20</td>\n",
" <td>36</td>\n",
" <td>-68.8</td>\n",
" <td>3.0</td>\n",
" <td>-22.933333</td>\n",
" <td>0.000000</td>\n",
" <td>68.8</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>40</td>\n",
" <td>16</td>\n",
" <td>88</td>\n",
" <td>-76.9</td>\n",
" <td>12.0</td>\n",
" <td>-6.408333</td>\n",
" <td>0.670946</td>\n",
" <td>201.3</td>\n",
" <td>-0.382017</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>55</td>\n",
" <td>21</td>\n",
" <td>85</td>\n",
" <td>-79.4</td>\n",
" <td>10.0</td>\n",
" <td>-7.940000</td>\n",
" <td>0.653880</td>\n",
" <td>131.9</td>\n",
" <td>-0.601971</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>134</td>\n",
" <td>69</td>\n",
" <td>69</td>\n",
" <td>-95.5</td>\n",
" <td>3.0</td>\n",
" <td>-31.833333</td>\n",
" <td>0.000000</td>\n",
" <td>95.5</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>123</td>\n",
" <td>56</td>\n",
" <td>66</td>\n",
" <td>-96.3</td>\n",
" <td>3.0</td>\n",
" <td>-32.100000</td>\n",
" <td>0.000000</td>\n",
" <td>96.3</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>28</td>\n",
" <td>115</td>\n",
" <td>43</td>\n",
" <td>-102.8</td>\n",
" <td>3.0</td>\n",
" <td>-34.266667</td>\n",
" <td>0.000000</td>\n",
" <td>102.8</td>\n",
" <td>-1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>62</td>\n",
" <td>61</td>\n",
" <td>62</td>\n",
" <td>-172.5</td>\n",
" <td>21.0</td>\n",
" <td>-8.214286</td>\n",
" <td>0.580700</td>\n",
" <td>237.9</td>\n",
" <td>-0.725095</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Slow Fast Exit Profit Trades Average PF MDD RF\n",
"4 97 85 35 127.7 8.0 15.962500 2.908819 36.8 3.470109\n",
"10 135 18 24 56.7 3.0 18.900000 13.600000 4.5 12.600000\n",
"12 10 70 74 35.8 13.0 2.753846 1.140282 115.7 0.309421\n",
"9 55 128 108 21.6 3.0 7.200000 1.301676 71.6 0.301676\n",
"11 95 84 103 18.2 7.0 2.600000 1.298851 48.6 0.374486\n",
"0 56 130 6 15.2 3.0 5.066667 1.340045 44.7 0.340045\n",
"7 41 41 21 0.0 0.0 0.000000 0.000000 0.0 0.000000\n",
"19 94 85 90 -38.6 7.0 -5.514286 0.419549 59.2 -0.652027\n",
"3 27 91 67 -41.2 7.0 -5.885714 0.516999 55.9 -0.737030\n",
"8 36 11 86 -50.7 15.0 -3.380000 0.812639 231.0 -0.219481\n",
"14 20 57 7 -59.7 14.0 -4.264286 0.738273 175.4 -0.340365\n",
"18 13 91 93 -64.1 8.0 -8.012500 0.236905 75.5 -0.849007\n",
"5 60 92 20 -64.1 6.0 -10.683333 0.461797 119.1 -0.538203\n",
"2 142 20 36 -68.8 3.0 -22.933333 0.000000 68.8 -1.000000\n",
"17 40 16 88 -76.9 12.0 -6.408333 0.670946 201.3 -0.382017\n",
"15 55 21 85 -79.4 10.0 -7.940000 0.653880 131.9 -0.601971\n",
"13 134 69 69 -95.5 3.0 -31.833333 0.000000 95.5 -1.000000\n",
"6 123 56 66 -96.3 3.0 -32.100000 0.000000 96.3 -1.000000\n",
"16 28 115 43 -102.8 3.0 -34.266667 0.000000 102.8 -1.000000\n",
"1 62 61 62 -172.5 21.0 -8.214286 0.580700 237.9 -0.725095"
]
},
"execution_count": 98,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"result = Optimize(ohlc, [SlowMAperiod, FastMAperiod, ExitMAperiod])\n",
"result.sort_values('Profit', ascending=False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"GAも乱数を使っているので、結果は毎回異なります。\n",
"\n",
"以下は結果の一例で、世代毎に最も高い適応度を示したものです。\n",
"\n",
"エリート保存しているので、高い適応度は順次更新されます。\n",
"\n",
"この問題の最適解は調べていないのでわかりませんが、この結果は、まあまあ高い値だと思います。\n",
"\n",
"そもそもGAの目的は、最適解を求めることではなく、総当たりするより短い時間で準最適解を求めることです。\n",
"\n",
"実際、シストレのパラメータで最適解を求めたところで、そのシステムが別の期間でも同じ結果を出すわけではありません。\n",
"\n",
"そういうことなので、200万通りの組み合わせの中から2000回の試行でまあまあの解が得られたのであれば、よしとするべきでしょうね。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Python [Root]",
"language": "python",
"name": "Python [Root]"
},
"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.5.1"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
"autocomplete": true,
"bibliofile": "biblio.bib",
"cite_by": "apalike",
"current_citInitial": 1,
"eqLabelWithNumbers": true,
"eqNumInitial": 1,
"hotkeys": {
"equation": "Ctrl-E",
"itemize": "Ctrl-I"
},
"labels_anchors": false,
"latex_user_defs": false,
"report_style_numbering": false,
"user_envs_cfg": false
},
"toc": {
"colors": {
"hover_highlight": "#DAA520",
"navigate_num": "#000000",
"navigate_text": "#333333",
"running_highlight": "#FF0000",
"selected_highlight": "#FFD700",
"sidebar_border": "#EEEEEE",
"wrapper_background": "#FFFFFF"
},
"moveMenuLeft": true,
"nav_menu": {
"height": "194px",
"width": "252px"
},
"navigate_menu": true,
"number_sections": true,
"sideBar": true,
"threshold": 4,
"toc_cell": false,
"toc_section_display": "block",
"toc_window_display": false,
"widenNotebook": false
}
},
"nbformat": 4,
"nbformat_minor": 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment