レベル: 上級 木村 桂 (kimuc@jp.ibm.com), ソフトウェア事業, IBM
2007年 6月 15日 前回に引き続きファンダメンタル的な情報を元に投資を行うカブロボの例を紹介します。今回紹介するのは、PER や PBR といった個別銘柄の「お買い得感」を計算によって求めた上で、業績と比較して割安な、いわゆる「バリュー株」を探して売買する、というロジックをカブロボに実装してみます。
第2回スーパー・カブロボ・コンテスト本番開始
今週の6月5日(火)より第2回スーパー・カブロボ・コンテストの本番運用が開始になりました。今までは作ったロボットを登録しておくことはできたのですが、現在はコンテストに参加し、1日ごとに更新されるホンモノの株価データを使って運用されることになります。平行してロボットの成績審査も開始されるようです。詳しくはカブロボサイト(http://www.kaburobo.jp/)をご覧ください。
PER と PBR
お買い得な株のことを「バリュー株」と表現することも多いのですが、そもそもこのバリュー株とはどのような条件で区別されているのでしょうか? この答は、そもそも「どんな株が『お買い得』なのか?」という命題を解決することから考える必要があります。一般的には PER(Price Earning Ratio : 株価収益倍率)、PBR(Price Book-value Ratio : 株価純資産倍率)という2つの指標の値を判断材料に使います。
そもそも異なる2つの会社(の株)の価値を比較するのは難しいのです。例えば株価 10,000 円の会社Aと株価 500 円の会社Bとでは、Aの方がBの20倍価値がある、といえるものではありません。株価を単純に比較しただけでは、会社の規模や発行株数が異なるため、意味がありません。
そこでまず1株辺りに直した利益がどのくらいになるかを計算します。この値を EPS(Earnings Price Share : 一株あたり利益)といい、この値が大きいほどその会社の価値も大きい、といえるものです。そして更に現在の株価をこの EPS で割って、現在の株価が1株あたり利益の何倍になっているか? を求めたものが PER です。
PER = 現在の株価 ÷ EPS(一株あたりの利益)
現在の株式市場ではこの PER の値が 30 ~ 40 近辺が適正と言われています。これを超えていると割高で、下回っているほど割安といえます。
一方、会社の利益を基準に株価の価値を求めたものが PER であるのに対して、PBR では経営基盤となる純資産を基準に株価の価値を求めます。まず1株あたりの純資産を計算します。この値を BPS(Book-value Price Share : 一株あたり純資産)といいます。そして現在の株価をこの BPS で割って、現在の株価が1株あたり純資産の何倍になっているか? を求めたものが PBR です。
PBR = 現在の株価 ÷ BPS(一株あたりの純資産)
PBR が 1.0 以上、例えば10(倍)になっている株は、その会社の将来性・成長性などが見込まれた結果、その会社の純資産よりもはるかに高い値段で取引されていることになるので、その意味では割高です。一方、PBR が 1(倍)以下の場合は割安ということになります。
カブロボ SDK を使った PER お呼び PBR の取得
一方、カブロボの SDK を使ってこれら PER/PBR の値を取得するにはどうすればいいでしょうか? 実は現在の SDK ではこれらの値を簡単に取得する方法は用意されておりません。したがって自分自身(ロボット自身)で計算して求める必要があります。この計算に必要な値を取得する方法は用意されています。
カブロボ SDK には StockAccount というインターフェースが用意されています。このクラスは主に各個別銘柄の決算年月日や売上高、営業利益、経常利益、総資産といった四季報で得られるような決算データを取得するために用意されていますが、このインターフェースを通じて EPS や BPS の値を取得することもできるようになっています。これらの値があれば、直近の株価をこれらの値で割ることによって PER/PBR を求めることができます。
バリュー株の定義
あらかじめ述べておきますが、「お得な株」の判断に PER や PBR だけを見ればよい、という絶対的な基準があるわけではありません。例えばあまりに極端に大きかったりする数値は、期待感が極端に強いということなので、何かのきっかけで値が崩れる可能性を秘めている、ともいえます。あくまで投資判断材料の1つとしてお考えください。
ではここで改めて「バリュー株」の条件を決めます。数字に多少の上下はありますが、一般的には以下のような条件を満たす株のことを「バリュー株」と呼んでいるようです:
- PER が 15.0 以下
- PBR が 1.0 以下
- PER × PBR が 22.5 以下
今回作成するカブロボでは、この条件を少し厳しめに設定してみます。具体的には以下の2条件 <1>,<2> のうち、少なくともどちらか1つを満たしている個別銘柄があれば、それを「割安感のあるバリュー株である」と判断して買います:
<1> PER が 12.0 以下 かつ PBR が 1.0 以下
<2> PER × PBR が 22.5 以下
また、買った銘柄は今までと同様の方法でポジション管理を行いますが、これとは別に以下の条件 <3> を満たすことがあったら決済することにします:
<3> PER が 15.0 以上 かつ PBR が 1.0 以上
カブロボへの実装
以上の条件 <1>, <2>, <3> を毎日のスクリーニング時に全銘柄別に判断して、条件を満たすものがあれば翌日の注文に反映させるようなカブロボを作ります。具体的には以下のような、比較的シンプルなプログラムになります:
DwRobotAdv05.java の内容
import java.util.ArrayList;
import java.util.Calendar;
import jp.tradesc.superkaburobo.sdk.driver.RobotDriver;
import jp.tradesc.superkaburobo.sdk.robot.AbstractRobot;
import jp.tradesc.superkaburobo.sdk.trade.InformationManager;
import jp.tradesc.superkaburobo.sdk.trade.TradeAgent;
import jp.tradesc.superkaburobo.sdk.trade.data.Portfolio;
import jp.tradesc.superkaburobo.sdk.trade.data.Stock;
import jp.tradesc.superkaburobo.sdk.trade.data.StockAccount;
public class DwRobotAdv05 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>(); //. 売り候補
//. カブロボで対象としている各株のオブジェクトを取り出して、繰り返し1つずつスクリーニング処理を行う
InformationManager informationManager = arg0.getInformationManager();
ArrayList<Stock> stockList = informationManager.getStockList();
for( Stock stock : stockList ){
try{
//. 本日のアカウント情報 (1)
StockAccount stockAccount = informationManager.getStockAccount( stock );
Integer price = informationManager.getStockSession( stock ).getClosingPrice(); //. 終値 (2)
Double eps = stockAccount.getEps(); //. 一株あたり利益 (3)
Double bps = stockAccount.getBps(); //. 一株あたり純資産 (4)
Double per = ( double )price/eps; //. PER (5)
Double pbr = ( double )price/bps; //. PBR (6)
if( per <= 12.0 pbr <= 1.0 || per * pbr < 22.5){
//. PER 12.0 以下かつ PBR 1.0 以下、または PER * PBR < 22.5 の銘柄は買い (7)
buyList.add( stock );
}else if( per > 15.0 pbr > 1.0 ){
//. PER 15.0 以上、かつ PBR 1.0 以上の銘柄は売り (8)
sellList.add( stock );
}
}catch( Exception e ){
}
}
//. 買い/売りの候補リストを記憶するメモクラスを用意する
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", "DwRobotAdv05" };
RobotDriver.main( arg );
}
}
|
このプログラムでも order メソッドの内容は DwRobot04 のものと全く同様のものを利用しますので説明は省略します。では肝となる screening メソッドの中身を見てみましょう。
screening メソッドでは個別銘柄の Stock オブジェクトを取り出した後、同銘柄の StockAccount 型オブジェクトを取り出します(1)。PER や PBR の値を求める上で必要となる個別銘柄の決算データをこの StockAccount オブジェクトから取得するためです。
PER を求めるには EPS が、PBR を求めるには BPS が必要です。したがって、まずこの銘柄の直近の終値を取り出した(2)後に、StockAccount オブジェクトから EPS と(3)、BPS の値をそれぞれ取り出します(4)。そして終値を EPS で割ったものが PER(5)、BPS で割ったものが PBR になります(6)。
PER と PBR の値を求めることができれば後は数値を比較するだけです。上記 <1> または <2> のどちらかの条件を満たしていれば、この銘柄を買いのリストに追加(7)、<3> の条件を満たしていれば、この銘柄を売りのリストに追加します(8)。 後は過去のロボットと同様、最終的に出来上がったリストをオブジェクトメモに記録してスクリーニング処理は終了になります。
このロボットを 50 銘柄で 2006-01-04 から一年間テストすると、以下のような最終結果が出力されます:
カブロボ DwRobotAdv05 が停止した後の Console の内容
■■最終成績表■■■■■■■■■■■■■■■■■■■■
--●取引データ●--------------------------------------
初期資産額(円) : 50,000,000
最終資産額(円) : 56,020,652
取引開始日 :2006-01-04
取引終了日 :2006-12-29
経過日数(日) :359
運用日数(日) :248
総トレード数 :382
勝ちトレード数 :256
負けトレード数 :126
勝率(%) :67.02
年間平均トレード数 :382
全トレード平均期間(日) :75
勝ちトレード平均期間(日) :92
負けトレード平均期間(日) :40
最長フラット期間(日) :1
トータル約定金額(円) :369,205,100
--●損益データ●--------------------------------------
トータル純損益(%) :12.04
勝ちトレード純利益(%) :25.36
負けトレード純損失(%) :-12.63
買いトレード純損益(%) :12.73
売りトレード純損益(%) :0
平均損益(%) :4.21
平均利益(%) :11.59
平均損失(%) :-10.78
年率換算利回り(%) :11.89
最大勝ちトレード(%) :19.86
最大負けトレード(%) :-21.62
--●指標データ●--------------------------------------
平均ドローダウン(%) :2.26
最大ドローダウン(%) :10.4
損益レシオ(倍) :0.99
プロフィットファクター(倍):2.01
リスクレシオ(倍) :1.14
年率シャープレシオ(倍) :0.96
年率ボラティリティ(%) :12.37
■■■■■■■■■■■■■■■■■■■■■■■■■■■
|
もちろん偶然の要素もあると思いますが、このシミュレーション結果だけを見るとそれなりの成績が伴っているようです。2006年の結果を見る限りでは、「バリュー株」というキーワードが人気になったのもうなづけますね。
なお、今回作成したロボットは、定義したバリュー株の定義を満たし続ける限りは買い増し続ける設計になっていますので、その意味では少し乱暴な判断をしています。実際には robot-config.xml ファイル内の <each-stock-limit> タグで指定した銘柄組入比率上限値(初期設定では 10%)によって個別銘柄ごとの組入れ割合が制限されるため、資金が続く限り購入する、というわけではありませんが、これ以外の制限は特にありませんので注意してください。
次回は最終回
3月から続けてきました本連載ですが、定期的な更新は次回をもっていったん最終回とさせていただく予定です。今後は新しい情報が入ったり、皆様からいただいたリクエストに応えるような形での更新を考えています。要望などありましたらお聞かせください。
次回のテーマは「条件付き特別注文」です。これはカブロボ SDK 2.0 から利用できるようになった、つまり第2回スーパー・カブロボ・コンテストから新しく利用できるようになった新機能です。この新機能を、ロボットの実例を交えて紹介する予定です。お楽しみに。
著者について  | |  | 木村 桂: 日本IBM ソフトウェア事業 |
記事の評価
|