ロボット作成方法

ここでは、ロボットの基本的な作り方について説明します。


ロボットクラス作成

ロボットのクラスは jp.tradesc.superkaburobo.sdk.robot.AbstractRobot 抽象クラスを extends し、実装します。

ロボットの注文処理


 ロボットは前場の前(8時〜9時)と後場の前(11時半〜12時半)の2回、それぞれ前場・後場の注文に向けて思考する時間が与えられます。 思考時間はそれぞれとも3分が上限となっております。具体的には、ロボットクラスの order メソッドが実行されます。

ロボットのスクリーニング処理

 ロボットは翌営業日の注文に向けて、スクリーニング処理をすることで銘柄の絞込みを行なうことができます。
スクリーニング処理は、後場後(16時〜24時)の最大8分の間に行ないます。
スクリーニング後の銘柄を「監視銘柄」と呼び、翌営業日の注文では、この監視銘柄の中から注文することになります。
 具体的には、ロボットクラスの screening メソッドが実行されます( order メソッドは呼ばれません)。
よって、order メソッドだけではなく、別に screening メソッドも実装する必要があります。

例えば、下記のような MyRobot というロボットクラスを作ります。


import jp.tradesc.superkaburobo.sdk.robot.AbstractRobot;
import jp.tradesc.superkaburobo.sdk.trade.TradeAgent;

public class MyRobot extends AbstractRobot {
  @Override
  public void order(TradeAgent tradeAgent) {
    System.out.println("Robot Order Start");
  }

  @Override
  public void screening(TradeAgent tradeAgent) {
    System.out.println("Robot Screening Start");
  }
}

これをカレントディレクトリ、または kaburobo ホームディレクトリ配下の robot ディレクトリに MyRobot.java に保存し、次のようなコマンドを実行してコンパイルします。

Windows なら
%KABUROBO_HOME%\build MyRobot.java

Unix なら
$KABUROBO_HOME/build.sh MyRobot.java

でコンパイルできます。
コンパイルした後、Windows なら
%KABUROBO_HOME%\kaburobo -n ロボット名

Unixなら
$KABUROBO_HOME/kaburobo.sh -n ロボット名

と入力すると、作ったロボットを起動することができます。 また、robot-config.xml の robot-class-name タグで指定することもできます。
今回は MyRobot という名前にしたので、ロボット名を MyRobot にして実行します。

>%KABUROBO_HOME%\kaburobo MyRobot
.
.
.
よろしければ[Enter]キーまたは start と打って[Enter]キーを押してください。
キャンセルする場合は quit と打って[Enter]キーを押してください。
ヘルプを表示する場合は help と打って[Enter]キーを押してください。
>
start[Enter]


●● 2004/09/01 16:00 (水) ● スクリーニング処理開始 ●●●●●●●●●●●●●●●●●●●●●●●


【保有資産評価】
                                                                 取引余力        50,000,000 円
                                                                 株式評価額               0 円
                                                                 資産評価額      50,000,000 円


【ポートフォリオ】
所有銘柄はありません。

Robot Screening Start

●● 2004/09/01 23:59 (水) ● スクリーニング処理終了 ●●●●●●●●●●●●●●●●●●●●●●●

ロボット処理時間(ミリ秒): 63


■■ 2004/09/02 08:00 (木) ■ 注文処理開始 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■


【保有資産評価】
                                                                 取引余力        50,000,000 円
                                                                 株式評価額               0 円
                                                                 資産評価額      50,000,000 円


【ポートフォリオ】
所有銘柄はありません。

Robot Order Start

【注文結果】
注文はありません。

■■ 2004/09/02 09:00 (木) ■ 注文処理終了 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■

ロボット処理時間(ミリ秒): 12

(略)

このようにロボットが動作し、スクリーニング処理の時には "Robot Screening Start"、 注文処理の時には "Robot Order Start" というメッセージが出力されています。


様々な機能

解析及び注文のための機能が数多く揃っています。
それらを利用するのは全て TradeAgent から取得可能です。
全ての機能は 〜Manager というクラスにまとめられています。


注文の発行

注文指示は、とてもシンプルにできます。
OrderManagerのorder系メソッドを利用する事で注文を発行することが出来ます。
下記の例だと、トヨタ自動車(銘柄コード:7203)の現物買い注文を即時に成行で 100 株分出しています。

import jp.tradesc.superkaburobo.sdk.robot.AbstractRobot;
import jp.tradesc.superkaburobo.sdk.trade.InformationManager;
import jp.tradesc.superkaburobo.sdk.trade.OrderManager;
import jp.tradesc.superkaburobo.sdk.trade.TradeAgent;

