レベル: 上級 木村 桂 (kimuc@jp.ibm.com), ソフトウェア事業, IBM
2007年 5月 11日
これまでに「スーパー・カブロボ・コンテスト 予習編」として7回に渡る連載記事で Java
ロボットの作り方、およびコンテストへの登録方法を紹介してきました。この内容で一通りの基本的な手順が紹介できたと思っています。しかし、スーパー・カブロボ・コンテストに
Java
ロボットで参加を検討している皆さんからより高度な投資アルゴリズムの実装方法の紹介についてのご意見を多くいただております。そこで
IBM developerWorks のカブロボサイトでは、改めて「上級編」として、カブロボ SDK
のより高度な使い方を紹介していくことにします。まず第一回目はカブロボ SDK
で用意されているテクニカル指標の使い方を紹介します。
カブロボ SDK で用意されているテクニカル指標
「スーパー・カブロボ・コンテスト 中級編」では全7回に渡り、投資ロボットの作成方法とその改良を紹介してきましたが、実はここで紹介したロボットの売買判断で用いた基準は移動平均値によるゴールデンクロスやデッドクロスという、比較的単純な単一のテクニカル手法だけを用いてきました。これはロボットの作り方そのものに重点を置いて紹介するためであって、判断ロジックそのものを複雑にしてしまうことで、記事全体の理解が困難にならないようにする、という配慮を行った結果でした。しかしその結果、より高度で複雑なテクニカル手法を用いるロボットを作りたいと考える方の希望に沿う形にはなっていませんでした。そこで今回はゴールデンクロス/デッドクロス以外のテクニカル手法を使った売買ロジックをロボットに実装する方法を紹介します。
まず、カブロボ SDK にはどのようなテクニカル手法が用意されているのでしょうか?この原稿はカブロボ SDK
2.0 RC2
をベースにしていますが、このバージョンの時点では全部でこれだけのテクニカル手法をカバーしています:
|
| テクニカル手法の一般名称 | カブロボ SDK 内でのクラス名 |
|---|
| 1 | ボリンジャーバンド |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.BollingerBand
|
|---|
| 2 | DMI |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.DMI
|
|---|
| 3 | エンベロープ |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.Envelope
|
|---|
| 4 | ゴールデンクロス |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.GoldenCross
|
|---|
| 5 | 黄金比率 |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.GoldenSectionRatio
|
|---|
| 6 | HLバンド |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.HLBand
|
|---|
| 7 | 一目均衡表 |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.Ichimoku
|
|---|
| 8 | MACD |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.MACD
|
|---|
| 9 | モメンタム |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.Momentum
|
|---|
| 10 | 移動平均 |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.MovingAverage
|
|---|
| 11 | サイコロジカルライン |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.PsychologicalLine
|
|---|
| 12 | RCI |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.RCI
|
|---|
| 13 | Rオシレーター |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.ROscillator
|
|---|
| 14 | RSI |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.RSI
|
|---|
| 15 | ストキャスティクス |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.Stochastics
|
|---|
| 16 | 株価変化率 |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.StockPriceRC
|
|---|
| 17 | 標準偏差 |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.Volatility
|
|---|
| 18 | ボリュームレシオ |
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.VolumeRatio
|
|---|
実際には例えば一目均衡表のように、1つのテクニカル手法の中に複数の異なるテクニカル指標が含まれていたり、またそれら主要なテクニカル指標値の移動平均値を求めるためのクラス(
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.FunctionInMovingAverage
)が別途用意されています。
中級編ではこの中のゴールデンクロスのみ扱っていましたので、今回は他のテクニカル手法の紹介例として RSI
を取り上げます。RSI は相対力指数(Ralative Strength
Index)の略で、過去の値動きを参考に「買われ過ぎ度合い」を 0 ~ 100% の数値で表したものです。この
RSI
値の計算方法は過去数日分(一般的には14日分)の株価データを基にした特定の計算を行うことで求めますが、カブロボ
SDK では上記 RSI
クラスを用いることでこの計算を自動化することができるため、ここでの詳細な計算方法は省略します。
計算結果としての RSI の値が 100%
の場合は「買われ過ぎ度満点」でむしろ「もう下がるだろう」という判断になります。逆に RSI 値が 0%
の場合は「買われ過ぎ度ゼロ」で、むしろ「売られ過ぎ度満点」です。こちらは「もう上がるだろう」と判断します。一般的には
RSI が 20% 以下の場合は買いのサイン、80% 以上の場合は売りのサインと判断されています。
心強い味方、JavaDoc
では早速 RSI を使って売買ロボットを作ってみましょう・・・と、その前に。カブロボ SDK を使ってどのように
RSI 値を求めるのかが分かっていないと何もできませんよね。というわけで、カブロボ SDK で用意されている
JavaDoc と呼ばれる形式のリファレンスを参照して確認してみます。カブロボ SDK
を導入したフォルダ(例えば C:\Kaburobo)の中に doc というサブフォルダがあり、更にその中には
javadoc というサブフォルダがあります。この javadoc サブフォルダ内には index.html
というファイルがあります。
この index.html をダブルクリックすると、カブロボ SDK の javadoc
形式のリファレンスが開きますので、ここから RSI
クラスを指定します。今回のようにクラス名が分かっていれば左下のクラス一覧から直接選んでも構いません。ただ今回はテクニカル指標のクラス一覧から
RSI を選んでみましょう。まず左上フレーム内でテクニカル指標のクラスがまとめて管理されている "
jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex
というパッケージ名をクリックします。すると左下フレーム内のみ変更され、このパッケージに含まれるテクニカル指標に関したクラスだけの一覧になります。今回はここから
"RSI" を選択します。
すると画面右側のフレームが変更になり、ここに RSI
クラスの使い方が表示されます。まず「コンストラクタの概要」を見ると、2種類のコンストラクタが存在していることがわかります。1つ目は何もパラメータを指定しない場合で、この場合は無条件に「日足ベースの14日集計による
RSI」が指定されたと見なされることになっていることが分かります。また2つ目は2つのパラメータを指定した場合で、こちらは粒度(前後場足、日足、週足、月足)と集計日数を指定した
RSI を計算することになっていることが分かります。また RSI の値を求めるメソッドについても
getIndexSimple()
という命令を実行すればよいのですが、この実行方法にもパラメータの指定方法によって2種類あることがわかります。1つは株式銘柄の種類を示す
Stock オブジェクトだけを指定して直近の RSI 値を求める場合と、もう1つは Stock
オブジェクトに加えて整数を指定し、何回か前の(日足であれば何日か前の) RSI
値を求める場合とがあることがわかります。
では、これらを参考にしながら実際にロボットを作ってみることにします。
RSI 売買ロボットの作成と実行
ロボットそのものの作り方は中級編で紹介したものと同様です。まずは中級編を一通り目を通しておいてください。また中級編(4)で作成した
DwMemo.java
を今回も使いますので、まだ用意されていない場合は中級編(4)の内容を参考に別途作成しておいてください。今回は上級編ということで
DwRobotAdv01 という名前のロボットを以下の内容で作成します:
DwRobotAdv01.java の内容
import java.util.ArrayList;
import jp.tradesc.superkaburobo.sdk.driver.RobotDriver;
import jp.tradesc.superkaburobo.sdk.robot.AbstractRobot;
import jp.tradesc.superkaburobo.sdk.trade.EnumAnalysisSpan;
import jp.tradesc.superkaburobo.sdk.trade.TradeAgent;
import jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.RSI;
import jp.tradesc.superkaburobo.sdk.trade.data.Portfolio;
import jp.tradesc.superkaburobo.sdk.trade.data.Stock;
public class DwRobotAdv01 extends AbstractRobot {
@Override
public void order(TradeAgent arg0) {
// TODO Auto-generated method stub
//. 省略(DwRobot04 の order メソッドと同じ)
}
@Override
public void screening(TradeAgent arg0) {
// TODO Auto-generated method stub
//. 売買の候補リストを用意
ArrayList<Stock> buyList = new ArrayList<Stock>(); //. 買い候補
ArrayList<Stock> sellList = new ArrayList<Stock>(); //. 売り候補
//. 13日計算の RSI のクラスを用意する (1)
RSI rsi = arg0.getAnalysisManager().getRSI( EnumAnalysisSpan.DAILY, 13 );
//. このシミュレーションで取引できる全株銘柄を取得する
ArrayList<Stock> stockList = arg0.getInformationManager().getStockList();
//. 個別に銘柄を1つずつ取得して、RSI の値をチェックする
for( Stock stock : stockList ){
//. 取り出した銘柄の RSI 値を調べる
Double x1 = rsi.getIndexSimple( stock ); //. 当日の RSI 値 (2)
Double x0 = rsi.getIndexSimple( stock, 1 ); //. 1営業日前の RSI 値 (3)
if( x0 <= 30.0 30.0 <= x1 ){
//. 前営業日から今日にかけて RSI 値が 30.0 を超えた場合は、買い候補 (4)
buyList.add( stock );
}else if( x0 >= 70.0 70.0 >= x1 ){
//. 前営業日から今日にかけて RSI 値が 70.0 を下回った場合は、売り候補 (5)
sellList.add( stock );
}
}
//. 買い/売りの候補リストを記憶するメモクラスを用意する
DwMemo memo = new DwMemo();
//. メモに売買それぞれの候補リストを設定する
memo.setBuyList( buyList );
memo.setSellList( sellList );
//. メモを格納する
arg0.getMemoManager().setObjectMemo( memo );
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//. 便利に実行するためのおまじない
String[] arg = { "-n", "DwRobotAdv01" };
RobotDriver.main( arg );
}
}
|
まず order メソッドの内容ですが、これは中級編(5)で紹介した DwRobot04.java 内の
order
メソッドを全く同じものを用意します(上記リストでは省略していますが、実際にはプログラムを入力する必要があります)。つまりこのロボットは空売りをせず、買った銘柄の株価が
15% 以上上昇するか、10%
以上下落するか、あるいはスクリーニングによって下落候補であると判断されるか、いずれか1つが合致した場合に決済となります。
次に screening メソッドの内容ですが、こちらも大まかには DwRobot04.java
のものと同じです。異なるのは上昇候補か下落候補かの判断に RSI の値を用いている点です。まず RSI
の管理クラスを生成します。14日の日足であればパラメータなしで生成できますが、今回は少し変更して13日の日足で
RSI を計算するよう指定しています(1)。
次に各銘柄ごとに RSI
の値を調べます。が、このロボットでは以下の基準で上昇候補/下落候補を振り分けることにします:
| RSI の値が 30% を超えた | ・・・ | 上昇のサイン | | RSI の値が 70% を下回った | ・・・ | 下落のサイン |
ここで難しいのが「超えた」とか「下回った」という判断です。例えば 30% を超えたかどうかの判断は当日の RSI
値だけでは判断できません。仮に今日の RSI 値が 30% を上回っていたとしても、前営業日も 30%
を超えていたのであれば今日は上昇のサインとみなすべきではありません。RSI の場合はあくまで 30%
を「超えた瞬間」をサインとみなすため、その判断には前営業日の RSI 値も不可欠になります。そこで RSI
クラスの
getIndexSimple
メソッドを使って当日の RSI 値を求めるだけでなく(2)、同時に前営業日の同じ銘柄の RSI
値も求めておきます。前営業日とは1営業日前なので、
getIndexSimple
メソッドの第2パラメータに "1"
という整数を指定して値を求めます(3)。ちなみに、もしも2営業日前や3営業日前の RSI
値を求めたい場合であれば、この部分に 2 や 3
をそれぞれ指定して、同様に値を求めることができます。 こうして求めた当日と前営業日の RSI
値を比較して、前営業日の値が 30% 以下で、かつ当日の値が 30%
以上になっていれば、ここで「30%を超えた」と判断して買いの候補リストに加えます(4)。また同様に前営業日の値が
70% 以上で、かつ当日の値が 70%
以下になっていれば、「70%を下回った」と判断して売りの候補リストに加えます(5)。
後は全て DwRobot04
と同様です。つまりロボットの戦略そのものは変更せず、上昇/下落のサインの判断基準だけを(ゴールデンクロス/デッドクロスから)RSI
の値をベースとした方法に変更したのが DwRobotAdv01 になります。
なお、このロボットを 2004/09/01 から 2005/08/31 まで 50
銘柄でシミュレーション実行した最終結果は以下のようになります。結果論ですが、勝率も純損益も DwRobot04
よりは少し改善できている模様です。
カブロボ DwRobotAdv01 が停止した後の Console の内容
■■最終成績表■■■■■■■■■■■■■■■■■■■■
--●取引データ●--------------------------------------
初期資産額(円) : 50,000,000
最終資産額(円) : 52,472,866
取引開始日 :2004-09-01
取引終了日 :2005-08-31
経過日数(日) :365
運用日数(日) :245
総トレード数 :302
勝ちトレード数 :216
負けトレード数 :86
勝率(%) :71.52
年間平均トレード数 :238
全トレード平均期間(日) :46
勝ちトレード平均期間(日) :40
負けトレード平均期間(日) :61
最長フラット期間(日) :4
トータル約定金額(円) :337,110,200
--●損益データ●--------------------------------------
トータル純損益(%) :4.95
勝ちトレード純利益(%) :9.97
負けトレード純損失(%) :-4.36
買いトレード純損益(%) :5.61
売りトレード純損益(%) :0
平均損益(%) :2.08
平均利益(%) :4.58
平均損失(%) :-4.22
年率換算利回り(%) :4.95
最大勝ちトレード(%) :21.62
最大負けトレード(%) :-12.85
--●指標データ●--------------------------------------
平均ドローダウン(%) :1.02
最大ドローダウン(%) :4.86
損益レシオ(倍) :0.91
プロフィットファクター(倍):2.29
リスクレシオ(倍) :1.02
年率シャープレシオ(倍) :0.85
年率ボラティリティ(%) :5.82
■■■■■■■■■■■■■■■■■■■■■■■■■■■
|
次回予告
今回はカブロボ SDK 内に用意されているテクニカル手法ライブラリから RSI
の利用方法と、その実例ロボットを紹介しました。RSI
以外のテクニカル手法については個別に紹介する予定はありませんが、RSI での例と javadoc
を同様に参考にしながら是非色々なテクニカル手法に挑戦してみてください。
次回はテクニカル手法を利用するのではなく、個別銘柄ごとに過去の値動きを取得する方法を紹介する予定です。
著者について  | |  | 木村 桂: 日本IBM ソフトウェア事業 |
記事の評価
|