2014/06/15

具体的な最適化手法(2) 堅牢なパラメータ値の選択



さて前回は、パラメータ値の最適化やシステム評価(≒パフォーマンス評価)の具体的な計算方法について書きました。  今回は、パラメータ値の最適化で、その評価値を元に、堅牢なパラメータ値を機械的に選ぶ工夫について書いてみたいと思います。

やりたい事自体は、色んなシストレの本で書いてある事と同じなのですが、今回記事の特徴は、機械的に計算するための工夫、といったところです。  前回記事の様に、「これだ!」とスッキリしている訳ではなく、もっと良い方法があるんじゃないか、とも思いながら、最近思いついた最善策、といったところでしょうか。  今はこの方法で、定期的な最適化をしています。


1.やりたい事


最適化の目的関数(年率オプティマルfレシオなど)評価値が最大になる、パラメータ値の組み合わせを見つけたい、という事です。 ただ、単純に評価値が最大になる組み合わせを選ぶのではなく、「堅牢」なパラメータ値の組み合わせを「機械的」に求めたいわけです。

たとえば、単一パラメータ変数と評価値の関係が、以下の様なグラフであった場合、高い値の方がいいのはいいのですが、多少パラメータ値を変更しても、評価値への影響が少ない方の値を選びたいわけです。



もちろん、パラメータの値そのものに意味があって、それを狙った戦略なのであれば、最適化などせず、そのパラメータ値固定でトレードするのがいいと思います。


2.サンプル・データ


これから使う、説明用のサンプル・データの説明です。 パラメータがAとBの2種類あり、パラメータ値の組み合わせと、評価値(年率オプティマルfレシオ)の関係が、以下の表の通りだったとします。 
















図1.サンプルデータ1


色が付いているマス目の値は、評価値で、値が大きい順に、「緑→黄色→赤」という風に色分けされています。 (エクセルで、表を選択状態にして、「条件付き書式」→「カラースケール」で簡単にできます)

この中では、評価値が最大になるのは、パラメータA=12、B=120の評価値174ですが、赤丸がついている、A=22、B=240を、機械的に選びたい、という事です。(多少パラメータ値が前後しても、高い評価値を維持できるので)

ちなみに、わざとパラメータA=12の列、パラメータB=120の行も高い値になる様なデータにしています。


3.選択手順


人が目で見て選ぶ、というやり方も当然ありますし、機械的に選んだら、何か特別なものが選ばれる、という訳でもありません。

ただ、機械的に選べたほうが、曖昧さが無いですし、プログラミングが可能になるので、自動化ができるのが良い、という事です。

具体的な手順は以下の通りです。

手順1.パラメータ毎に、評価値の中央値をとる
例えば、パラメータA=22の列について中央値をとる場合は、パラメータA=22における、パラメータBが100~280の評価値の、中央値をとります。
手順2.パラメータ毎の中央値を、前後のパラメータ値で平均する
例えば、パラメータA=22の中央値は153ですが、前後のパラメータ値については、A=20の場合は150、A=24だと150になり、それら3つの値の平均します。 具体的には、A=22における、平均値は(153+150+150)÷3=151 です。
手順3.「手順2」で求めた平均値が最大のパラメータ値を選ぶ
この場合、パラメータAの各値について実際にやってみると、以下の様になり、パラメータA=22が選ばれます。


図2.パラメータA集計結果


「中央値」だとA=12が最大だったのが、前後の平均値をとる事で、A=22という、期待したとおりのパラメータ値を選ぶ事ができました。

手順4.他のパラメータ変数も同様。 選ばれた値の組み合わせが「最適化結果」
全てのパラメータ変数(この場合はB)にたいして、前述「手順1」~「手順3」を計算し、パラメータ変数毎の最適なパラメータ値を選ぶ。  選ばれたパラメータ値の組み合わせが、機械的に選んだ最適化結果のパラメータ・セットです。
パラメータBについて同様にすると、以下の様になり、B=240が選ばれます。


従って、パラメータA=22、B=240が最適化結果になり、当初選びたかったパラメータ値が選ばれました。
説明しやすい様に、ある程度作為的にデータを作成した事もあって、期待通りの結果になりましたが、単純に最大値を選んだ時との違いを、イメージできましたでしょうか?


 4.簡単な実験