public class MyRobotToyota extends AbstractRobot {
  @Override
  public void order(TradeAgent tradeAgent) {
    InformationManager informationManager = tradeAgent.getInformationManager();
    OrderManager order = tradeAgent.getOrderManager();
    order.orderActualNowMarket(informationManager.getStock(7203), 100);
  }

  @Override
  public void screening(TradeAgent tradeAgent) {
    System.out.println("Robot Screeing Start");
  }
}

この他にも指値や逆指値、寄り引けの指定など、細かく注文を出すことが出来ます。
また、新規信用取引の売却注文を出すことで空売りも出来ます。


ポートフォリオ

注文したものが、本当に約定されているかを確かめる為にポートフォリオを見てみます。
ポートフォリオの扱いは PortfolioManager から行います。
そして、ポートフォリオにある事を確認したら、それの反対売買を行ってみます。
下記の例ではポートフォリオに存在する銘柄の全株数を即時に成行で反対売買注文しています。

import java.util.ArrayList;

import jp.tradesc.superkaburobo.sdk.robot.AbstractRobot;
import jp.tradesc.superkaburobo.sdk.trade.InformationManager;
import jp.tradesc.superkaburobo.sdk.trade.OrderManager;
import jp.tradesc.superkaburobo.sdk.trade.PortfolioManager;
import jp.tradesc.superkaburobo.sdk.trade.TradeAgent;
import jp.tradesc.superkaburobo.sdk.trade.data.Portfolio;

public class MyRobotPortfolio extends AbstractRobot {
  @Override
  public void order(TradeAgent tradeAgent) {
    // ポートフォリオマネージャを取得します。
    PortfolioManager portfolioManager = tradeAgent.getPortfolioManager();
    
    // ポートフォリオを取得します。
    ArrayList<Portfolio> portfolioList = portfolioManager.getPortfolio();
    
    // ポートフォリオの内容を列挙します。
    for (Portfolio portfolio : portfolioList) {
      // コンソールに銘柄コードを出力します。
      System.out.println("Portfolio stockcode : " + portfolio.getStock().getStockCode());
      
      // 対象ポートフォリオの全株数を反対売買します。
      portfolio.orderReverseNowMarketAll();
    }
    
    // インフォメーションマネージャを取得します。
    InformationManager informationManager = tradeAgent.getInformationManager();
    
    // オーダーマネージャを取得します。
    OrderManager order = tradeAgent.getOrderManager();
    
    // 銘柄コード7203(トヨタ)の株を100株、現物即時成行注文します。
    order.orderActualNowMarket(informationManager.getStock(7203), 100);
  }

  @Override
  public void screening(TradeAgent tradeAgent) {
    System.out.println("Robot Screeing Start");
  }
}

株式情報データの利用

ではもう少ししっかりとしたデータに基づいて注文を行いたい為、株式情報データを見てみる事にします。
株式情報データは InformationManager から行います。
とりあえずカブロボで取り扱っている銘柄が何があるのかを調べるために、全銘柄リストを取得します。
下記の例では銘柄数を表示しています。
import java.util.ArrayList;

import jp.tradesc.superkaburobo.sdk.robot.AbstractRobot;
import jp.tradesc.superkaburobo.sdk.trade.InformationManager;
import jp.tradesc.superkaburobo.sdk.trade.OrderManager;
import jp.tradesc.superkaburobo.sdk.trade.PortfolioManager;
import jp.tradesc.superkaburobo.sdk.trade.TradeAgent;
import jp.tradesc.superkaburobo.sdk.trade.data.Portfolio;
import jp.tradesc.superkaburobo.sdk.trade.data.Stock;

public class MyRobotStockCount extends AbstractRobot {

  @Override
  public void order(TradeAgent tradeAgent) {
    // インフォメーションマネージャを取得します。
    InformationManager informationManager = tradeAgent.getInformationManager();
    // 対象銘柄の一覧を取得します
    ArrayList<Stock> stockList = informationManager.getStockList();
    // 対象銘柄数を出力します。
    System.out.println("StockList count : " + stockList.size());
    
    PortfolioManager portfolioManager = tradeAgent.getPortfolioManager();
    ArrayList<Portfolio> portfolioList = portfolioManager.getPortfolio();
    for(Portfolio portfolio : portfolioList){
      System.out.println("Portfolio stockcode : " + portfolio.getStock().getStockCode());
      portfolio.orderReverseNowMarketAll();
    }
    
    OrderManager order = tradeAgent.getOrderManager();
    order.orderActualNowMarket(informationManager.getStock(7203), 100);
  }

