カブロボをJUnitから実行する
JUnitから実行というの作ってみました。
KabuRoboDriverのソースを切り貼りしたものです。
テスト用のヘルパークラスの例
package hoge; import java.io.PrintStream; import java.text.DateFormat; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.TimeZone; import java.util.logging.ConsoleHandler; import java.util.logging.FileHandler; import java.util.logging.Formatter; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; import jp.kaburobo.information.CachedInformationManagerBuilder; import jp.kaburobo.information.InformationManager; import jp.kaburobo.information.InformationManagerBuilder; import jp.kaburobo.informationprovider.model.IndexDailyDao; import jp.kaburobo.informationprovider.model.IndexYearlyDao; import jp.kaburobo.investment.FlexibleInvestmentAgentFactory; import jp.kaburobo.investment.InvestmentAgent; import jp.kaburobo.investment.OrderHistory; import jp.kaburobo.investment.Portfolio; import jp.kaburobo.robot.Robot; import jp.kaburobo.search.CachedSearchManagerBuilder; import jp.kaburobo.search.SearchManager; import jp.kaburobo.search.SearchManagerBuilder; import jp.kaburobo.stockserviceprovider.client.IStockAgentClient; import jp.kaburobo.stockserviceprovider.client.StockAgentClient; import jp.kaburobo.stockserviceprovider.client.StockAgentDebugClient; import jp.kaburobo.technical.TechnicalAnalysisManager; import jp.kaburobo.technical.TechnicalAnalysisManagerBuilder; import jp.kaburobo.technical.XMLTechnicalAnalysisManagerBuilder; import jp.kaburobo.util.FixedTimeSetting; import jp.kaburobo.util.LogFilter; import jp.kaburobo.util.LoggingStream; import jp.kaburobo.util.MarketSchedule; import jp.kaburobo.util.Time; import jp.kaburobo.util.XMLConfigLoader; /** * @see jp.kaburobo.driver.KabuRoboDriver */ public class KaburoboTestManager { private static KaburoboTestManager testManager; static{ try{ testManager = new KaburoboTestManager(); }catch(Exception e){ e.printStackTrace(); throw new IllegalStateException("testManager initilize fail"); } } private DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); private DecimalFormat moneyFormat = new DecimalFormat("###,###,###"); private Logger logger; private IStockAgentClient stockAgentClient; private InvestmentAgent investmentAgent; private FixedTimeSetting timeSetting; private Calendar date; public static KaburoboTestManager getInstance(){ return testManager; } private KaburoboTestManager() { try{ XMLConfigLoader config = XMLConfigLoader.getInstance(); PrintStream err = System.err; PrintStream out = System.out; logger = Logger.getLogger("jp.kaburobo.logging"); logger.setUseParentHandlers(false); String[] logHandlers = config.getLogHandlers(); for(int i=0; i<logHandlers.length; i++){ try{ Handler handler = null; if(logHandlers[i].equals("console")){ System.setErr(out); handler = new ConsoleHandler(); System.setErr(err); } else if(logHandlers[i].equals("file")){ String file = config.getLogFile(logHandlers[i]); handler = new FileHandler(file); } if(handler != null){ LogFilter outputFilter = new LogFilter(); handler.setFilter(outputFilter); String[] filters = config.getFilters(logHandlers[i]); if(filters != null){ for(int j=0; j<filters.length; j++){ outputFilter.addType(filters[j]); } } String formatter = config.getFormatter(logHandlers[i]); try{ if(formatter != null){ Class c = Class.forName(formatter); handler.setFormatter((Formatter)c.newInstance()); } }catch(Exception e){ e.printStackTrace(); } handler.setLevel(Level.ALL); logger.addHandler(handler); } }catch(Exception e){ e.printStackTrace(); } } logger.setLevel(Level.ALL); if(config.getRedirect()){ LoggingStream outStream = new LoggingStream(logger, "output"); LoggingStream errStream = new LoggingStream(logger, "error"); System.setOut(outStream); System.setErr(errStream); } long totalStartTime = System.currentTimeMillis(); TimeZone.setDefault(TimeZone.getTimeZone("Asia/Tokyo")); date = (Calendar)config.getStartDate().clone(); Calendar endDate = config.getEndDate(); // Interval interval = new Interval(date, endDate); // Calendar[] validDates = MarketSchedule.getInstance().getDates(interval); // int index=0; timeSetting = new FixedTimeSetting(); timeSetting.setTime(date); Time.setTimeSetting(timeSetting); InformationManagerBuilder builder = new CachedInformationManagerBuilder(); InformationManager informationManager = builder .createInformationManager(); TechnicalAnalysisManagerBuilder tbuilder = new XMLTechnicalAnalysisManagerBuilder(); TechnicalAnalysisManager technicalManager = tbuilder.createTechnicalAnalysisManager(); SearchManagerBuilder sbuilder = new CachedSearchManagerBuilder(); SearchManager searchManager = sbuilder.createSearchManager(); if(config.getParameter("stockserver", "url") != null){ stockAgentClient= new StockAgentClient( config.getParameter("stockserver", "id"), config.getParameter("stockserver", "password"), config.getParameter("stockserver", "url")); } else { String id = config.getParameter("stockserver", "id"); String password = config.getParameter("stockserver", "password"); String infojdbc = config.getParameter("information", "jdbc"); String infourl = config.getParameter("information", "url"); String infoid = config.getParameter("information", "id"); String infopassword = config.getParameter("information", "password"); IndexYearlyDao indexYearlyDao = new IndexYearlyDao (infojdbc, infourl, infoid, infopassword); IndexDailyDao indexDaylyDao = new IndexDailyDao (infojdbc, infourl, infoid, infopassword); stockAgentClient= new StockAgentDebugClient( id, password, indexYearlyDao, indexDaylyDao); } // リセット処理 stockAgentClient.reset(); FlexibleInvestmentAgentFactory factory = new FlexibleInvestmentAgentFactory(); factory.setInformationManager(informationManager); factory.setTechnicalAnalysisManager(technicalManager); factory.setSearchManager(searchManager); factory.setStockAgentClient(stockAgentClient); investmentAgent = factory.createInvestmentAgent(); }catch(Exception e){ e.printStackTrace(); throw new IllegalStateException(); } } public IStockAgentClient getAgentClient(){ return stockAgentClient; } public void setDate(Date newDate){ date.setTime(newDate); timeSetting.setTime(date); } /** * カブロボを実行して一日進める * ログも表示 */ public void runRobot(Robot robot){ try{ String strDate = dateFormat.format(date.getTime()); logger.log(Level.INFO, "DAY: "+strDate, "driver"); Portfolio portfolio = investmentAgent.getPortfolio(); logger.log(Level.INFO, "資金: "+moneyFormat.format(portfolio.getMoney())+"pts " +"取引可能金額: "+moneyFormat.format(portfolio.getAvailableMoney())+"pts\n", "driver"); if(MarketSchedule.getInstance().checkSchedule(date)){ //実行 robot.run(investmentAgent); // Calendar execDate = getNearlyMarketDate(); stockAgentClient.orderExec(execDate.getTime()); // 注文結果出力 List list = investmentAgent.getOrderResult(date); Iterator itr = list.iterator(); if(itr.hasNext()){ String strResult = "\n【当日注文処理結果】\n"; strResult += "銘柄|取引単位数|値段\n"; strResult += "----+----------+----\n"; while(itr.hasNext()){ jp.kaburobo.investment.OrderResult result = (jp.kaburobo.investment.OrderResult)itr.next(); String str = ""+result.getStockCode(); for(int j=str.length(); j<4; j++){ str = " "+str; } strResult += str+"|"; str = ""+result.getNumber(); for(int j=str.length(); j<10; j++){ str = " "+str; } strResult += str+"|"; if(result.getNumber() != 0){ strResult += result.getSuccessPrice()+"\n"; } else { strResult += " - \n"; } } logger.log(Level.INFO, strResult, "result"); } }else{ logger.log(Level.INFO, "休日"); } addDate(); }catch(Exception e){ e.printStackTrace(); throw new IllegalStateException("fail to run robot"); } } private Calendar getNearlyMarketDate(){ Calendar execDate = (Calendar)date.clone(); for(;;){ execDate.add(Calendar.DATE, 1); if(MarketSchedule.getInstance().checkSchedule(execDate)){ break; } } return execDate; } /** * 指定した日からdays日間(休日含む)ロボット実行 */ public void runRobotFrom(Robot robot, String startDate, int days){ setDateByText(startDate); for(int i=0; i<days; i++){ runRobot(robot); } } public void dumpOrderHistories(){ OrderHistory[] histories = investmentAgent.getOrderHistory(); String strHistory = "【履歴】\n"; for(int i=0; i<histories.length; i++){ strHistory += dateFormat.format(histories[i].getDate().getTime())+" " +"資金: "+moneyFormat.format(histories[i].getMoney())+"pts " +"評価額: "+moneyFormat.format(histories[i].getAmount())+"pts\n"; } logger.log(Level.INFO, strHistory, "history"); } public InvestmentAgent getInvestmentAgent(){ return investmentAgent; } /** * yyyy/MM/dd */ public void setDateByText(String dateText){ try{ Date newDate = dateFormat.parse(dateText); setDate(newDate); }catch(Exception e){ e.printStackTrace(); throw new IllegalStateException("date parse fail"); } } public void addDate(){ date.add(Calendar.DATE, 1); timeSetting.setTime(date); } }
テストケースの例
package hoge; import junit.framework.TestCase; import com.muimi.kaburobo.MyRobot; public class KabuRoboTestCase extends TestCase { public void testFoo(){ KaburoboTestManager manager = KaburoboTestManager.getInstance(); manager.runRobotFrom(new MyRobot(), "2004/04/01", 30); manager.dumpOrderHistories(); } public void testBar(){ KaburoboTestManager manager = KaburoboTestManager.getInstance(); manager.setDateByText("2004/04/01"); manager.runRobot(new MyRobot()); } }
ちょっと結果確認ってしずらいので、単なるランチャー気分かも。
日付は自由に切り替えられます。
結局DBにいろんなデータとりにいくので、ちゃんとやろうとすると、DBにテストデータをセッティングする必要があるかもないかも。。。
なお、実行にはVM引数に kaburobo.home を指定する必要があります。
- Dkaburobo.home=C:\data\projects\kaburobo\kaburobo_ver_1_2_5\kaburobo