ここまでは、わりと滑らかなサンプル・データを使ってきました。 実際にはノイズも加わると思うので、このサンプル・データの「評価値」に、ノイズを加えたらどうなるか、実験してみました。
■ ノイズの加え方
全評価値に、-2σ~+2σの乱数の値を足します。 擬似的な外れ値として、評価値が最大となっているA=12、B=120の値を、「固定:平均+4σ」と「固定:2倍」にした2パターンで実施しました。
10パターンのノイズを生成し、期待したパラメータ値の組み合わせ(A=12、B=240)周囲1マス以内が選ばれれば、成功とみなしました。  
(つまり、A=20~24かつ、B=220~240であれば成功)

ついでに、4パターンのパラメータ値の選択方法も比較してみました。 表内の数値は、前述の基準で「成功」と判断されたパターン数です。 つまり10パターンのうち、どの程度成功したか、という表です。

以下「④中央値 前後平均」が今回紹介した方法です。




今回の手法だと、ノイズを加えても、ある程度成功している事がわかります。  「②平均 前後平均」も割りといい感じですが、やはり極大な外れ値には弱い、という事かもしれません。 また、「前後平均」は、「平均値」と「中央値」の両方で、効果があった様に見えます。


 5.考察


今回、実験につかったサンプル・データは1種類だけとはいい、まぁ、いい結果じゃないかな、と思います。 すでにこの手法での最適化を行って運用開始していますが、この記事でやった検証はしていなくて、今回初めてでです(笑)

今回の手順のミソは、パラメータ変数毎の集計、「中央値」で集計、前後の値を平均してから評価、の3点です。 前後の値を平均してから評価する手法は、「アルゴリズムトレーディング入門」で紹介されていました。

補足ですが、「平均値」よりも「中央値」を使う事で、外れ値の影響を抑えることができる様です。 これは10個の乱数の値を使って100回中95回、「中央値」を使った方が「平均値」を使った時よりも良い結果になりました。

具体的には、10個の乱数に「平均+3σ」のデータ1つを追加した時、それぞれの値の影響が小さく済んだ、という事で確認しました。   実際、前述「4.簡単な実験」でも、「平均値」を使うよりも「中央値」を使った方が良い結果になっています。


6.さいごに


ここまで3回の記事にわたって、パラメータ値の最適化について書いてきました。 今まで悶々としていた最適化ですが、割と自分的にはスッキリしました。  最大化したい事と配慮したい事を分けて考える事で、スッキリしたのだと思います。

もちろん今後、もっといい方法が見つかると嬉しいですけどね♪ そんな事も期待して、最近「機械学習」の本を読み始めました(笑)

あと、手前味噌ですが、今回の一連の最適化を行う無料ソフトを公開しています。是非、ダウンロードしてみてください。 ご意見いただければ、幸いです。

■ 無料ソフトウェア・ダウンロード → Test Analyzer

このソフトは、「T2OFレシオ(≒年率オプティマルfレシオ)」を目的関数として、今回のパラメータ値選択方法で最適化する、MT4用の無料ソフトです。



ではでは~


【 P.S. 】 ブログ「FXシステムトレード奮闘記」の「過去記事 一覧」を作成しました♪



2014/06/12

具体的な最適化手法(1) 目的関数



(2014/6/25 19:20 計算式修正)
さて前回は、システム評価・最適化をマネージメントに絡めて考察しました。  今回はその考察結果を元に、最適化やシステム評価(≒パフォーマンス評価)の具体的な手法について書いてみます。



1.おさらい


前回、資産の最大化を目指す「目的関数(≒パフォーマンス評価方法)」として、「オプティマルfにおける幾何平均」がよい、と考えましたが、付随して配慮すべき点もありましたので、どういったシステムを良い、と考えるのかを、一旦整理します。


  ■ 目的関数の特性

  1. オプティマルfにおける幾何平均が高いほどよい
  2. 同じ「オプティマルfにおける幾何平均」であれば、オプティマルfは低いほどよい
  3. オプティマルfにおける幾何平均」÷オプティマルfが同じでも、「オプティマルfにおける幾何平均」が高いほどよい
「オプティマルf」については、過去ブログ記事の「ロット数を決める方法(資金管理)について」を参照ください。 この記事での、複利運用で資産を最大化するリスク量(初期リスク%)が、「オプティマルf」です。 (リスク量が一定以上大きくなると、リターンが減少していきます)



2.目的関数の計算式


評価値(年率オプティマルfレシオ) =
 平方根[ { (オプティマルfにおける複利年率+100%)^2-1 } ÷ オプティマルf ]   (式1)
(2014/6/25 計算式修正)