  @Override
  public void screening(TradeAgent tradeAgent) {
    System.out.println("Robot Screeing Start");
  }
}
次に先頭の銘柄の情報を取得してみます。
import java.util.ArrayList;

import jp.tradesc.superkaburobo.sdk.robot.AbstractRobot;
import jp.tradesc.superkaburobo.sdk.trade.InformationManager;
import jp.tradesc.superkaburobo.sdk.trade.OrderManager;
import jp.tradesc.superkaburobo.sdk.trade.PortfolioManager;
import jp.tradesc.superkaburobo.sdk.trade.TradeAgent;
import jp.tradesc.superkaburobo.sdk.trade.data.Portfolio;
import jp.tradesc.superkaburobo.sdk.trade.data.Stock;

public class MyRobotStockInfo extends AbstractRobot {
  
  @Override
  public void order(TradeAgent tradeAgent) {
    // インフォメーションマネージャを取得します。
    InformationManager informationManager = tradeAgent.getInformationManager();
    // 対象銘柄の一覧を取得します。
    ArrayList<Stock> stockList = informationManager.getStockList();
    // 対象銘柄数を出力します。
    System.out.println("StockList count : " + stockList.size());
    
    // 最初の銘柄の銘柄コード、銘柄、単位株数、業種コード、業種名を取得し表示します。
    if (stockList.size() >= 0) {
      Stock stock = stockList.get(0);
      System.out.println("StockList firststock" 
          + " StockCode:" + stock.getStockCode() 
          + " StockName:" + stock.getStockName()
          + " Unit:" + stock.getUnit()
          + " CategoryCode:" + stock.getCategory().getCategoryCode()
          + " CategoryName:" + stock.getCategory().getCategoryName());
    }
    
    PortfolioManager portfolioManager = tradeAgent.getPortfolioManager();
    ArrayList<Portfolio> portfolioList = portfolioManager.getPortfolio();
    for(Portfolio portfolio : portfolioList){
      System.out.println("Portfolio stockcode : " + portfolio.getStock().getStockCode());
      portfolio.orderReverseNowMarketAll();
    }
    
    OrderManager order = tradeAgent.getOrderManager();
    order.orderActualNowMarket(informationManager.getStock(7203), 100);
    
  }
  
  @Override
  public void screening(TradeAgent tradeAgent) {
    System.out.println("Robot Screeing Start");
  }
}
これで銘柄の基本的な情報となる銘柄コード、銘柄名、単元株数、業種コード、業種名を取得出来ました。
次は前後場の4本値を取得してみます。
import java.util.ArrayList;

import jp.tradesc.superkaburobo.sdk.robot.AbstractRobot;
import jp.tradesc.superkaburobo.sdk.trade.InformationManager;
import jp.tradesc.superkaburobo.sdk.trade.OrderManager;
import jp.tradesc.superkaburobo.sdk.trade.PortfolioManager;
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.StockData;

public class MyRobotStockPrice extends AbstractRobot {
  @Override
  public void order(TradeAgent tradeAgent) {
    // インフォメーションマネージャを取得します。
    InformationManager informationManager = tradeAgent.getInformationManager();
    
    // 対象銘柄の一覧を取得します。
    ArrayList<Stock> stockList = informationManager.getStockList();
    
    // 対象銘柄数を出力します。
    System.out.println("StockList count : " + stockList.size());
    
    // 最初の銘柄の銘柄コード、銘柄、単位株数、業種コード、業種名を取得し表示します。
    if (stockList.size() >= 0) {
      Stock stock = stockList.get(0);
      System.out.println("StockList firststock" 
          + " StockCode:" + stock.getStockCode() 
          + " StockName:" + stock.getStockName()
          + " Unit:" + stock.getUnit()
          + " CategoryCode:" + stock.getCategory().getCategoryCode()
          + " CategoryName:" + stock.getCategory().getCategoryName());
      
      // 4本値を取得・表示します。
      StockData stockData = informationManager.getStockSession(stock);
      System.out.println("StockSessionData " 
          + " opening:" + stockData.getOpeningPrice() 
          + " high:" + stockData.getHighPrice()
          + " low:" + stockData.getLowPrice()
          + " closing:" + stockData.getClosingPrice()
          + " volume:" + stockData.getTradingVolume()
          + " value:" + stockData.getTradingValue());
          
      OrderManager orderManager = tradeAgent.getOrderManager();
      orderManager.orderActualNowMarket(stock, stock.getUnit());
    }
    
    PortfolioManager portfolioManager = tradeAgent.getPortfolioManager();
    ArrayList<Portfolio> portfolioList = portfolioManager.getPortfolio();
    for(Portfolio portfolio : portfolioList){
      System.out.println("Portfolio stockcode : " + portfolio.getStock().getStockCode());
      portfolio.orderReverseNowMarketAll();
    }
  }
  
