アプリケーションの実装
このアプリケーションではEncogを使用します。Encogは、Lesser GNU Public License(LGPL)の下にリリースされているオープンソースのニューラルネットワークフレームワークです。Java、.Net、Silverlight向けにEncogの各バージョンが提供されています。Encogは、Google Codeでホスティングされています。ダウンロードリンクやEncogに関する詳細情報については、http://www.heatonresearch.com/encogを参照ください。
アプリケーションでは、ニューラルネットワーク用のトレーニングデータを作成する必要があります。トレーニングデータは、プログラムの中のGatherUtilクラスによって収集します。トレーニング方法を改良するには、このクラスを変更します。大きなデータブロックからのトレーニングデータの作成にも、ニューラルネットワークに対する予測の問い合わせにもこのクラスを使用します。まずは、トレーニングデータの生成方法を見ていきましょう。トレーニングデータは、LoadCompanyというメソッドで生成します。このメソッドではまず、YahooFinanceLoaderを作成します。YahooFinanceLoaderは、Encogで提供されているものです。
IMarketLoader loader = new YahooFinanceLoader(); TickerSymbol ticker = new TickerSymbol(symbol);
Encogに対し、対象とする市場データを供給するためのリストを作成しなければなりません。ここでは毎日の終値、始値、高値、低値を使用します。実際のローソク足データのみを使用します。シンプルなプログラムにするために、出来高は使用しません。ただし出来高は、トレンドの予測に非常に有用であり、他の投資規律ではこれを考慮に入れる場合が多くあります。
IList<MarketDataType> dataNeeded = new List<MarketDataType>(); dataNeeded.Add(MarketDataType.ADJUSTED_CLOSE); dataNeeded.Add(MarketDataType.CLOSE); dataNeeded.Add(MarketDataType.OPEN); dataNeeded.Add(MarketDataType.HIGH); dataNeeded.Add(MarketDataType.LOW);
次に、要求されたすべてのデータを大きなリストに代入し、ソートします。
List<LoadedMarketData> results = (List<LoadedMarketData>)loader.Load(ticker, dataNeeded, from, to); results.Sort();
上昇または下落のトレンド
次に、すべてのデータに対して処理を繰り返し、トレーニングデータを構築していきます。予測ウィンドウで指定された日数分のデータを、現在日からさかのぼって参照する必要があります。そこで、リストの先頭から少なくとも予測ウィンドウ1つ分を飛ばした次のデータから、ループ処理を開始します。ちょうど評価ウィンドウ1つ分のデータを残して、ループ処理を終了します。評価ウィンドウは、予測ウィンドウの後に始まるのが上昇または下落のどちらの傾向であるかを判定するために使用します。
for (int index = PredictWindow; index < results.Count - EvalWindow; index++) {
市場データを取得したら、それがチャートにおいて、上昇期間(の到来を示唆する期間)であるのか下落期間(の到来を示唆する期間)であるのかを示す、2つのフラグを作成します。
LoadedMarketData data = results[index]; // determine bull or bear position, or neither bool bullish = false; bool bearish = false;
上昇期間か下落期間かを判定するために、評価期間に対してループ処理を行い、変動率(パーセントの変化)を調べます。
for (int search = 1; search <= EvalWindow; search++) { LoadedMarketData data2 = results[index + search]; double priceBase = data.GetData(MarketDataType.ADJUSTED_CLOSE); double priceCompare = data2.GetData(MarketDataType.ADJUSTED_CLOSE); double diff = priceCompare - priceBase; double percent = diff / priceBase;
変動率が上昇パーセントよりも高ければ、上昇期間となります。下落パーセントよりも低ければ、下落期間となります。
if (percent > BullPercent) { bullish = true; } else if (percent < BearPercent) { bearish = true; } }
上昇期間であったか下落期間であったかが分かれば、トレーニングデータを作成できます。上昇でも下落でもない場合は、トレーニングデータは作成されません。チャート全体が、トレーニングに使用されるわけではなりません。
INeuralDataPair pair = null; if (bullish) { pair = CreateData(results, index, true); } else if (bearish) { pair = CreateData(results, index, false); }
トレーニングペアが作成された場合は、それをEncogトレーニングデータに追加します。
if (pair != null) { training.Add(pair); }
上のプログラムでは、ニューラルネットワークへの入力データを作成するためにCreateData
というメソッドを呼び出しています。このメソッドは、トレーニングペアの入力側を生成する際と、予測のためのニューラルネットワークへの入力を作成する際の両方に使用します。メソッドでは、評価ウィンドウを参照し、ニューラルネットワークへの入力を作成します。以下では、この非常に重要な関数について説明します。
この関数ではまず、BasicNeuralData
オブジェクトを作成します。Encogでは、ニューラルネットワークへのすべての入力および出力に、このオブジェクトを使用します。14個の要素があります。それぞれの要素は、本稿前半に示したローソク足の14種類の基本パターンに対応しています。ここでは非常に簡単なパターンを使用することにします。ここでは単に、14種類のローソク足パターンに対し、それぞれその総数を求めます。これは非常に簡単な方法ですが、ある程度の良い結果が得られます。もっと高度な方法を採用する場合も、ニューラルネットワークに対して、評価ウィンドウを浮動小数点数の配列としてどのように表現するかという観点から考察するとよいでしょう。ニューラルネットワークへの入出力は必ず、浮動小数点数の配列となります。
このような非常に簡単な方法が使用できるのは、各ローソク足がアトミックだからです。ここでは、ある1日の変動だけを考慮に入れています。実際の日々の値動きは考慮していません。そのためプログラムでは、株式分割について考慮する必要がありません。これにより、ニューラルネットワークの複雑さが少し緩和されます。日々の値動きを比較する場合には、株式分割があったことを示す「調整後終値」という項目を使用する必要が生じます。
INeuralData neuralData = new BasicNeuralData(14); int totalPatterns = 0; int[] patternCount = new int[14];
評価ウィンドウ全体に対し、ループ処理を行います。
for (int i = 0; i < EvalWindow; i++) { LoadedMarketData data = marketData[(marketDataIndex-EvalWindow) + i];
提供されているIdentifyCandleStick
クラスを用いて、どのパターンのローソク足であるかを判定します。
IdentifyCandleStick candle = new IdentifyCandleStick(); candle.SetStats(data); int pattern = candle.DeterminePattern();
変数pattern
には、それがどのパターンのローソク足であるかを表す、0から13の間の数値が代入されます。各パターンの数をカウントしていきます。
if (pattern != IdentifyCandleStick.UNKNOWN) { totalPatterns++; patternCount[pattern]++; } }
すべてのヒゲと実体の組み合わせが、名前を持つローソク足になるとは限りません。評価ウィンドウの中に、名前を持つローソク足パターンが1つもなかった場合、その評価ウィンドウは考慮に入れません。
if (totalPatterns == 0) return null;
ニューラルネットワークに入出力する浮動小数点数は通常、0~1の間の数値になります。これに対応するために、14種類のローソク足パターンのそれぞれを百分率で表します。入力ニューロンは、全部で14個になります。
for (int i = 0; i < 14; i++) { neuralData[i] = ((double)patternCount[i]) / ((double)totalPatterns); } return neuralData;
上記の入力を受け取り、上昇傾向に対して0.9、下落傾向に対して0.1を出力するように、ニューラルネットワークをトレーニングします。このネットワークを予測に使用する場合は、ローソク足の平均個数をネットワークに入力し、その出力によって予測を行います。出力が0.8以上の場合は上昇傾向、0.2以下の場合は下落傾向であると判断します。それ以外の値の場合は、ネットワークはその日の傾向に関し、中立の立場を示すことになります。
まとめ
本稿では、テクニカルな市場分析の支援にニューラルネットワークを使用するための非常に簡単な方法を紹介しました。これを出発点にして、他のテクニカルまたはファンダメンタルな手法を探求していくとよいでしょう。拡張点としては、出来高や日々の値動きの導入、ニューラルネットワークに対するパターンのより適切な表現方法が挙げられます。Encogの詳細情報や、その他の例については、Encogのホームページhttp://www.heatonresearch.com/encogを参照ください。