ずばり、これがいいのではないか、と思っています。  例えば、オプティマルfが初期リスク10%で、その時の複利年率が+30%であった場合は、以下の様に計算されます。


   評価値 = 平方根[ {(30%+100%)^2-1} ÷ 10% ]
         = 平方根[ { (0.3+1)^2-1 } ÷ 0.1 ]
         = 平方根[ (1.3^2-1) ÷ 0.1 ] (2014/9/27 修正)
         = 平方根(0.69÷0.1) (2014/9/27 修正)
         = 2.6268 (2014/9/27 修正)


便宜上、この目的関数(パフォーマンス評価指標)を命名したいので、「年率オプティマルfレシオ」(略してAROFレシオ:Annual rate at Optimal-f Ratio、あろっふれしお?
という名前にしてみました(笑)    

最適化の為だけの評価であれば、同一期間のパフォーマンスを比較できればよいので、以下の計算式でも問題ないと思います。 自分が最近見直した最適化作業では、簡便的にこの式を使っています。
#むしろ、下記(式2)が先に思いついて、ブログを書きながら、前述の(式1)に変形させた、といった流れです(笑)


   評価値(T2OFレシオ) = (最終資産倍率^2-1) ÷ オプティマルf   (式2)
   (2014/6/25 計算式修正)

さきほどと同じ条件で、かつ、検証結果が3年分の評価結果だとすると、評価値は以下の様になります。

   評価値 = {( 1.3倍/年^3年 )^2 -1} ÷0.3
         = (2.197^2-1) ÷ 0.3
         = (4.8268-1) ÷ 0.3 
         = 12.756

ついでにこれも、「T2OFレシオ」(TWR^2 at Optimal-f Ratio)と、命名しました(笑)



3.計算式の背景


もし条件が「オプティマルfにおける幾何平均」であれば話は簡単なのですが、冒頭「目的関数の特性」にある、他の2つの条件を表現する必要があります。  単純に考えると、「幾何平均÷オプティマルf」が思いついたのですが、3番目の条件を満たせなくなります。

なので、倍率で表現した「幾何平均」を2乗すれば、条件をクリアできる、と思いついたわけです。 要は、前述の(式2)です。
#幾何平均が「+10%」であれば、1.1を2乗する

そして、(式2)を、もうちょっと意味がありそうな値として年率換算し、平方根をとることで、レベルをあわせ、(式1)に変形しました。 

「じゃあ、2乗じゃなくて、3乗や1.5乗じゃだめなのか?」 という疑問も、当然湧いてくると思うのですが、ダメな理由は何も思いつきません(笑)



4.考察


このパフォーマンス評価方法の欠点は、期待値がマイナスのシステムを評価できない点にあります。  これは、そもそも「オプティマルf」を求める際、期待値がマイナスだと、オプティマルfはゼロ(つまりトレードしない)がベストですので、実質的にオプティマルfが求まらないためです。

あと、「オプティマルf」を求めるのが面倒、という欠点もあります。  エクセルであれば「ソルバー」を使えば、簡単に求まります。  プログラムで求める場合は、「2分探索木」のアルゴリズムを使って、任意に決めた一定レベルの精度にたどり着くまで計算する、という方法があり、私はそうしています。

ちなみに、「オプティマルfなんて、ケリーの公式で簡単に求まるじゃないか」という意見もありそうですが、ラルフ・ビンスの資金管理大全」では、以下の様に、実質的に否定されています。


「 利益が常に同額でないとき、かつ/または、損失が常に同額でないときにはケリーの公式は適用できない。 適用しても正しいオプティマルfの値は得られない。 」 (「ラルフ・ビンスの資金管理大全」より

なので、裏をかえすと、固定値幅でTP/SLを指定して、他に決済ルールが無い場合は、「ケリーの公式」が使えるという事だと思います。



5.最後に


ここまでで、前回ブログ記事でいう「資産を最大化してくれるか?」という観点で評価するための、目的関数の計算方法について書いてきました。  つまり、パラメータ値の最適化時は、この「年率オプティマルfレシオ」(もしくはT2OFレシオ)が最大になるパラメータ値を選ぶ事になります。 

ただし実際には、「堅牢なパラメータ値か?(局所解に陥っていないか?)」という配慮も必要になり、その取組みが、オーバー・フィッティングを避けれるかどうかを左右するのだと思います。

次回は、この方法を具体的に書いてみたいと思います。 たぶん(笑)




ではでは~