  @Override
  public void screening(TradeAgent tradeAgent) {
    System.out.println("Robot Screeing Start");
  }
}
4本値は InformationManager から取得出来ます。
getStockSession からは StockData 型で返ってきます。
上記の例では4本値及び出来高、売買代金を表示しています。
また、注文を 7203 に固定していましたが、最初の銘柄を買うように変更しました。
注文株数を1単位分にしました。

スクリーニング

今回から、このスクリーニング作業を、夜間に長い時間できるようにしました。
その為戦略としては
というのが最も良いと思われます。

絞り込んだ銘柄は、MemoManager の ObjectMemo を利用して保存しましょう。
下記にその利用方法を示します。

まず、MyObjectMemo クラスを作ります。
注意点として、データベースに書き込んで保存されるため、
Serializable インターフェースを実装しておかないと書き込むことが出来ない事があげられます。
import java.io.Serializable;
import java.util.ArrayList;

import jp.tradesc.superkaburobo.sdk.trade.data.Stock;

public class MyObjectMemo implements Serializable {
  private static final long serialVersionUID = 1L;
  private ArrayList<Stock> buyList = new ArrayList<Stock>();
  private ArrayList<Stock> sellList = new ArrayList<Stock>();
  public ArrayList<Stock> getBuyList() {
    return buyList;
  }
  public ArrayList<Stock> getSellList() {
    return sellList;
  }
  public void setBuyList(ArrayList<Stock> buyList) {
    this.buyList = buyList;
  }
  public void setSellList(ArrayList<Stock> sellList) {
    this.sellList = sellList;
  }
}
次に、上記で作成した MyObjectMemo の利用方法を例示します。
下記ではスクリーニング時に、買う銘柄である buyList に 7203 を、売る銘柄である sellList に 2914 を追加してます。
そして、注文時にそれらを呼び出しています。
この流れは MemoManager を使うことで実現できます。
import java.util.ArrayList;

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.Stock;

public class MyRobotUsingMemo extends AbstractRobot {

  @Override
  public void order(TradeAgent tradeAgent) {
    MyObjectMemo memo = (MyObjectMemo)tradeAgent.getMemoManager().getObjectMemo();
    if(memo != null){
      for(Stock stock : memo.getBuyList())
        System.out.println("買う銘柄:" + stock.getStockCode());
      for(Stock stock : memo.getSellList())
        System.out.println("売る銘柄:"+ stock.getStockCode());
    }
  }

  @Override
  public void screening(TradeAgent tradeAgent) {
    InformationManager informationManager = tradeAgent.getInformationManager();
    MyObjectMemo memo = new MyObjectMemo();
    ArrayList<Stock> buyList = memo.getBuyList();
    ArrayList<Stock> sellList = memo.getSellList();
    
    buyList.add(informationManager.getStock(7203));
    sellList.add(informationManager.getStock(2914));
    
    tradeAgent.getMemoManager().setObjectMemo(memo);
  }
}

テクニカル分析

スクリーニング時により詳細に絞り込みたい時にはテクニカル分析が便利です。
テクニカル分析には AnalysisManager を利用します。

下記の例では、まず AnalysisManager から RSI と MovingAverage クラスを引数を指定して取得します。
EnumAnalysisSpan では、分析期間の粒度(前後場足、日足、週足、月足)を指定できます。
取得した分析クラスでは、getIndex〜 というメソッドに銘柄コードを入れるだけで値を取得する事が可能です。
今回は RSI と短期移動平均と長期移動平均の数値を組み合わせてスクリーニングをしています。
import java.util.ArrayList;

import jp.tradesc.superkaburobo.sdk.robot.AbstractRobot;
import jp.tradesc.superkaburobo.sdk.trade.AnalysisManager;
import jp.tradesc.superkaburobo.sdk.trade.EnumAnalysisSpan;
import jp.tradesc.superkaburobo.sdk.trade.TradeAgent;
import jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.MovingAverage;
import jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.RSI;
import jp.tradesc.superkaburobo.sdk.trade.data.Stock;

public class MyRobotTechnical extends AbstractRobot {

  @Override
  public void order(TradeAgent tradeAgent) {
    MyObjectMemo memo = (MyObjectMemo)tradeAgent.getMemoManager().getObjectMemo();
    if(memo != null){
      for(Stock stock : memo.getBuyList())
        System.out.println("買う銘柄:" + stock.getStockCode());
      for(Stock stock : memo.getSellList())
        System.out.println("売る銘柄:"+ stock.getStockCode());
    }
  }

  @Override
  public void screening(TradeAgent tradeAgent) {
    MyObjectMemo memo = new MyObjectMemo();
    ArrayList<Stock> buyList = memo.getBuyList();
    ArrayList<Stock> sellList = memo.getSellList();
    
    AnalysisManager analysisManager = tradeAgent.getAnalysisManager();
    RSI rsi = analysisManager.getRSI(EnumAnalysisSpan.DAILY, 10);
    MovingAverage ma20 = analysisManager.getMovingAverage(
        EnumAnalysisSpan.DAILY, 20);
    MovingAverage ma40 = analysisManager.getMovingAverage(
        EnumAnalysisSpan.DAILY, 40);
    for (Stock stock : tradeAgent.getInformationManager().getStockList()) {
      Double rsiVal = rsi.getIndexSimple(stock);
      Double maVal20 = ma20.getIndexSimple(stock);
      Double maVal40 = ma40.getIndexSimple(stock);
      if (rsiVal != null && maVal20 != null && maVal40 != null)
        if (rsiVal <= 40.0 && maVal20 > maVal40) {
          buyList.add(stock);
        } else if (rsiVal * 100 >= 60.0 && maVal20 < maVal40) {
          sellList.add(stock);
        }
    }
    tradeAgent.getMemoManager().setObjectMemo(memo);
  }
}

ETFの利用について

◆ETFとは

ETF とは、"Exchange Traded Fund"の略で、東証などの取引所で取引きされている投資信託のことを指しています。

カブロボでは、以下の2銘柄を取り扱います。

ETF取り扱い一覧
銘柄コード銘柄名
1330上場インデックスファンド225
1306TOPIX連動型上場投資信託

以下に、ETF対応のSDKの使用方法を簡単にご説明いたします。

◆ETFを使うために

robot-config.xml を事前に修正しておく必要があります。
方法は SDK付属の robot-config.html のドキュメントをご覧ください。

◆ETFの使い方

ETFは通常の銘柄と同様に扱うことができます。
OrderManager->[JavaDoc] クラスで通常の銘柄同様注文します。
成行、指値、逆指値も可能です。
また、空売りもできます。

◆ETFのStockクラスの取得方法

詳しい内容は、JavaDocをご覧ください。

以下のサンプルでは、ETFの銘柄コードと銘柄名を出力します。

    for(Category cat: InformationManager.getInstance().getEtfList()){
      ArrayList<Stock> stocks = cat.getStockList();
      for(Stock etf: stocks){
        RobotLogManager.getInstance().log(etf.getStockCode() + " : " + etf.getStockName());
      }
    }

出力例:

1306 : TOPIX連動型上場投資信託
1330 : 上場インデックスファンド225

その他の下記の形でETFリストを取得可能です。

◆ETFと通常の銘柄の違い


成績表

ロボットの稼動状況及び成績は最後に表示される成績表を確認するのが最も効率的です。
中でもエントリー基準の項目は最低限合格しなければならないので注意してください。

ここでは、最後の成績表示を自分なりにカスタマイズしたい方に、そのやり方を解説します。
AbstractRobotterminate(PerformanceAgent performanceAgent) メソッドをオーバーライドして下さい。
引数の PerformanceAgent では様々な成績を計算して閲覧することが出来ます。
自分なりに組み合わせたい場合や、アラートを出したい場合などに利用する事が可能です。

下記の例では、super.terminate(performanceAgent)を呼ぶ事で、デフォルトの表示をして、
さらに自分なりに解析した結果を出力するようにしています。
  @Override
  public void terminate(PerformanceAgent performanceAgent){
    super.terminate(performanceAgent);
    System.out.println("My合格基準 [純損益10%以上] :"
        + (performanceAgent.getProfitAll() > 10 ? "合格" : "不合格"));
  }
一つ注意しなくてはいけないのが、この terminate メソッドは SDK でのセルフテスト時のみ有効という事です。
全ての運用が終わった時に解析をするため、仮想運用中や実運用中はこのメソッドは呼ばれません。
あくまでも最終成績の確認の為に利用してください。

まとめ

以上で簡単なロボットの作り方は終わりです。
ここでは全ての機能を説明しきれませんが、
他にも数多くの機能があります。
TradeAgentから全てアクセス出来るようになっていますので、色々とお試しください。
そして、オリジナルのカブロボを作って参加しましょう!